AbstractIntegratedModule 0.7.0__tar.gz → 0.7.1__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 (21) hide show
  1. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/PKG-INFO +10 -3
  2. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.py +208 -100
  3. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractOptimizedModules.c +152 -152
  4. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/PKG-INFO +10 -3
  5. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/README.md +9 -2
  6. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/setup.py +2 -9
  7. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/SOURCES.txt +0 -0
  8. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/dependency_links.txt +0 -0
  9. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/requires.txt +0 -0
  10. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/top_level.txt +0 -0
  11. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractOptimizedModules.pyx +0 -0
  12. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/MANIFEST.in +0 -0
  13. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/Cargo.toml +0 -0
  14. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/pyproject.toml +0 -0
  15. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/src/lib.rs +0 -0
  16. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/debug/build/libsqlite3-sys-ed07b882cd2aa5e2/out/bindgen.rs +0 -0
  17. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/debug/build/target-lexicon-08527f45de28143d/out/host.rs +0 -0
  18. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/release/build/libsqlite3-sys-bf0400df4523274c/out/bindgen.rs +0 -0
  19. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/release/build/target-lexicon-43eb95a0588bf457/out/host.rs +0 -0
  20. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/pyproject.toml +0 -0
  21. {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractIntegratedModule
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Library for Advanced Integrated Non-LLM AI Models - Optimized Backend Framework For Non-LLM AI Agent
5
5
  Author: Micro-Novelty
6
6
  Author-email: hernikpuspita5@gmail.com
@@ -42,7 +42,7 @@ https://github.com/Micro-Novelty/IntegratedPipeline-Specialized-Non-LLM-AI-Agent
42
42
  #### Note: The README here you are reading is a direct copy from my README Repository, to download the necessary files, you can visit my Repository with the provided link above.
43
43
 
44
44
  ### Library Short Description:
45
- - Development Stage: 0.7.0 Official Release.
45
+ - Development Stage: 0.7.1 Official Release.
46
46
  - Maintainer: Micro-Novelty.
47
47
  - library Source-Code is Open-sourced on github.
48
48
  - Purpose: Specifically Designed for providing Non-LLM AI Agent Framework for edge Devices, Optimized for ARM64 architecture.
@@ -65,10 +65,17 @@ https://github.com/Micro-Novelty/IntegratedPipeline-Specialized-Non-LLM-AI-Agent
65
65
  - Robust Advanced prediction capabilities proven effective on ARM64 Using MLP + LSTM Architectures.
66
66
  - Transformer Modules Optimized using Cython, to reduce Memory overhead and Reduce CPU Usage, With Reduced Training Time.
67
67
  - Changelog:
68
- - v0.7.0:
68
+ - v0.7.1:
69
69
  - [=] New features:
70
70
  - Added Rust specific compiled binary for handling complex weight matrices.
71
71
  - added specific optimized weight saving handling with rust optimization.
72
+ - Adding Optimization and refinements, especially bug fixes in:
73
+ - IntegratedPipeline lstm samples creating
74
+ - IntegratedPipeline shape adaptation
75
+ - IntegratedPipeline probability calibration
76
+ - IntegratedPipeline auto generate labels text
77
+ - IntegratedPipeline MLP samples generation.
78
+
72
79
  -----
73
80
 
74
81
  <img width="1280" height="600" alt="WhatsApp Image 2026-05-27 at 07 16 32" src="https://github.com/user-attachments/assets/4b58a556-45a3-419b-96fd-9c1b76cac574" />
@@ -31,6 +31,7 @@ from typing import Any, Callable, Tuple, Optional, Dict, List
31
31
  from datetime import datetime, timedelta
32
32
  from enum import IntEnum, Enum
33
33
  from collections import deque
34
+ from collections import Counter
34
35
  import traceback
35
36
  from concurrent.futures import TimeoutError as FutureTimeoutError
36
37
  import secrets
@@ -2781,7 +2782,6 @@ class WeightedEnsemblePredictor:
2781
2782
  predictions = [r['prediction'] for r in results]
2782
2783
  confidences = [r['confidence'] for r in results]
2783
2784
 
2784
- from collections import Counter
2785
2785
  distribution = Counter(predictions)
2786
2786
 
2787
2787
  print("\n📊 Batch Summary:")
@@ -5024,7 +5024,7 @@ class ModelStorage:
5024
5024
  try:
5025
5025
  binary = wc.load_transformer_weights(self.db_path, memory_name)
5026
5026
 
5027
- buf = io.BytesIO(bytes(row[0]))
5027
+ buf = io.BytesIO(bytes(binary))
5028
5028
  data = np.load(buf, allow_pickle=False)
5029
5029
 
5030
5030
  print('[+] Transformer weights data loaded using Rust module!')
@@ -5094,7 +5094,7 @@ class ModelStorage:
5094
5094
  try:
5095
5095
  result = wc.load_lstm_weights(self.db_path, memory_name)
5096
5096
  print('[+] LSTM weights loaded via Rust module')
5097
- except:
5097
+ except Exception as e:
5098
5098
  result = self.weight_retrieval(memory_name)
5099
5099
  print(f'[=] Cant load LSTM Weights due to: {e}, using python sqlite3 as fallback.')
5100
5100
  else:
@@ -5135,22 +5135,30 @@ class ModelStorage:
5135
5135
  except:
5136
5136
  db_path = self.get_database_path()
5137
5137
  conn = sqlite3.connect(db_path)
5138
-
5139
- conn = sqlite3.connect(self.db_path)
5140
- c = conn.cursor()
5141
-
5142
- c.execute("""
5143
- SELECT model_data FROM model_attn_storage
5144
- WHERE memory_name = ? AND is_active = 1
5145
- """, (memory_name,))
5146
-
5147
- result = c.fetchone()
5148
- conn.close()
5149
-
5150
- if result:
5151
- return json.loads(result[0])
5138
+
5139
+ if _RUST_MODULE_AVAILABLE:
5140
+ try:
5141
+ data = wc.load_attention_dict(self.db_path, memory_name)
5142
+ print('[+] Transformer attention loaded using Rust module!')
5143
+ return data
5144
+ except Exception as e:
5145
+ print(f'[=]: {e}, Loading transformer attention from python sqlite3...')
5146
+ else:
5147
+ conn = sqlite3.connect(self.db_path)
5148
+ c = conn.cursor()
5149
+
5150
+ c.execute("""
5151
+ SELECT model_data FROM model_attn_storage
5152
+ WHERE memory_name = ? AND is_active = 1
5153
+ """, (memory_name,))
5154
+
5155
+ result = c.fetchone()
5156
+ conn.close()
5157
+
5158
+ if result:
5159
+ return json.loads(result[0])
5152
5160
  except Exception as e:
5153
- print(f'Error handling attention dict: {e}')
5161
+ print(f'[!] Error handling attention dict: {e}')
5154
5162
 
5155
5163
  return None
5156
5164
 
@@ -9899,59 +9907,62 @@ class IntegratedPipeline:
9899
9907
 
9900
9908
  def _calibrate_probs(self, probs, target_preds, attn_weights, input_ids):
9901
9909
  calibrated = probs.copy()
9910
+
9902
9911
  if isinstance(input_ids, list):
9903
9912
  input_ids = np.array(input_ids)
9904
9913
 
9905
- if len(probs.shape) > 1:
9906
- n_classes = probs.shape[1]
9907
- else:
9908
- n_classes = probs.shape[0]
9909
-
9914
+ n_classes = probs.shape[1] if probs.ndim > 1 else probs.shape[0]
9910
9915
  batch_size = len(target_preds)
9911
9916
  eps = 1e-5
9912
9917
 
9913
- try:
9914
- for i in range(batch_size):
9915
- mlp_target = target_preds[i]
9918
+ temperature_accum = []
9916
9919
 
9917
- if attn_weights is None:
9918
- anisotropy = self.anisotropy_measurement(mlp_target)
9919
- else:
9920
- try:
9921
- anisotropy = self.anisotropy_measurement(attn_weights[i])
9922
- except:
9923
- anisotropy = self.anisotropy_measurement(attn_weights)
9920
+ attn_len = len(attn_weights) if attn_weights is not None else 0
9924
9921
 
9925
- if attn_weights is not None and i < len(attn_weights):
9926
- attn = attn_weights[i]
9927
-
9928
- score_quality = np.std(attn) if attn.size > 0 else self.confidence_threshold
9929
- abstract_score = self.confidence_threshold + score_quality * anisotropy
9922
+ for i in range(batch_size):
9923
+ # consistent bound check, no off-by-one
9924
+ mlp_target = target_preds[i] if i < attn_len else target_preds[0]
9925
+
9926
+ # anisotropy needs an array-like input
9927
+ if attn_weights is None:
9928
+ # no attention available
9929
+ anisotropy = eps
9930
+ elif i < attn_len:
9931
+ anisotropy = self.anisotropy_measurement(attn_weights[i])
9932
+ else:
9933
+ anisotropy = self.anisotropy_measurement(attn_weights[0])
9930
9934
 
9935
+ if attn_weights is not None and i < attn_len:
9936
+ attn = attn_weights[i]
9937
+ score_quality = np.std(attn) if attn.size > 0 else self.confidence_threshold
9938
+ abstract_score = self.confidence_threshold + score_quality * anisotropy
9939
+ else:
9940
+ if attn_weights is not None and attn_len > 0:
9941
+ # use last valid index
9942
+ fallback_attn = attn_weights[min(i, attn_len - 1)]
9943
+ score_quality = 1.0 / (1.0 + np.exp(-fallback_attn))
9931
9944
  else:
9932
- if attn_weights is not None:
9933
- if i <= len(attn_weights):
9934
- score_quality = 1.0 / (1.0 + np.exp(-attn_weights[i]))
9935
- else:
9936
- score_quality = 1.0 / (1.0 + np.exp(-attn_weights[0]))
9937
- else:
9938
- score_quality = 1.0 / (1.0 + np.exp(-mlp_target))
9939
-
9940
- abstract_score = (1.0 - score_quality) + eps
9945
+ score_quality = self.confidence_threshold # neutral default
9946
+ abstract_score = (1.0 - np.mean(score_quality)) + eps
9947
+
9948
+ temp = (1.0 - abstract_score) + score_quality * anisotropy
9949
+ if isinstance(temp, np.ndarray):
9950
+ temp = float(np.clip(np.mean(temp), 1e-5, 5.0))
9951
+ temperature_accum.append(temp)
9952
+
9953
+ # bounds guard before indexing
9954
+ if 0 <= mlp_target < n_classes and i < calibrated.shape[0]:
9955
+ calibrated[i, mlp_target] = min(
9956
+ calibrated[i, mlp_target] * (1.5 * (1.0 - abstract_score)), 0.95
9957
+ )
9941
9958
 
9942
- self.temperature = (1.0 - abstract_score) + score_quality * anisotropy
9943
- if isinstance(self.temperature, np.ndarray):
9944
- self.temperature = np.clip(np.mean(self.temperature), 1e-5, 5.0)
9959
+ row_sum = calibrated[i].sum()
9960
+ if row_sum > eps:
9961
+ calibrated[i] /= row_sum
9962
+ else:
9963
+ calibrated[i] = np.full(n_classes, 1.0 / n_classes)
9945
9964
 
9946
- try:
9947
- calibrated[i, mlp_target] = min(calibrated[i, mlp_target] * (1.5 * (1.0 - abstract_score)), 0.95)
9948
- except:
9949
- return calibrated
9950
-
9951
- calibrated[i] /= calibrated[i].sum()
9952
- except Exception as e:
9953
- print(f'[!] cant calibrate probability due to: {e}, returning regular probability.')
9954
- calibrated = calibrated.copy()
9965
+ self.temperature = float(np.mean(temperature_accum)) if temperature_accum else 1.0
9955
9966
 
9956
9967
  return calibrated
9957
9968
 
@@ -10083,10 +10094,9 @@ class IntegratedPipeline:
10083
10094
 
10084
10095
 
10085
10096
  def auto_generate_labels_from_texts(self, rules, texts):
10086
- import re
10087
10097
  y_raw = []
10088
10098
  self.rules = rules
10089
-
10099
+
10090
10100
  for text in texts:
10091
10101
  text_lower = text.lower()
10092
10102
  matched = False
@@ -10095,74 +10105,107 @@ class IntegratedPipeline:
10095
10105
  y_raw.append(label)
10096
10106
  matched = True
10097
10107
  break
10098
-
10099
10108
  if not matched:
10100
10109
  y_raw.append('other')
10101
-
10102
- from collections import Counter
10110
+
10103
10111
  print("\n[📊] Auto-generated label distribution:")
10104
- for label, count in Counter(y_raw).items():
10112
+ for label, count in sorted(Counter(y_raw).items()):
10105
10113
  print(f" {label}: {count} ({count/len(texts)*100:.1f}%)")
10106
-
10107
- return y_raw
10108
10114
 
10115
+ return y_raw
10109
10116
 
10110
10117
 
10111
10118
  def mlp_training_features(self, rules, dataset):
10112
10119
  print("\n[🔄] Preparing MLP data from dataset format")
10113
10120
 
10114
- texts = [item[:-1] for item in dataset]
10115
- labels = [item[-1] for item in dataset]
10116
-
10117
10121
  if isinstance(dataset[0], tuple) and len(dataset[0]) == 2:
10118
- # Format: [(features, label), ...]
10122
+ print('[=] Dataset Type 1: [(features, label), ...]')
10119
10123
  features_list = []
10120
- labels_list = []
10121
- print('[=] Dataset Type 1: [(value), (value)]')
10124
+ labels_list = []
10122
10125
  for item in dataset:
10123
10126
  features, label = item
10124
10127
  features_list.append(features)
10125
10128
  labels_list.append(label)
10126
-
10127
10129
  X_mlp = np.array(features_list)
10128
10130
  y_raw = np.array(labels_list)
10129
-
10131
+
10130
10132
  elif isinstance(dataset[0], (list, np.ndarray)) and len(dataset[0]) > 1:
10131
- print('[=] Dataset Type 2')
10133
+ print('[=] Dataset Type 2: [feature1, feature2, ..., label]')
10134
+ texts = [item[:-1] for item in dataset]
10135
+ labels = [item[-1] for item in dataset]
10132
10136
  X_mlp = np.array(texts)
10133
10137
  y_raw = np.array(labels)
10134
10138
 
10135
- else:
10136
- print('[=] Dataset type 3')
10137
- X_mlp = dataset.copy()
10138
- y_raw = self.auto_generate_labels_from_texts(rules, dataset)
10139
+ else:
10140
+ print('[=] Dataset type 3: raw texts, auto-labeling via rules')
10141
+ X_mlp = dataset.copy()
10142
+ y_raw = self.auto_generate_labels_from_texts(rules, dataset)
10139
10143
 
10140
10144
  unique_labels = sorted(set(y_raw))
10141
- label_to_idx = {l: i for i, l in enumerate(unique_labels)}
10142
- y_indices = np.array([label_to_idx[l] for l in y_raw])
10145
+ label_to_idx = {l: i for i, l in enumerate(unique_labels)}
10146
+ y_indices = np.array([label_to_idx[l] for l in y_raw])
10143
10147
 
10144
10148
  n_classes = len(unique_labels)
10145
- y_onehot = np.zeros((len(y_indices), n_classes))
10149
+ y_onehot = np.zeros((len(y_indices), n_classes))
10146
10150
  y_onehot[np.arange(len(y_indices)), y_indices] = 1
10147
10151
 
10148
-
10149
- if isinstance(X_mlp, np.ndarray):
10150
- input_dim = X_mlp.shape[0]
10152
+ if isinstance(X_mlp, np.ndarray) and X_mlp.ndim > 1:
10153
+ input_dim = X_mlp.shape[1]
10154
+ elif isinstance(X_mlp, np.ndarray):
10155
+ input_dim = 1 # 1D array — single feature per sample
10151
10156
  else:
10152
- input_dim = len(X_mlp)
10157
+ input_dim = len(X_mlp[0]) if len(X_mlp) > 0 else 0
10153
10158
 
10154
10159
  print(f"\n✅ MLP data ready:")
10155
- print(f"[=] X shape: {input_dim}")
10160
+ print(f"[=] X shape: {X_mlp.shape if isinstance(X_mlp, np.ndarray) else len(X_mlp)}")
10161
+ print(f"[=] input_dim: {input_dim}")
10156
10162
  print(f"[=] y shape: {y_onehot.shape}")
10157
- print(f"[=] Classes: {label_to_idx}")
10158
- return X_mlp, y_onehot, n_classes, input_dim
10163
+ print(f"[=] Classes: {label_to_idx}")
10159
10164
 
10160
- def shape_adaptation(self, X, inp):
10161
- tuple_ver = (inp, inp)
10162
- if X.shape != tuple_ver:
10163
- X = X[:inp, :inp]
10165
+ return X_mlp, y_onehot, n_classes, input_dim
10164
10166
 
10165
- return X
10167
+
10168
+ def shape_adaptation(self, X, target_features):
10169
+ """
10170
+ Adapts X's FEATURE dimension (columns) to match target_features.
10171
+ Sample count (rows) is never touched — only column width changes.
10172
+
10173
+ Args:
10174
+ X: (n_samples, n_features) array
10175
+ target_features: desired number of feature columns
10176
+ """
10177
+ try:
10178
+ if X.ndim == 1:
10179
+ X = X.reshape(1, -1)
10180
+
10181
+ n_samples, n_features = X.shape
10182
+
10183
+ if n_features == target_features:
10184
+ return X
10185
+
10186
+ print(f'[⚠️] shape_adaptation: X has {n_features} features, '
10187
+ f'target is {target_features} — adapting columns only '
10188
+ f'(rows={n_samples} unchanged)')
10189
+
10190
+ X_adapted = np.zeros((n_samples, target_features))
10191
+ min_features = min(n_features, target_features)
10192
+ X_adapted[:, :min_features] = X[:, :min_features]
10193
+
10194
+ if n_features > target_features:
10195
+ print(f'[⚠️] shape_adaptation: TRUNCATED {n_features - target_features} '
10196
+ f'feature columns ({n_features} → {target_features})')
10197
+ else:
10198
+ print(f'[=] shape_adaptation: PADDED {target_features - n_features} '
10199
+ f'feature columns with zeros')
10200
+ except Exception as e:
10201
+ print(f'[-] Fallback to primitive shape adaptation due to {e}')
10202
+ print(f'[!] WARNING: This may pad shapes aggressively! ')
10203
+ inp = X.shape[1]
10204
+ tuple_ver = (inp, inp)
10205
+ if X.shape != tuple_ver:
10206
+ X = X[:inp, :inp]
10207
+
10208
+ return X_adapted
10166
10209
 
10167
10210
  def AME_Encoder(self, x):
10168
10211
  X = np.asarray(x)
@@ -10217,9 +10260,40 @@ class IntegratedPipeline:
10217
10260
 
10218
10261
  return X, y, input_dim, n_classes
10219
10262
 
10220
- def _set_lstm_samples(self, X, Y):
10221
- X = np.array(X)[..., np.newaxis]
10222
- Y = np.array(Y)[..., np.newaxis]
10263
+ def _set_lstm_samples(self, X, Y, min_samples_for_split=10, use_cache_augmentation=True):
10264
+ """
10265
+ Reshape X, Y for LSTM input. If sample count is too small for a
10266
+ meaningful train/val split, augment with verified entries from
10267
+ AccurateAnswerCache before reshaping.
10268
+ """
10269
+ try:
10270
+ X = np.array(X)
10271
+ Y = np.array(Y)
10272
+
10273
+ # augment from accurate_cache before reshaping.
10274
+ if use_cache_augmentation and len(X) < min_samples_for_split:
10275
+ if hasattr(self, 'accurate_cache') and self.accurate_cache_lookup.cache:
10276
+ print(f'[=] Only {len(X)} samples — augmenting from accurate_cache '
10277
+ f'(has {len(self.accurate_cache_lookup.cache)} verified entries)')
10278
+
10279
+ cached_X, cached_Y = self._extract_cache_samples_for_lstm(
10280
+ target_count=min_samples_for_split - len(X)
10281
+ )
10282
+
10283
+ if len(cached_X) > 0:
10284
+ X = np.concatenate([X, cached_X], axis=0)
10285
+ Y = np.concatenate([Y, cached_Y], axis=0)
10286
+ print(f'[=] Augmented to {len(X)} samples using '
10287
+ f'{len(cached_X)} verified cache entries')
10288
+ else:
10289
+ print('[=] No suitable cache entries found for augmentation')
10290
+
10291
+ X = X[..., np.newaxis]
10292
+ Y = Y[..., np.newaxis]
10293
+ except Exception as e:
10294
+ print(f'[!] Error in seeting LSTM Samples: {e}, filling gaps with regular newaxis to populate data.')
10295
+ X = X = np.array(X)[..., np.newaxis]
10296
+ Y = np.array(Y)[..., np.newaxis]
10223
10297
 
10224
10298
  print('[=] Successfully set up LSTM Samples:')
10225
10299
  print(f'[=] X.shape: {X.shape}')
@@ -10227,6 +10301,37 @@ class IntegratedPipeline:
10227
10301
 
10228
10302
  return X, Y
10229
10303
 
10304
+
10305
+ def _extract_cache_samples_for_lstm(self, target_count):
10306
+ """
10307
+ Pull verified-correct entries from AccurateAnswerCache to use as
10308
+ additional LSTM training samples — only entries with multiple
10309
+ confirmed hits (hit_count >= 1) to avoid using unverified noise.
10310
+ """
10311
+ if not hasattr(self, 'accurate_cache') or not self.accurate_cache_lookup.cache:
10312
+ return np.array([]), np.array([])
10313
+
10314
+ candidates = [
10315
+ entry for entry in self.accurate_cache_lookup.cache.values()
10316
+ if entry.get('hit_count', 0) >= 1 # only entries confirmed at least once
10317
+ ]
10318
+
10319
+ # prioritize highest-confidence, most-confirmed entries first
10320
+ candidates.sort(key=lambda e: (e['hit_count'], e['confidence']), reverse=True)
10321
+ selected = candidates[:target_count]
10322
+
10323
+ if not selected:
10324
+ return np.array([]), np.array([])
10325
+
10326
+ cached_X = np.array([e['x_mlp'] for e in selected])
10327
+ cached_Y = np.array([
10328
+ e['prediction'] if isinstance(e['prediction'], (int, float))
10329
+ else e['confidence'] # fallback if prediction is a label string
10330
+ for e in selected
10331
+ ])
10332
+
10333
+ return cached_X, cached_Y
10334
+
10230
10335
  def lstm_setup_inference(self, raw_X, raw_Y):
10231
10336
  print("\n" + "=" * 55)
10232
10337
  print("===== LSTM SETUP INFERENCE =====")
@@ -10239,7 +10344,9 @@ class IntegratedPipeline:
10239
10344
  AME = self.AME_Encoder(raw_X) # geometric complexity scalar
10240
10345
  AMR = 1.0 / (1.0 + np.exp(-AME)) # abstract modelling rate
10241
10346
 
10242
- X, Y = self._set_lstm_samples(raw_X, raw_Y)
10347
+ augmentation = AMR > self.confidence_threshold and self.peer_assistance_threshold < 0.15
10348
+ X, Y = self._set_lstm_samples(raw_X, raw_Y, use_cache_augmentation=augmentation)
10349
+
10243
10350
  n_train = int(0.8 * len(X)) # 80% of the data training is used for training
10244
10351
  X_val = X[n_train:]
10245
10352
  Y_val = Y[n_train:]
@@ -12308,7 +12415,8 @@ class PipelineAsyncManager:
12308
12415
  predicted_output.append(advanced_result)
12309
12416
 
12310
12417
  # Get stats
12311
- print(f"[=] Stats: {self.get_stats()}")
12418
+ print(f"[=] Stats: {self.get_stats()}")
12419
+ print('[=] Returning predicted output as list')
12312
12420
  return predicted_output
12313
12421
 
12314
12422
  except Exception as e: