File size: 11,627 Bytes
2e41b25 8f0d906 2e41b25 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | ---
license: mit
language:
- en
tags:
- neural-network
- self-training
- anomaly-detection
- patent
- comfyui
---
# STANNO β Self-Training Artificial Neural Network Object
A neural network that trains another neural network. No backpropagation. Directly modifies weights.
## What is this?
STANNO is a modern, open-source implementation of the **Artificial Neurogenesis Network** concept from US Patent 5,852,815 (Thaler, 1998). Instead of using backpropagation to update weights, one network (the **TrainerNet**) computes weight updates for another network (the **TraineeNet**) by analyzing its internal state.
Think of it as: you have a student network that learns, and a teacher network that decides how the student's weights should change β without autodiff, without gradients.
Multiple STANNOs can be **cascaded** into pipelines where the output of one feeds the next, trained end-to-end with gradient flow across stage boundaries. A **DSANNO** (Data Scanning variant) wraps any trained STANNO and scans large datasets to find rows that match its learned representation β the inverse of anomaly detection.
### Patent & Attribution
This codebase is an implementation of the architecture described in **US Patent 5,852,815** (*Artificial Neurogenesis Network*) filed by Stephen L. Thaler. The original patent has expired (US utility patents run 20 years from filing date). This open-source implementation builds upon the original design with modern extensions: **CascadeSTANNO** (multi-stage gradient flow), **DSANNO** (data scanning), and integration with contemporary frameworks (PyTorch, ComfyUI).
We acknowledge and attribute all core concepts to Thaler's patent. See [Patents & Reference](#papers--reference) below for full citation details.
## β οΈ Before you start
**STANNO is specialized**, not a general-purpose neural network. It's designed for:
- Anomaly detection β
- Online learning β
- Interpretability β
It's **not** for:
- Regression (use PyTorch/TensorFlow instead)
- Image generation alone (use with ComfyUI + SD 1.5)
- High-accuracy function fitting
See [STANNO_IS_NOT.md](STANNO_IS_NOT.md) for details.
## Why would I use this?
- **Direct weight modification**: The trainer has explicit control over what happens to each synapse. Useful for interpretability, debugging, or unconventional training schemes.
- **Meta-learning friendly**: The trainer itself can be learned (via evolution or other methods). Different tasks can teach the trainer how to train.
- **Composable**: Three trainer implementations (Fixed, LocalRule, Evolutionary) let you pick the right tool.
- **Cascadable**: Chain multiple STANNOs into encoder-decoder pipelines or progressive compression networks. Freeze individual stages, adapt others β all in the same object.
- **Data scanning**: DSANNO turns any trained STANNO into a semantic scanner. Find the rows in a large dataset that most closely match the network's learned distribution, with auto-calibrated thresholds and top-k retrieval.
- **ComfyUI integration**: Nine custom nodes for image generation workflows.
- **Works with LLMs**: Filter or augment LLM inputs/outputs using STANNO's anomaly detection.
## Install
```bash
pip install git+https://github.com/nitroxido/stanno.git
```
Or clone and install locally:
```bash
git clone https://github.com/nitroxido/stanno.git
cd stanno
pip install -e .
```
For ComfyUI, the nodes auto-install via ComfyUI-Manager, or manually:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/nitroxido/comfyui-stanno.git
cd comfyui-stanno
pip install -r requirements.txt
```
## Quick Start
### Train on sin(x)
```python
import numpy as np
from stanno import STANNO
from stanno.config.schema import STANNOConfig
# Config
config = STANNOConfig(
layers=[1, 32, 1],
trainer_type="fixed",
learning_rate=0.005,
)
# Data
x = np.linspace(0, 1, 512, dtype=np.float32).reshape(-1, 1)
y = np.sin(2 * np.pi * x).astype(np.float32)
# Train
stanno = STANNO(config)
stanno.fit(x, y, epochs=500, batch_size=64)
# Predict
y_pred = stanno.predict(np.array([[0.25]], dtype=np.float32))
print(f"sin(0.25) β {y_pred[0, 0]:.3f}") # β 0.587
```
### Load from config file
```bash
python -m stanno train --config examples/sin_regression.json
python -m stanno predict --config examples/sin_regression.json --input 0.25
python -m stanno dream --config examples/sin_regression.json
```
### Anomaly filtering (pre-filter for LLM)
```python
from stanno import STANNO
from stanno.config.schema import FilterConfig
from stanno.integration.filter import STANNOFilter
from stanno.integration.llm_client import LLMClient
# Train STANNO on normal embeddings
stanno = STANNO(...)
stanno.fit(normal_embeddings, normal_embeddings, epochs=100)
# Set up filter
filter_config = FilterConfig(anomaly_threshold=0.7, block_above_threshold=True)
llm = LLMClient(llm_config)
filt = STANNOFilter(stanno, filter_config, llm)
# Score incoming prompt
score, meta = filt.score(embedding)
if not meta["blocked"]:
response = filt.filter_and_send(messages, embedding)
```
### Online learning
```python
from stanno.integration.continual import ContinualSTANNO
cont = ContinualSTANNO(stanno)
# One sample at a time
for x_i, y_i in stream:
loss = cont.observe(x_i, y_i)
print(f"Step {cont.steps}: loss={loss:.4f}")
# Check held-out test set
test_loss = cont.test_loss(x_test, y_test)
print(f"Test loss: {test_loss:.4f}")
```
### Cascading (encoder β decoder pipeline)
```python
from stanno import STANNO, STANNOConfig, CascadeSTANNO
# Two-stage autoencoder: compress 768-D embeddings to 64-D
enc = STANNO(STANNOConfig(layers=[768, 256, 64], learning_rate=0.05))
dec = STANNO(STANNOConfig(layers=[64, 256, 768], learning_rate=0.05))
ae = CascadeSTANNO([enc, dec])
ae.fit(embeddings, embeddings, epochs=200, batch_size=32)
# Get compressed representation
codes = ae.intermediate_output(embeddings, stage=0) # (N, 64)
# Freeze encoder, continue training decoder
ae.freeze(0)
ae.fit(embeddings, embeddings, epochs=100) # only decoder updates
```
CLI equivalent:
```bash
python -m stanno cascade --config examples/cascade_autoencoder.json
```
### Data scanning (DSANNO)
```python
from stanno import STANNO, STANNOConfig, DSANNO
# Train on known-good data
detector = STANNO(STANNOConfig(layers=[64, 128, 64], learning_rate=0.05))
detector.fit(normal_data, normal_data, epochs=200)
scanner = DSANNO(detector, mode="reconstruction")
# Auto-calibrate threshold from training distribution
threshold = scanner.calibrate_threshold(normal_data, percentile=95)
# Scan a large dataset β returns matching rows
result = scanner.scan(large_dataset, threshold=threshold)
matching_rows = large_dataset[result.matched_indices()]
# Or just get the top-k best matches
indices, scores, _ = scanner.top_k(large_dataset, k=20)
```
CLI equivalent:
```bash
python -m stanno scan --model model.stanno.pkl --data corpus.npy --top-k 20
python -m stanno scan --model model.stanno.pkl --data corpus.npy --threshold 0.05
```
## The three trainers
| Trainer | How it works | Use case |
|---------|-------------|----------|
| **Fixed** | 4-module patent-faithful design. No learning, deterministic. | Baseline, reproducibility |
| **LocalRule** | Shared MLP learns per-synapse update rules. Can meta-train. | Adaptive training, interpretability |
| **Evolutionary** | ES-based. Evolves per-layer learning rates. No autodiff. | Exploration, unconventional problems |
## ComfyUI nodes
Nine nodes in the **STANNO** category:
| Node | What it does |
|------|--------------|
| **STANNOLoad** | Create or load a STANNO model |
| **STANNOTrainImages** | Train as autoencoder on image batch |
| **STANNOScoreImages** | Filter images by reconstruction error |
| **STANNODreamCond** | Modify CLIP conditioning with dream mode |
| **STANNODynamicLoRA** | Apply dream output as LoRA patches |
| **STANNOCompositeCheck** | Route images to whichever of two STANNOs matches best |
| **STANNOScan** | DSANNO scanner: auto-calibrated threshold + top-k image retrieval |
| **STANNOCascadeLoad** | Create or load a multi-stage CascadeSTANNO |
| **STANNOCascadeTrainImages** | Train a cascade end-to-end on an image batch |
See [comfyui-stanno-integration.md](./comfyui-stanno-integration.md) for workflows and examples.
## Architecture
```
stanno/
βββ config/ # Dataclasses for all configuration
βββ core/
β βββ backend.py # NumPy & PyTorch backend abstraction
β βββ trainer.py # AbstractTrainerNet base class + cascade API
β βββ trainee.py # TraineeNet (the student network)
β βββ stanno.py # STANNO orchestrator
βββ trainers/
β βββ fixed.py # 4-module patent design (cascade-aware)
β βββ local_rule.py # Learned per-synapse rules
β βββ evolutionary.py # ES-based adaptation
βββ data/ # Loaders for CSV, JSON, NumPy, builtin datasets
βββ integration/
β βββ llm_client.py # OpenAI-compatible HTTP client (Ollama, etc.)
β βββ filter.py # STANNOFilter for anomaly detection
β βββ continual.py # ContinualSTANNO for online learning
β βββ cascade.py # CascadeSTANNO β multi-stage chained networks
β βββ dsanno.py # DSANNO β data scanning and semantic retrieval
βββ cli.py # Command-line interface
```
### CLI subcommands
| Command | What it does |
|---------|--------------|
| `stanno train` | Train a single STANNO from a JSON config |
| `stanno predict` | Run one prediction |
| `stanno dream` | Generate a sequence via dream mode |
| `stanno evaluate` | Compute MSE/MAE on a dataset |
| `stanno filter` | Run anomaly filter on a file of prompts |
| `stanno cascade` | Train a CascadeSTANNO from a JSON config |
| `stanno scan` | Scan a `.npy` dataset with a trained STANNO |
## Configuration
All settings in JSON. Example:
```json
{
"stanno": {
"layers": [1, 32, 1],
"trainer_type": "fixed",
"learning_rate": 0.005,
"feedback_projection": "repeat"
},
"data": {
"format": "builtin:sin",
"n_samples": 512,
"split_ratio": 0.8
},
"fit": {
"epochs": 500,
"batch_size": 64,
"log_every": 50
}
}
```
See [examples/](./examples/) for more.
## Testing
```bash
python -c "
import numpy as np
from stanno import STANNO
from stanno.config.schema import STANNOConfig
for trainer_type in ['fixed', 'local_rule', 'evolutionary']:
cfg = STANNOConfig(layers=[1, 32, 1], trainer_type=trainer_type)
stanno = STANNO(cfg)
x = np.linspace(0, 1, 100, dtype='f').reshape(-1, 1)
y = np.sin(2*np.pi*x).astype('f')
stanno.fit(x, y, epochs=50, batch_size=16)
pred = stanno.predict(x[:5])
mse = np.mean((pred - y[:5])**2)
print(f'{trainer_type:15s} MSE={mse:.5f}')
"
```
Expected output:
```
fixed MSE=0.24653
local_rule MSE=0.01234
evolutionary MSE=0.35421
```
## Papers & Reference
- **Original Patent**: Thaler, S. L. (1998). *Artificial neurogenesis network*. US Patent 5,852,815.
- **Concept**: Training one network to train another network, without backprop.
- **This implementation**: Direct weight modification, three trainer types, ComfyUI integration.
## License
MIT
## Contributing
Bug reports, feature requests, and pull requests welcome. Start with an issue describing what you want to do.
## Contact
nitroxido
https://github.com/nitroxido
https://x.com/CompotaMission
## ComfyUI Integration
See [comfyui-stanno](https://huggingface.co/oldman-dev/comfyui-stanno)
for ComfyUI custom nodes. |