AbstractIntegratedModule 1.1.3__tar.gz → 1.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/PKG-INFO +1 -1
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.py +246 -39
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractOptimizedModules.c +200 -200
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/PKG-INFO +1 -1
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/README.md +63 -17
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/pyproject.toml +1 -1
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/setup.py +1 -1
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/SOURCES.txt +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/dependency_links.txt +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/requires.txt +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/top_level.txt +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractOptimizedModules.pyx +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/MANIFEST.in +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/Cargo.toml +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/pyproject.toml +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/src/lib.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/libsqlite3-sys-ed07b882cd2aa5e2/out/bindgen.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/serde_core-ebc15f2e9cad7f5f/out/private.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/target-lexicon-08527f45de28143d/out/host.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/libsqlite3-sys-bf0400df4523274c/out/bindgen.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/serde_core-5cdb76131825e4af/out/private.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/target-lexicon-43eb95a0588bf457/out/host.rs +0 -0
- {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/setup.cfg +0 -0
{abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.py
RENAMED
|
@@ -485,12 +485,12 @@ class GeometricWeightShaping:
|
|
|
485
485
|
subnet = x[:min(10, x.shape[0]), :min(10, x.shape[1])]
|
|
486
486
|
gradient = np.gradient(subnet.flatten())
|
|
487
487
|
|
|
488
|
-
|
|
488
|
+
mean_vector_mag = np.mean(np.linalg.norm(gradient, axis=-1))
|
|
489
489
|
X_mag = np.mean(np.linalg.norm(X, axis=-1))
|
|
490
490
|
# Regular AME Equations, higher AME provides capabilities for the model to experience errors during abstraction
|
|
491
491
|
# Lower AME means lower chance for un optimal abstraction.
|
|
492
492
|
|
|
493
|
-
AME = np.log1p(X_mag) * np.log1p(
|
|
493
|
+
AME = np.log1p(X_mag) * np.log1p(mean_vector_mag)
|
|
494
494
|
return AME
|
|
495
495
|
|
|
496
496
|
# anisotropy provides the model the standard complexity of the data geometry, allowing it to know how complex the data needs to be processed.
|
|
@@ -1920,6 +1920,48 @@ class MLP:
|
|
|
1920
1920
|
|
|
1921
1921
|
return self.softmax.forward(x)
|
|
1922
1922
|
|
|
1923
|
+
def k_fold_split(self, X, y, k=5, seed=42, min_fold_size=2):
|
|
1924
|
+
X = np.asarray(X)
|
|
1925
|
+
y = np.asarray(y)
|
|
1926
|
+
n = len(X)
|
|
1927
|
+
|
|
1928
|
+
# adapt k downward for small datasets, never produce
|
|
1929
|
+
# folds smaller than min_fold_size
|
|
1930
|
+
effective_k = min(k, max(2, n // min_fold_size))
|
|
1931
|
+
if effective_k < k:
|
|
1932
|
+
print(f'[⚠️] k_fold_split: reduced k from {k} to {effective_k} '
|
|
1933
|
+
f'for n={n} samples, to avoid folds smaller than '
|
|
1934
|
+
f'{min_fold_size} samples')
|
|
1935
|
+
|
|
1936
|
+
rng = np.random.default_rng(seed)
|
|
1937
|
+
idx = rng.permutation(n)
|
|
1938
|
+
folds = np.array_split(idx, effective_k)
|
|
1939
|
+
|
|
1940
|
+
for i in range(effective_k):
|
|
1941
|
+
val_idx = folds[i]
|
|
1942
|
+
train_idx = np.concatenate([folds[j] for j in range(effective_k) if j != i])
|
|
1943
|
+
yield X[train_idx], y[train_idx], X[val_idx], y[val_idx]
|
|
1944
|
+
|
|
1945
|
+
|
|
1946
|
+
def confusion_matrix(self, y_true, y_pred, num_classes):
|
|
1947
|
+
y_true = np.asarray(y_true)
|
|
1948
|
+
y_pred = np.asarray(y_pred)
|
|
1949
|
+
|
|
1950
|
+
cm = np.zeros((num_classes, num_classes), dtype=int)
|
|
1951
|
+
|
|
1952
|
+
# Convert to label arrays: use argmax only if input is one-hot/prob (2D+),
|
|
1953
|
+
# otherwise need to treat as already being class labels.
|
|
1954
|
+
true_labels = np.argmax(y_true, axis=1) if y_true.ndim > 1 else y_true
|
|
1955
|
+
pred_labels = np.argmax(y_pred, axis=1) if y_pred.ndim > 1 else y_pred
|
|
1956
|
+
|
|
1957
|
+
for t, p in zip(true_labels, pred_labels):
|
|
1958
|
+
if 0 <= t < num_classes and 0 <= p < num_classes:
|
|
1959
|
+
cm[t, p] += 1
|
|
1960
|
+
else:
|
|
1961
|
+
print(f'[⚠️] confusion_matrix: label out of range '
|
|
1962
|
+
f'(true={t}, pred={p}, num_classes={num_classes}) — skipped')
|
|
1963
|
+
return cm
|
|
1964
|
+
|
|
1923
1965
|
def performance_calculation(self, x, AME=None, anisotropy=None):
|
|
1924
1966
|
eps = 1e-5
|
|
1925
1967
|
standard_low_error_mean = eps
|
|
@@ -1943,7 +1985,7 @@ class MLP:
|
|
|
1943
1985
|
|
|
1944
1986
|
return performance_score
|
|
1945
1987
|
|
|
1946
|
-
def forward(self, x, AME=None, anisotropy=None):
|
|
1988
|
+
def forward(self, x, y=None, AME=None, anisotropy=None, condition=None):
|
|
1947
1989
|
eps = 1e-5
|
|
1948
1990
|
performance_score = self.performance_calculation(x, AME=AME, anisotropy=anisotropy)
|
|
1949
1991
|
|
|
@@ -1951,6 +1993,11 @@ class MLP:
|
|
|
1951
1993
|
x = layer.forward(x, performance_score)
|
|
1952
1994
|
|
|
1953
1995
|
output = self.softmax.forward(x)
|
|
1996
|
+
if not condition == 'training' and y is not None:
|
|
1997
|
+
if y.shape == output.shape:
|
|
1998
|
+
acc = np.mean(np.argmax(output, axis=1) == np.argmax(y, axis=1))
|
|
1999
|
+
loss = Loss.categorical_crossentropy(y, output)
|
|
2000
|
+
print(f"[=] MLP Forward validation score: | loss: {loss:.4f} | Acc: {acc:.2%}")
|
|
1954
2001
|
|
|
1955
2002
|
return output
|
|
1956
2003
|
|
|
@@ -2175,7 +2222,7 @@ class MLP:
|
|
|
2175
2222
|
print(f'[+] MLP Training started with: {parameters} Parameters.')
|
|
2176
2223
|
for epoch in range(epochs):
|
|
2177
2224
|
if not focused_fit_condition:
|
|
2178
|
-
y_pred = self.forward(X, AME=AME, anisotropy=anisotropy)
|
|
2225
|
+
y_pred = self.forward(X, y=y, AME=AME, anisotropy=anisotropy, condition='training')
|
|
2179
2226
|
else:
|
|
2180
2227
|
y_pred = self.focused_forward(X, AME=AME, anisotropy=anisotropy)
|
|
2181
2228
|
|
|
@@ -3402,7 +3449,7 @@ class WeightedEnsemblePredictor:
|
|
|
3402
3449
|
AME = self.pipeline.model2.AME_Encoder(input_ids)
|
|
3403
3450
|
|
|
3404
3451
|
trans_probs, attn_weights = self.pipeline.model2.forward(input_ids, AME=AME, embedded=embedded)
|
|
3405
|
-
mlp_probs = self.pipeline.model3.forward(X_mlp)
|
|
3452
|
+
mlp_probs = self.pipeline.model3.forward(X_mlp, y=y_true)
|
|
3406
3453
|
lstm_probs, lstm_weight_hint = self._get_lstm_probs(input_ids, X_mlp, label_bins=label_bins)
|
|
3407
3454
|
|
|
3408
3455
|
established_agreement = self.query_node._establish_node_connection("PredictEnsemble")
|
|
@@ -4447,9 +4494,8 @@ class ExplainabilityModule:
|
|
|
4447
4494
|
print('[=] Note: Very little Consistency meaning Transformer attention quality is Healthy and focused')
|
|
4448
4495
|
|
|
4449
4496
|
if isinstance(final_conf, np.ndarray):
|
|
4450
|
-
final_conf = 1.0 / (1.0 + np.
|
|
4451
|
-
#
|
|
4452
|
-
# with real covariance of distribution from the data.
|
|
4497
|
+
final_conf = 1.0 / (1.0 + np.exp(-final_conf))
|
|
4498
|
+
# Apply a sigmoid transformation to ensure the confidence is between 0 and 1
|
|
4453
4499
|
|
|
4454
4500
|
if np.isnan(final_conf).any() or np.isinf(final_conf).any():
|
|
4455
4501
|
final_conf = self.pipeline.confidence_threshold
|
|
@@ -5944,10 +5990,13 @@ class ModelStorage:
|
|
|
5944
5990
|
|
|
5945
5991
|
try:
|
|
5946
5992
|
weights = result
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
self.pipeline.network_model.
|
|
5993
|
+
if isinstance(weights, str):
|
|
5994
|
+
weights = json.loads(weights)
|
|
5995
|
+
|
|
5996
|
+
self.pipeline.network_model.cell.W = np.array(weights.get('lstm_W'))
|
|
5997
|
+
self.pipeline.network_model.cell.b = np.array(weights.get('lstm_b'))
|
|
5998
|
+
self.pipeline.network_model.Wy = np.array(weights.get('Wy')) if weights.get('Wy') else None
|
|
5999
|
+
self.pipeline.network_model.by = np.array(weights.get('by'))
|
|
5951
6000
|
self.pipeline.lstm_engine.residual_mean = weights.get('residual_mean', 0.0)
|
|
5952
6001
|
self.pipeline.lstm_engine.residual_std = weights.get('residual_std', 1.0)
|
|
5953
6002
|
self.pipeline.lstm_engine.n_samples = weights.get('n_samples', self.pipeline.lstm_engine.n_samples)
|
|
@@ -5963,6 +6012,7 @@ class ModelStorage:
|
|
|
5963
6012
|
|
|
5964
6013
|
except Exception as e:
|
|
5965
6014
|
print(f'[!] Cant load any Weights due to: {e}')
|
|
6015
|
+
traceback.print_exc()
|
|
5966
6016
|
|
|
5967
6017
|
|
|
5968
6018
|
def load_transformer_dict(self, memory_name):
|
|
@@ -9822,6 +9872,133 @@ class IntegratedPipeline:
|
|
|
9822
9872
|
f"Unexpected memory type: {type(memory).__name__}",
|
|
9823
9873
|
"Clear and reinitialize memory")
|
|
9824
9874
|
|
|
9875
|
+
def k_fold_cross_validate(self, X, y, input_dim, n_classes, k=5, seed=42,
|
|
9876
|
+
epochs=None, lr=None, log_to_diagnostics=True):
|
|
9877
|
+
"""
|
|
9878
|
+
Orchestrates init → train → predict across k folds. Each fold gets
|
|
9879
|
+
a FRESH model (no weight carryover between folds), and the model
|
|
9880
|
+
that existed before k-fold started is restored afterward — k-fold
|
|
9881
|
+
here is purely an evaluation procedure, not a permanent side effect.
|
|
9882
|
+
"""
|
|
9883
|
+
X = np.asarray(X)
|
|
9884
|
+
y = np.asarray(y)
|
|
9885
|
+
|
|
9886
|
+
# preserve pre-existing model, restore it once CV is done
|
|
9887
|
+
original_model = getattr(self, 'model3', None)
|
|
9888
|
+
|
|
9889
|
+
recorder = None
|
|
9890
|
+
if log_to_diagnostics:
|
|
9891
|
+
try:
|
|
9892
|
+
from abstract_diagnostics import get_recorder
|
|
9893
|
+
recorder = get_recorder(self.memory_name)
|
|
9894
|
+
except ImportError:
|
|
9895
|
+
pass # diagnostics package not installed — silently skip, no crash
|
|
9896
|
+
|
|
9897
|
+
aggregate_cm = np.zeros((n_classes, n_classes), dtype=int)
|
|
9898
|
+
fold_accuracies = []
|
|
9899
|
+
|
|
9900
|
+
for fold_idx, (X_tr, y_tr, X_val, y_val) in enumerate(
|
|
9901
|
+
self.model3.k_fold_split(X, y, k=k, seed=seed)
|
|
9902
|
+
):
|
|
9903
|
+
# FRESH model every fold — this is the load-bearing line
|
|
9904
|
+
self.initialize_model_(X_tr, input_dim, n_classes)
|
|
9905
|
+
self.model3.train(X_tr, y_tr,
|
|
9906
|
+
epochs=epochs or self.mlp_training_epochs,
|
|
9907
|
+
lr=lr or self.mlp_lr)
|
|
9908
|
+
|
|
9909
|
+
y_pred = self.model3.forward(X_val)
|
|
9910
|
+
cm = self.model3.confusion_matrix(y_val, y_pred, n_classes)
|
|
9911
|
+
aggregate_cm += cm
|
|
9912
|
+
|
|
9913
|
+
fold_acc = np.trace(cm) / max(cm.sum(), 1)
|
|
9914
|
+
fold_accuracies.append(fold_acc)
|
|
9915
|
+
print(f'[=] Fold {fold_idx + 1}/{k}: accuracy={fold_acc:.2%}')
|
|
9916
|
+
|
|
9917
|
+
if recorder:
|
|
9918
|
+
recorder.log_scalar('mlp/kfold_accuracy', fold_acc, step=fold_idx)
|
|
9919
|
+
|
|
9920
|
+
self.model3 = original_model # restore — CV was evaluation only
|
|
9921
|
+
|
|
9922
|
+
mean_acc, std_acc = float(np.mean(fold_accuracies)), float(np.std(fold_accuracies))
|
|
9923
|
+
print(f'[=] K-Fold CV complete: {mean_acc:.2%} ± {std_acc:.2%}')
|
|
9924
|
+
|
|
9925
|
+
if recorder:
|
|
9926
|
+
recorder.log_scalar('mlp/kfold_mean_accuracy', mean_acc)
|
|
9927
|
+
recorder.log_scalar('mlp/kfold_std_accuracy', std_acc)
|
|
9928
|
+
|
|
9929
|
+
return {
|
|
9930
|
+
'fold_accuracies': fold_accuracies,
|
|
9931
|
+
'mean_accuracy': mean_acc,
|
|
9932
|
+
'std_accuracy': std_acc,
|
|
9933
|
+
'confusion_matrix': aggregate_cm,
|
|
9934
|
+
}
|
|
9935
|
+
|
|
9936
|
+
def evaluate_mlp_performance(self, X, y, label_map, k=5, seed=42):
|
|
9937
|
+
"""
|
|
9938
|
+
input_dim and n_classes are ALWAYS derived from the actual X/y
|
|
9939
|
+
given to this call — never accepted as separate parameters that
|
|
9940
|
+
could silently drift out of sync with the real data (the exact
|
|
9941
|
+
bug class this whole session was about).
|
|
9942
|
+
"""
|
|
9943
|
+
X = np.asarray(X)
|
|
9944
|
+
y = np.asarray(y)
|
|
9945
|
+
|
|
9946
|
+
if X.ndim == 1:
|
|
9947
|
+
X = X.reshape(-1, 1)
|
|
9948
|
+
|
|
9949
|
+
# derived input_dim directly from X, matching this call's
|
|
9950
|
+
# ACTUAL data.
|
|
9951
|
+
input_dim = X.shape[1]
|
|
9952
|
+
model_classes = self._get_num_classes()
|
|
9953
|
+
|
|
9954
|
+
#derived n_classes the same authoritative way used
|
|
9955
|
+
# throughout the rest of the pipeline (_get_num_classes as
|
|
9956
|
+
# primary source, cross-checked against y itself)
|
|
9957
|
+
|
|
9958
|
+
y_arr = np.asarray(y)
|
|
9959
|
+
|
|
9960
|
+
onehot_validation = self._validate_onehot(y)
|
|
9961
|
+
if onehot_validation:
|
|
9962
|
+
if model_classes != len(label_map):
|
|
9963
|
+
model_classes = len(label_map)
|
|
9964
|
+
if model_classes > np.max(y):
|
|
9965
|
+
y = np.eye(model_classes)[np.asarray(y)]
|
|
9966
|
+
else:
|
|
9967
|
+
print('[⚠️] Warning: Proper Y onehot encoding fails, modifying number of classes to exactly match Y values to do one final one hot encoding...')
|
|
9968
|
+
try:
|
|
9969
|
+
model_classes = np.max(y) + 1
|
|
9970
|
+
y = np.eye(model_classes)[np.asarray(y)]
|
|
9971
|
+
except:
|
|
9972
|
+
print('[!] Error: One hot encoding failed, please check your Y values and label map for consistency, passing raw Y and skipping MLP Training...')
|
|
9973
|
+
unsuitable = True
|
|
9974
|
+
y = y.copy() # fallback to raw y if one-hot fails
|
|
9975
|
+
|
|
9976
|
+
if y_arr.ndim > 1:
|
|
9977
|
+
n_classes_from_y = y_arr.shape[1]
|
|
9978
|
+
else:
|
|
9979
|
+
n_classes_from_y = int(y_arr.max()) + 1
|
|
9980
|
+
|
|
9981
|
+
if model_classes is not None and model_classes != n_classes_from_y:
|
|
9982
|
+
print(f'[⚠️] evaluate_mlp_performance: n_classes mismatch — '
|
|
9983
|
+
f'model reports {model_classes}, y data implies '
|
|
9984
|
+
f'{n_classes_from_y}. Using y-derived value ({n_classes_from_y}) '
|
|
9985
|
+
f'since k-fold must match the ACTUAL labels being evaluated.')
|
|
9986
|
+
n_classes = n_classes_from_y
|
|
9987
|
+
|
|
9988
|
+
print(f'[=] evaluate_mlp_performance: derived input_dim={input_dim}, '
|
|
9989
|
+
f'n_classes={n_classes} from provided X/y (shapes: '
|
|
9990
|
+
f'X={X.shape}, y={y_arr.shape})')
|
|
9991
|
+
|
|
9992
|
+
result = self.k_fold_cross_validate(X, y, input_dim, n_classes, k=k, seed=seed)
|
|
9993
|
+
|
|
9994
|
+
print('========= MLP Performance Evaluation Summary ============')
|
|
9995
|
+
print(f'[=>] MLP performance evaluation complete: mean accuracy={result["mean_accuracy"]:.2%}, '
|
|
9996
|
+
f'std accuracy={result["std_accuracy"]:.2%}')
|
|
9997
|
+
print(f'[=>] Confusion matrix:\n{result["confusion_matrix"]}')
|
|
9998
|
+
print(f'[=>] Fold accuracies: {result["fold_accuracies"]}')
|
|
9999
|
+
print(f'[=>] K-Fold CV complete: {result["mean_accuracy"]:.2%} ± {result["std_accuracy"]:.2%}')
|
|
10000
|
+
return result
|
|
10001
|
+
|
|
9825
10002
|
|
|
9826
10003
|
def _validate_tuple_memory(self, memory: tuple, num_classes: int) -> tuple:
|
|
9827
10004
|
"""
|
|
@@ -11505,7 +11682,7 @@ class IntegratedPipeline:
|
|
|
11505
11682
|
method='dynamic', embedded=embedded
|
|
11506
11683
|
)
|
|
11507
11684
|
else:
|
|
11508
|
-
fresh_probs = self.model3.forward(fresh_X_raw)
|
|
11685
|
+
fresh_probs = self.model3.forward(fresh_X_raw, y=y_true)
|
|
11509
11686
|
try:
|
|
11510
11687
|
fresh_trans_probs, _ = self.model2.forward(fresh_input_ids, embedded=False)
|
|
11511
11688
|
except:
|
|
@@ -12878,6 +13055,7 @@ class IntegratedPipeline:
|
|
|
12878
13055
|
|
|
12879
13056
|
return float(np.asarray(arr).flat[-1]) # ultimate fallback, never crashes
|
|
12880
13057
|
|
|
13058
|
+
|
|
12881
13059
|
def _get_ensemble_confidence_for_true_class(self, X, Y, input_ids=None, eps=1e-3):
|
|
12882
13060
|
"""
|
|
12883
13061
|
Computes, per sample, how confident the MLP + Transformer ensemble
|
|
@@ -12921,7 +13099,7 @@ class IntegratedPipeline:
|
|
|
12921
13099
|
if X.shape != self.model3.layers[0].W.shape:
|
|
12922
13100
|
X = np.reshape(X, (n_samples, self.model3.layers[0].W.shape[0]))
|
|
12923
13101
|
|
|
12924
|
-
mlp_probs = np.asarray(self.model3.forward(X), dtype=np.float64)
|
|
13102
|
+
mlp_probs = np.asarray(self.model3.forward(X, y=Y), dtype=np.float64)
|
|
12925
13103
|
if mlp_probs.ndim == 1:
|
|
12926
13104
|
mlp_probs = mlp_probs.reshape(1, -1)
|
|
12927
13105
|
except Exception as e:
|
|
@@ -12987,6 +13165,7 @@ class IntegratedPipeline:
|
|
|
12987
13165
|
|
|
12988
13166
|
return confidences
|
|
12989
13167
|
|
|
13168
|
+
|
|
12990
13169
|
def lstm_setup_inference(self, raw_X, raw_Y, input_ids=None):
|
|
12991
13170
|
print("\n" + "=" * 55)
|
|
12992
13171
|
print("===== LSTM SETUP INFERENCE =====")
|
|
@@ -13224,6 +13403,7 @@ class IntegratedPipeline:
|
|
|
13224
13403
|
|
|
13225
13404
|
if isinstance(X_provided, (str, np.str_)):
|
|
13226
13405
|
X_provided = _safe_parse_string(X_provided)
|
|
13406
|
+
|
|
13227
13407
|
|
|
13228
13408
|
if isinstance(X_provided, np.ndarray) and np.issubdtype(X_provided.dtype, np.character):
|
|
13229
13409
|
joined = ' '.join(X_provided.astype(str).flatten())
|
|
@@ -13316,7 +13496,7 @@ class IntegratedPipeline:
|
|
|
13316
13496
|
|
|
13317
13497
|
issues = []
|
|
13318
13498
|
|
|
13319
|
-
# 1. Values outside [0, 1]
|
|
13499
|
+
# 1. Values outside [0, 1].
|
|
13320
13500
|
out_of_range = (y_true < 0) | (y_true > 1)
|
|
13321
13501
|
if out_of_range.any():
|
|
13322
13502
|
bad_rows = np.where(out_of_range.any(axis=1))[0]
|
|
@@ -13349,7 +13529,7 @@ class IntegratedPipeline:
|
|
|
13349
13529
|
)
|
|
13350
13530
|
|
|
13351
13531
|
if issues:
|
|
13352
|
-
print(f"[>] [{context}]
|
|
13532
|
+
print(f"[>] [{context}] y sample is not properly one-hot encoded, one-hot encoding y sample...")
|
|
13353
13533
|
return True
|
|
13354
13534
|
|
|
13355
13535
|
return False
|
|
@@ -13358,6 +13538,7 @@ class IntegratedPipeline:
|
|
|
13358
13538
|
def transformer_utilities(self, X_provided= None, X_raw=None, y_true=None, rules=None,
|
|
13359
13539
|
datasets=None, label_map=None, batch_size=2, min_signal=1e-3,
|
|
13360
13540
|
max_samples_for_focused_fit=500):
|
|
13541
|
+
unsuitable = False
|
|
13361
13542
|
if X_provided is not None:
|
|
13362
13543
|
X_raw = X_provided
|
|
13363
13544
|
|
|
@@ -13520,8 +13701,14 @@ class IntegratedPipeline:
|
|
|
13520
13701
|
if n_classes > np.max(y):
|
|
13521
13702
|
y = np.eye(n_classes)[np.asarray(y)]
|
|
13522
13703
|
else:
|
|
13523
|
-
print('[⚠️] Warning: Y onehot encoding fails,
|
|
13524
|
-
|
|
13704
|
+
print('[⚠️] Warning: Proper Y onehot encoding fails, modifying number of classes to exactly match Y values to do one final one hot encoding...')
|
|
13705
|
+
try:
|
|
13706
|
+
n_classes = np.max(y) + 1
|
|
13707
|
+
y = np.eye(n_classes)[np.asarray(y)]
|
|
13708
|
+
except:
|
|
13709
|
+
print('[!] Error: One hot encoding failed, please check your Y values and label map for consistency, passing raw Y and skipping MLP Training...')
|
|
13710
|
+
unsuitable = True
|
|
13711
|
+
y = y.copy() # fallback to raw y if one-hot fails
|
|
13525
13712
|
|
|
13526
13713
|
if self.model2 is None:
|
|
13527
13714
|
self.model2 = Transformer(
|
|
@@ -13534,9 +13721,15 @@ class IntegratedPipeline:
|
|
|
13534
13721
|
if self.use_transformer:
|
|
13535
13722
|
self.model2.train(sequence_inputs, y_true, epochs=self.transformer_training_epochs, mode=mode, lr=lr, embedded=True, batch_size=batch_size)
|
|
13536
13723
|
|
|
13537
|
-
X = self.shape_adaptation(hybrid_X, input_dim)
|
|
13724
|
+
X = self.shape_adaptation(hybrid_X, input_dim)
|
|
13725
|
+
|
|
13726
|
+
|
|
13538
13727
|
self.initialize_model_(X, input_dim, n_classes)
|
|
13539
|
-
|
|
13728
|
+
if not unsuitable:
|
|
13729
|
+
self.model3.train(X, y, epochs=self.mlp_training_epochs, lr=self.mlp_lr, max_samples_for_focused_fit=max_samples_for_focused_fit)
|
|
13730
|
+
else:
|
|
13731
|
+
print('[->] MLP Training skipped due to unproper Y samples.')
|
|
13732
|
+
|
|
13540
13733
|
self.lstm_setup_inference(X, y, input_ids=sequence_inputs)
|
|
13541
13734
|
if self.lstm_engine:
|
|
13542
13735
|
self.storage.save_weights(self.memory_name, model_type='Pipeline')
|
|
@@ -16386,15 +16579,8 @@ class PipelinePredictionManager:
|
|
|
16386
16579
|
X_tfidf = X
|
|
16387
16580
|
|
|
16388
16581
|
# Forward pass through MLP
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
X_tfidf = X
|
|
16392
|
-
mlp_probs = self.pipeline.model3.predict_proba(X)
|
|
16393
|
-
else:
|
|
16394
|
-
# Fallback if predict_proba not available
|
|
16395
|
-
logits = self.pipeline.model3.forward(X)
|
|
16396
|
-
mlp_probs = self.pipeline._softmax(logits)
|
|
16397
|
-
|
|
16582
|
+
mlp_probs = self.pipeline.model3.forward(X, y=y)
|
|
16583
|
+
|
|
16398
16584
|
# Validate all MLP predictions at once
|
|
16399
16585
|
mlp_pred_indices = np.argmax(mlp_probs, axis=1)
|
|
16400
16586
|
if num_classes <= 0:
|
|
@@ -17431,12 +17617,8 @@ class PipelinePredictionManager:
|
|
|
17431
17617
|
X = np.asarray(X)
|
|
17432
17618
|
|
|
17433
17619
|
# MLP forward pass
|
|
17434
|
-
|
|
17435
|
-
|
|
17436
|
-
else:
|
|
17437
|
-
logits = self.pipeline.model3.forward(X)
|
|
17438
|
-
mlp_probs = self.pipeline._softmax(logits)
|
|
17439
|
-
|
|
17620
|
+
mlp_probs = self.pipeline.model3.forward(X, y=y_val)
|
|
17621
|
+
|
|
17440
17622
|
# Validate all MLP predictions at once
|
|
17441
17623
|
mlp_pred_indices = np.argmax(mlp_probs, axis=1)
|
|
17442
17624
|
if num_classes <= 0:
|
|
@@ -17571,7 +17753,9 @@ class PipelinePredictionManager:
|
|
|
17571
17753
|
|
|
17572
17754
|
# Transformer prediction and blending
|
|
17573
17755
|
if trans_probs is not None and attn_weights is not None:
|
|
17574
|
-
|
|
17756
|
+
if i < len(trans_probs):
|
|
17757
|
+
trans_probs_i = trans_probs[i]
|
|
17758
|
+
|
|
17575
17759
|
trans_class_idx = np.argmax(trans_probs_i)
|
|
17576
17760
|
if isinstance(trans_probs_i, float):
|
|
17577
17761
|
trans_confidence = target_confidence
|
|
@@ -17649,7 +17833,10 @@ class PipelinePredictionManager:
|
|
|
17649
17833
|
agreement = mlp_class_idx == trans_class_idx
|
|
17650
17834
|
|
|
17651
17835
|
else:
|
|
17652
|
-
|
|
17836
|
+
if i < len(mlp_probs):
|
|
17837
|
+
final_probs = mlp_probs[i]
|
|
17838
|
+
else:
|
|
17839
|
+
final_probs = mlp_probs[0]
|
|
17653
17840
|
|
|
17654
17841
|
final_class_idx = target_class_idx
|
|
17655
17842
|
final_confidence = target_confidence[0] if isinstance(target_confidence, np.ndarray) else target_confidence
|
|
@@ -17834,9 +18021,11 @@ class PipelinePredictionManager:
|
|
|
17834
18021
|
'X_samples': X,
|
|
17835
18022
|
'input_ids': input_ids
|
|
17836
18023
|
}
|
|
18024
|
+
print('[=] Displaying Test Performance Results....')
|
|
17837
18025
|
if titles is not None and len(titles) > 0:
|
|
17838
18026
|
correct, sec_correct = self.display_hybrid_results(payload, final_class_idx, results, top_k, verbose=True)
|
|
17839
|
-
|
|
18027
|
+
|
|
18028
|
+
|
|
17840
18029
|
return results, chosen_label, confidence
|
|
17841
18030
|
|
|
17842
18031
|
else:
|
|
@@ -18122,6 +18311,7 @@ class PipelinePredictionManager:
|
|
|
18122
18311
|
else:
|
|
18123
18312
|
print(f'[⚡] Final Prediction: {chosen_label} with confidence: {confidence:.1%}')
|
|
18124
18313
|
chosen_label = chosen_label
|
|
18314
|
+
|
|
18125
18315
|
|
|
18126
18316
|
# delete pipelines cache
|
|
18127
18317
|
print('[🔍] Pipelines Cache Cleaned!')
|
|
@@ -18184,7 +18374,9 @@ class PipelinePredictionManager:
|
|
|
18184
18374
|
|
|
18185
18375
|
except Exception as e:
|
|
18186
18376
|
print(f'[!] Cant check and calibrate probs based on penalty due to: {e}')
|
|
18187
|
-
traceback.print_exc()
|
|
18377
|
+
traceback.print_exc()
|
|
18378
|
+
|
|
18379
|
+
|
|
18188
18380
|
|
|
18189
18381
|
return final_probs
|
|
18190
18382
|
|
|
@@ -20301,6 +20493,21 @@ def PermissiveTest():
|
|
|
20301
20493
|
("Watching Slack", "communication"),
|
|
20302
20494
|
("Programming in Visual Studio Code", "focused_work"),
|
|
20303
20495
|
("Watching netflix.com - Chrome", "break"),
|
|
20496
|
+
("Listening to Spotify", "entertainment"),
|
|
20497
|
+
("Playing Steam Game", "gaming"),
|
|
20498
|
+
("Checking Discord messages", "communication"),
|
|
20499
|
+
("Reading documentation on StackOverflow", "research"),
|
|
20500
|
+
("Downloading files from Google Drive", "file_work"),
|
|
20501
|
+
("Using Terminal to run scripts", "system_work"),
|
|
20502
|
+
("Analyzing data in Excel", "data_work"),
|
|
20503
|
+
("Attending Zoom meeting", "communication"),
|
|
20504
|
+
("Designing in Photoshop", "creative"),
|
|
20505
|
+
("Learning from Coursera course", "learning"),
|
|
20506
|
+
("Using Calculator utility", "utility"),
|
|
20507
|
+
("Browsing Facebook on Chrome", "social_media"),
|
|
20508
|
+
("Reading an eBook in PDF format", "reading"),
|
|
20509
|
+
("Listening to a podcast", "audio_learning"),
|
|
20510
|
+
("Using Google Translate", "utility"),
|
|
20304
20511
|
]
|
|
20305
20512
|
rules = [
|
|
20306
20513
|
# === WORK / PRODUCTIVITY ===
|