AbstractIntegratedModule 1.1.2__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.2 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/PKG-INFO +1 -1
  2. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.py +271 -47
  3. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractOptimizedModules.c +209 -201
  4. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/PKG-INFO +1 -1
  5. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/README.md +63 -16
  6. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/pyproject.toml +1 -1
  7. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/setup.py +1 -1
  8. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/SOURCES.txt +0 -0
  9. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/dependency_links.txt +0 -0
  10. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/requires.txt +0 -0
  11. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractIntegratedModule.egg-info/top_level.txt +0 -0
  12. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/AbstractOptimizedModules.pyx +0 -0
  13. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/MANIFEST.in +0 -0
  14. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/Cargo.toml +0 -0
  15. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/pyproject.toml +0 -0
  16. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/src/lib.rs +0 -0
  17. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/libsqlite3-sys-ed07b882cd2aa5e2/out/bindgen.rs +0 -0
  18. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/serde_core-ebc15f2e9cad7f5f/out/private.rs +0 -0
  19. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/debug/build/target-lexicon-08527f45de28143d/out/host.rs +0 -0
  20. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/libsqlite3-sys-bf0400df4523274c/out/bindgen.rs +0 -0
  21. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/serde_core-5cdb76131825e4af/out/private.rs +0 -0
  22. {abstractintegratedmodule-1.1.2 → abstractintegratedmodule-1.1.4}/abstract_model_storage/target/release/build/target-lexicon-43eb95a0588bf457/out/host.rs +0 -0
  23. {abstractintegratedmodule-1.1.2 → 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.2
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):
@@ -9544,6 +9594,10 @@ class IntegratedPipeline:
9544
9594
  self.lstm_lr = 5e-2
9545
9595
  self.lstm_hidden_dim = 64
9546
9596
 
9597
+ self.unsuitable_tolerance = False
9598
+ self.unsuitable_conditions = False
9599
+ self.unsuitable_peer_request = False
9600
+
9547
9601
  # Main component setup
9548
9602
  self.standard_scaler = StandardScaler()
9549
9603
  self.tfidf = TfidfVectorizer(max_features=70)
@@ -9818,6 +9872,133 @@ class IntegratedPipeline:
9818
9872
  f"Unexpected memory type: {type(memory).__name__}",
9819
9873
  "Clear and reinitialize memory")
9820
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
+
9821
10002
 
9822
10003
  def _validate_tuple_memory(self, memory: tuple, num_classes: int) -> tuple:
9823
10004
  """
@@ -11501,7 +11682,7 @@ class IntegratedPipeline:
11501
11682
  method='dynamic', embedded=embedded
11502
11683
  )
11503
11684
  else:
11504
- fresh_probs = self.model3.forward(fresh_X_raw)
11685
+ fresh_probs = self.model3.forward(fresh_X_raw, y=y_true)
11505
11686
  try:
11506
11687
  fresh_trans_probs, _ = self.model2.forward(fresh_input_ids, embedded=False)
11507
11688
  except:
@@ -12102,9 +12283,12 @@ class IntegratedPipeline:
12102
12283
  calibrated[i, mlp_target_int] * (1.5 * (1.0 - abstract_score)), 0.95
12103
12284
  )
12104
12285
  else:
12105
- calibrated[mlp_target_int] = min(
12106
- calibrated[mlp_target_int] * (1.5 * (1.0 - abstract_score)), 0.95
12107
- )
12286
+ if mlp_target_int < len(calibrated):
12287
+ calibrated[mlp_target_int] = min(
12288
+ calibrated[mlp_target_int] * (1.5 * (1.0 - abstract_score)), 0.95
12289
+ )
12290
+ else:
12291
+ calibrated = min(calibrated * (1.5 * (1.0 - abstract_score)), 0.95)
12108
12292
 
12109
12293
  if i <= len(calibrated):
12110
12294
  try:
@@ -12513,7 +12697,7 @@ class IntegratedPipeline:
12513
12697
  lengths.add(1)
12514
12698
 
12515
12699
  if len(lengths) > 1:
12516
- # RAGGED — pad to uniform length
12700
+ # RAGGED — pad to uniform length.
12517
12701
  max_len = max(lengths)
12518
12702
  print(f'[=] AME_Encoder: ragged input detected '
12519
12703
  f'(lengths: {lengths}) — padding to {max_len}')
@@ -12871,6 +13055,7 @@ class IntegratedPipeline:
12871
13055
 
12872
13056
  return float(np.asarray(arr).flat[-1]) # ultimate fallback, never crashes
12873
13057
 
13058
+
12874
13059
  def _get_ensemble_confidence_for_true_class(self, X, Y, input_ids=None, eps=1e-3):
12875
13060
  """
