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.
Files changed (23) hide show
  1. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/PKG-INFO +1 -1
  2. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.py +246 -39
  3. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractOptimizedModules.c +200 -200
  4. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/PKG-INFO +1 -1
  5. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/README.md +63 -17
  6. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/pyproject.toml +1 -1
  7. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/setup.py +1 -1
  8. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/SOURCES.txt +0 -0
  9. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/dependency_links.txt +0 -0
  10. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/requires.txt +0 -0
  11. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/top_level.txt +0 -0
  12. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/AbstractOptimizedModules.pyx +0 -0
  13. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/MANIFEST.in +0 -0
  14. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/Cargo.toml +0 -0
  15. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/pyproject.toml +0 -0
  16. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/src/lib.rs +0 -0
  17. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/libsqlite3-sys-ed07b882cd2aa5e2/out/bindgen.rs +0 -0
  18. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/serde_core-ebc15f2e9cad7f5f/out/private.rs +0 -0
  19. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/target-lexicon-08527f45de28143d/out/host.rs +0 -0
  20. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/libsqlite3-sys-bf0400df4523274c/out/bindgen.rs +0 -0
  21. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/serde_core-5cdb76131825e4af/out/private.rs +0 -0
  22. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/target-lexicon-43eb95a0588bf457/out/host.rs +0 -0
  23. {abstractintegratedmodule-1.1.3 → abstractintegratedmodule-1.1.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractIntegratedModule
3
- Version: 1.1.3
3
+ Version: 1.1.4
4
4
  Summary: Integrated Pipeline with Specialized Non-LLM AI Agent Framework for ARM64 architecture
5
5
  Author: Micro-Novelty
6
6
  Author-email: Micro-Novelty <hernikpuspita5@gmail.com>
@@ -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
- grad_energy = np.mean(np.linalg.norm(gradient, axis=-1))
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(grad_energy)
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.std(final_conf))
4451
- # growth deviation of arrayed final confidence helped to distinguish noise from unnecessary distribution,
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
- self.pipeline.network_model.cell.W = np.array(weights['lstm_W'])
5948
- self.pipeline.network_model.cell.b = np.array(weights['lstm_b'])
5949
- self.pipeline.network_model.Wy = np.array(weights['Wy']) if weights['Wy'] else None
5950
- self.pipeline.network_model.by = np.array(weights['by'])
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] — catches your [5,3,1,4,3,2] case directly
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}] y_true failed one-hot validation, one-hot encoding y sample...")
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, Returning Y samples as is, This may cause Exploding Gradient in MLP Training!')
13524
- y = y.copy()
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
- self.model3.train(X, y, epochs=self.mlp_training_epochs, lr=self.mlp_lr, max_samples_for_focused_fit=max_samples_for_focused_fit)
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
- if hasattr(self.pipeline.mlp, 'predict_proba'):
16390
- if X_tfidf is None:
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
- if hasattr(self.pipeline.mlp, 'predict_proba'):
17435
- mlp_probs = self.pipeline.model3.predict_proba(X)
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
- trans_probs_i = trans_probs[i]
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
- final_probs = mlp_probs[i]
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 ===