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.
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/PKG-INFO +10 -3
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.py +208 -100
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractOptimizedModules.c +152 -152
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/PKG-INFO +10 -3
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/README.md +9 -2
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/setup.py +2 -9
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/SOURCES.txt +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/dependency_links.txt +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/requires.txt +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.egg-info/top_level.txt +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractOptimizedModules.pyx +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/MANIFEST.in +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/Cargo.toml +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/pyproject.toml +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/src/lib.rs +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/debug/build/libsqlite3-sys-ed07b882cd2aa5e2/out/bindgen.rs +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/debug/build/target-lexicon-08527f45de28143d/out/host.rs +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/release/build/libsqlite3-sys-bf0400df4523274c/out/bindgen.rs +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/abstract_model_storage/target/release/build/target-lexicon-43eb95a0588bf457/out/host.rs +0 -0
- {abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/pyproject.toml +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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" />
|
{abstractintegratedmodule-0.7.0 → abstractintegratedmodule-0.7.1}/AbstractIntegratedModule.py
RENAMED
|
@@ -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(
|
|
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
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9914
|
-
for i in range(batch_size):
|
|
9915
|
-
mlp_target = target_preds[i]
|
|
9918
|
+
temperature_accum = []
|
|
9916
9919
|
|
|
9917
|
-
|
|
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
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
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
|
-
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
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
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
10142
|
-
y_indices
|
|
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
|
|
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
|
-
|
|
10150
|
-
|
|
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: {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
10222
|
-
Y
|
|
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
|
-
|
|
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:
|