12876
13061
  Computes, per sample, how confident the MLP + Transformer ensemble
@@ -12914,7 +13099,7 @@ class IntegratedPipeline:
12914
13099
  if X.shape != self.model3.layers[0].W.shape:
12915
13100
  X = np.reshape(X, (n_samples, self.model3.layers[0].W.shape[0]))
12916
13101
 
12917
- 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)
12918
13103
  if mlp_probs.ndim == 1:
12919
13104
  mlp_probs = mlp_probs.reshape(1, -1)
12920
13105
  except Exception as e:
@@ -12980,6 +13165,7 @@ class IntegratedPipeline:
12980
13165
 
12981
13166
  return confidences
12982
13167
 
13168
+
12983
13169
  def lstm_setup_inference(self, raw_X, raw_Y, input_ids=None):
12984
13170
  print("\n" + "=" * 55)
12985
13171
  print("===== LSTM SETUP INFERENCE =====")
@@ -13086,6 +13272,10 @@ class IntegratedPipeline:
13086
13272
  unsuitable_training = False
13087
13273
 
13088
13274
  probs = self.model_memory_gate(input_ids, x)
13275
+ cache = self.accurate_cache_lookup.lookup(
13276
+ x_mlp=x,
13277
+ input_ids=input_ids)
13278
+ cached = cache is not None and cache['similarity'] >= 0.95
13089
13279
 
13090
13280
  anisotropy = self.anisotropy_measurement(input_ids)
13091
13281
  AME = self.AME_Encoder(input_ids)
@@ -13104,11 +13294,15 @@ class IntegratedPipeline:
13104
13294
  # AMR is guaranteed to give sufficient ratio on how modelling error error could be sufficient enough to guarantee the model successful training
13105
13295
  # (not too high that it shows unstability, not too low that it shows rigidity), high anisotropy correlates to a much complex non linearity that the model will have a hard time adjusting
13106
13296
  # Too high AAC means the model is likely to be in a regime where training could lead to overfitting or divergence due to insufficient modelling capacity relative to the complexity of the data, especially if the confidence score is also low, indicating that the model is not currently confident in its predictions and may not benefit from further training on this data.
13107
- unsuitable_tolerance = probs is not None or AAC > 0.75
13297
+ unsuitable_tolerance = probs is not None and cached or AAC > 0.75
13108
13298
  unsuitable_conditions = anisotropy > 0.85 or final_conf > confidence_threshold or self.froze_learning
13109
13299
  unsuitable_peer_request = probs is not None and self.peer_assistance_threshold > self.confidence_threshold
13110
13300
 
13111
- if unsuitable_tolerance or unsuitable_conditions or unsuitable_peer_request:
13301
+ self.unsuitable_tolerance = unsuitable_tolerance
13302
+ self.unsuitable_conditions = unsuitable_conditions
13303
+ self.unsuitable_peer_request = unsuitable_peer_request
13304
+
13305
+ if self.unsuitable_tolerance or self.unsuitable_conditions or self.unsuitable_peer_request:
13112
13306
  print(f'[==] Unsuitable training condition detected! Tolerance: {unsuitable_tolerance} || Unsuitable Conditions: {unsuitable_conditions}')
13113
13307
  print(f'[==] Peer assistance condition: {unsuitable_peer_request} || Peer assistance threshold: {self.peer_assistance_threshold}')
13114
13308
  unsuitable_training = True
@@ -13174,6 +13368,8 @@ class IntegratedPipeline:
13174
13368
  if sequence_inputs.shape[1] == 1:
13175
13369
  print('[=] transformer_pooled_features: single-timestep input, '
13176
13370
  'std_pool will be all zeros (no variance across T=1)')
13371
+ print('[=] Reshaping sequence inputs to 2 dimension...')
13372
+ sequence_inputs = sequence_inputs.reshape(-1, 1)
13177
13373
 
13178
13374
  mean_pool = np.mean(sequence_inputs, axis=1)
13179
13375
  max_pool = np.max(sequence_inputs, axis=1)
@@ -13207,6 +13403,7 @@ class IntegratedPipeline:
13207
13403
 
13208
13404
  if isinstance(X_provided, (str, np.str_)):
13209
13405
  X_provided = _safe_parse_string(X_provided)
13406
+
13210
13407
 
13211
13408
  if isinstance(X_provided, np.ndarray) and np.issubdtype(X_provided.dtype, np.character):
13212
13409
  joined = ' '.join(X_provided.astype(str).flatten())
@@ -13299,7 +13496,7 @@ class IntegratedPipeline:
13299
13496
 
13300
13497
  issues = []
13301
13498
 
13302
- # 1. Values outside [0, 1] — catches your [5,3,1,4,3,2] case directly
13499
+ # 1. Values outside [0, 1].
13303
13500
  out_of_range = (y_true < 0) | (y_true > 1)
13304
13501
  if out_of_range.any():
13305
13502
  bad_rows = np.where(out_of_range.any(axis=1))[0]
@@ -13332,7 +13529,7 @@ class IntegratedPipeline:
13332
13529
  )
13333
13530
 
13334
13531
  if issues:
13335
- print(f"[WARNING] [{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...")
13336
13533
  return True
13337
13534
 
13338
13535
  return False
@@ -13341,6 +13538,7 @@ class IntegratedPipeline:
13341
13538
  def transformer_utilities(self, X_provided= None, X_raw=None, y_true=None, rules=None,
13342
13539
  datasets=None, label_map=None, batch_size=2, min_signal=1e-3,
13343
13540
  max_samples_for_focused_fit=500):
13541
+ unsuitable = False
13344
13542
  if X_provided is not None:
13345
13543
  X_raw = X_provided
13346
13544
 
@@ -13443,7 +13641,7 @@ class IntegratedPipeline:
13443
13641
  weak_rows = np.where(row_sums < min_signal)[0]
13444
13642
  weak_ratio = len(weak_rows) / len(X_raw_features)
13445
13643
 
13446
- print(f'[!] Zero ratio in samples: {weak_ratio * 100}%')
13644
+ print(f'[>] Zero ratio in samples: {weak_ratio * 100}%')
13447
13645
  if weak_ratio > 0.3: # more than 30% zero rows means vocab mismatch
13448
13646
  if isinstance(X_raw_generation[0], str):
13449
13647
  print(f'[= ! =] High zero-row ratio ({weak_ratio:.0%}), refitting on current batch')
@@ -13503,8 +13701,14 @@ class IntegratedPipeline:
13503
13701
  if n_classes > np.max(y):
13504
13702
  y = np.eye(n_classes)[np.asarray(y)]
13505
13703
  else:
13506
- print('[⚠️] Warning: Y onehot encoding fails, Returning Y samples as is, This may cause Exploding Gradient in MLP Training!')
13507
- 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
13508
13712
 
13509
13713
  if self.model2 is None:
13510
13714
  self.model2 = Transformer(
@@ -13517,9 +13721,15 @@ class IntegratedPipeline:
13517
13721
  if self.use_transformer:
13518
13722
  self.model2.train(sequence_inputs, y_true, epochs=self.transformer_training_epochs, mode=mode, lr=lr, embedded=True, batch_size=batch_size)
13519
13723
 
13520
- X = self.shape_adaptation(hybrid_X, input_dim)
13724
+ X = self.shape_adaptation(hybrid_X, input_dim)
13725
+
13726
+
13521
13727
  self.initialize_model_(X, input_dim, n_classes)
13522
- 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
+
13523
13733
  self.lstm_setup_inference(X, y, input_ids=sequence_inputs)
13524
13734
  if self.lstm_engine:
13525
13735
  self.storage.save_weights(self.memory_name, model_type='Pipeline')
@@ -13527,7 +13737,7 @@ class IntegratedPipeline:
13527
13737
  print('🎉 All Model Trained!')
13528
13738
  else:
13529
13739
  print(f'[=] No suitable condition for training!')
13530
- print('[=] Saving Weights for prediction')
13740
+ print('[>] Loading Weights for prediction...')
13531
13741
 
13532
13742
  num_classes = self._get_num_classes(label_map=label_map) if label_map else (y_true.shape[1] if y_true.ndim > 1 else len(np.unique(y_true)))
13533
13743
 
@@ -16369,15 +16579,8 @@ class PipelinePredictionManager:
16369
16579
  X_tfidf = X
16370
16580
 
16371
16581
  # Forward pass through MLP
16372
- if hasattr(self.pipeline.mlp, 'predict_proba'):
16373
- if X_tfidf is None:
16374
- X_tfidf = X
16375
- mlp_probs = self.pipeline.model3.predict_proba(X)
16376
- else:
16377
- # Fallback if predict_proba not available
16378
- logits = self.pipeline.model3.forward(X)
16379
- mlp_probs = self.pipeline._softmax(logits)
16380
-
16582
+ mlp_probs = self.pipeline.model3.forward(X, y=y)
16583
+
16381
16584
  # Validate all MLP predictions at once
16382
16585
  mlp_pred_indices = np.argmax(mlp_probs, axis=1)
16383
16586
  if num_classes <= 0:
@@ -17414,12 +17617,8 @@ class PipelinePredictionManager:
17414
17617
  X = np.asarray(X)
17415
17618
 
17416
17619
  # MLP forward pass
17417
- if hasattr(self.pipeline.mlp, 'predict_proba'):
17418
- mlp_probs = self.pipeline.model3.predict_proba(X)
17419
- else:
17420
- logits = self.pipeline.model3.forward(X)
17421
- mlp_probs = self.pipeline._softmax(logits)
17422
-
17620
+ mlp_probs = self.pipeline.model3.forward(X, y=y_val)
17621
+
17423
17622
  # Validate all MLP predictions at once
17424
17623
  mlp_pred_indices = np.argmax(mlp_probs, axis=1)
17425
17624
  if num_classes <= 0:
@@ -17554,7 +17753,9 @@ class PipelinePredictionManager:
17554
17753
 
17555
17754
  # Transformer prediction and blending
17556
17755
  if trans_probs is not None and attn_weights is not None:
17557
- trans_probs_i = trans_probs[i]
17756
+ if i < len(trans_probs):
17757
+ trans_probs_i = trans_probs[i]
17758
+
17558
17759
  trans_class_idx = np.argmax(trans_probs_i)
17559
17760
  if isinstance(trans_probs_i, float):
17560
17761
  trans_confidence = target_confidence
@@ -17632,7 +17833,10 @@ class PipelinePredictionManager:
17632
17833
  agreement = mlp_class_idx == trans_class_idx
17633
17834
 
17634
17835
  else:
17635
- 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]
17636
17840
 
17637
17841
  final_class_idx = target_class_idx
17638
17842
  final_confidence = target_confidence[0] if isinstance(target_confidence, np.ndarray) else target_confidence
@@ -17817,9 +18021,11 @@ class PipelinePredictionManager:
17817
18021
  'X_samples': X,
17818
18022
  'input_ids': input_ids
17819
18023
  }
18024
+ print('[=] Displaying Test Performance Results....')
17820
18025
  if titles is not None and len(titles) > 0:
17821
18026
  correct, sec_correct = self.display_hybrid_results(payload, final_class_idx, results, top_k, verbose=True)
17822
-
18027
+
18028
+
17823
18029
  return results, chosen_label, confidence
17824
18030
 
17825
18031
  else:
@@ -18105,6 +18311,7 @@ class PipelinePredictionManager:
18105
18311
  else:
18106
18312
  print(f'[⚡] Final Prediction: {chosen_label} with confidence: {confidence:.1%}')
18107
18313
  chosen_label = chosen_label
18314
+
18108
18315
 
18109
18316
  # delete pipelines cache
18110
18317
  print('[🔍] Pipelines Cache Cleaned!')
@@ -18167,7 +18374,9 @@ class PipelinePredictionManager:
18167
18374
 
18168
18375
  except Exception as e:
18169
18376
  print(f'[!] Cant check and calibrate probs based on penalty due to: {e}')
18170
- traceback.print_exc()
18377
+ traceback.print_exc()
18378
+
18379
+
18171
18380
 
18172
18381
  return final_probs
18173
18382
 
@@ -20284,6 +20493,21 @@ def PermissiveTest():
20284
20493
  ("Watching Slack", "communication"),
20285
20494
  ("Programming in Visual Studio Code", "focused_work"),
20286
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"),
20287
20511
  ]
20288
20512
  rules = [
20289
20513
  # === WORK / PRODUCTIVITY ===