Add scaled WRN model + capability benchmark report and plots
Browse files- BENCHMARK_REPORT.md +146 -0
- MODEL_CARD.md +85 -0
- load_akn.py +107 -0
- plots/bench_forgetting.png +0 -0
- plots/bench_mindstate.png +0 -0
- plots/bench_pramana.png +0 -0
- plots/bench_retention.png +0 -0
- plots/bench_scorecard.png +0 -0
BENCHMARK_REPORT.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Antaḥkaraṇa-Net — Scale-Up Benchmark & Performance Report
|
| 2 |
+
|
| 3 |
+
**A capability benchmark of the Vedic-mind continual-learning architecture at 36.5M–52.6M parameters.**
|
| 4 |
+
All numbers are from **live inference on the trained checkpoints** (the model is loaded from disk and
|
| 5 |
+
re-evaluated), not training-time logs. 11 models, 7 capabilities each, run on a single NVIDIA A10.
|
| 6 |
+
|
| 7 |
+
> **Scope, stated up front.** This is a *research proof-of-concept*: WideResNets on Split-CIFAR-100 and
|
| 8 |
+
> Split-Tiny-ImageNet. The contribution is the **architecture** — one agent that learns continually
|
| 9 |
+
> without forgetting, abstains instead of hallucinating, and self-regulates — demonstrated to *scale*
|
| 10 |
+
> from the original small-CNN POC to real models. It is not, and is not meant to be, a frontier model.
|
| 11 |
+
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
## 1. Setup
|
| 15 |
+
|
| 16 |
+
| | |
|
| 17 |
+
|---|---|
|
| 18 |
+
| **Architectures** | WRN-28-10 (**36.5M params**), WRN-28-12 (**52.6M params**) — shared trunk φ + one linear head per task |
|
| 19 |
+
| **Control ring** | chitta (saṃskāra EWC+decay), guṇa (forgetting-aware MetaGunaController), āśrama, tapas, pramāṇa, turīya |
|
| 20 |
+
| **Datasets** | Split-CIFAR-100 (10×10 and 20×5 class-incremental); Split-Tiny-ImageNet (200-class, 10×20, 64→32) |
|
| 21 |
+
| **OOD set (pramāṇa)** | SVHN (test) |
|
| 22 |
+
| **Training** | from scratch, 25 epochs/task, Adam; wake→dream(replay)→sleep(consolidate) cycle |
|
| 23 |
+
| **Hardware** | OCI `BM.GPU.A10.4` → single A10 (23 GB), us-sanjose-1 |
|
| 24 |
+
| **Protocol** | per-checkpoint live inference: per-task accuracy, pramāṇa gating, temperature calibration, mind-state trace |
|
| 25 |
+
| **Seeds** | core ×5, scale ×2, tiny ×2, āśrama ×2 (11 models total) |
|
| 26 |
+
|
| 27 |
+
## 2. Capability scorecard (the 7 checks + PASS criteria)
|
| 28 |
+
|
| 29 |
+
| # | Capability (faculty) | PASS criterion |
|
| 30 |
+
|---|---|---|
|
| 31 |
+
| 1 | **Learns the task** (buddhi+backbone) | avg accuracy > 3× chance |
|
| 32 |
+
| 2 | **Continual memory** (chitta/saṃskāra) | forgetting ≤ 0.05 **and** all tasks > 1.5× chance |
|
| 33 |
+
| 3 | **Anti-hallucination** (pramāṇa) | gated acc ≥ raw acc **and** OOD blind-accept < 30% |
|
| 34 |
+
| 4 | **Calibration** | ECE decreases after temperature scaling |
|
| 35 |
+
| 5 | **Self-regulation** (guṇa) | plasticity headroom decreases over life |
|
| 36 |
+
| 6 | **Lifelong** (āśrama) | progresses through life-stages to vānaprastha/saṃnyāsa |
|
| 37 |
+
| 7 | **Identity monitor** (turīya) | witness drift bounded (< 1.0) |
|
| 38 |
+
|
| 39 |
+
**Result: 10 of 11 models pass 7/7; 1 passes 6/7** (āśrama_s0 — see §6, a threshold artifact).
|
| 40 |
+
|
| 41 |
+
## 3. Headline results — group means
|
| 42 |
+
|
| 43 |
+
| Configuration | Params | Avg acc | Naive forget | **Agent forget** | **Reduction** | Gated acc | OOD accept |
|
| 44 |
+
|---|---|---|---|---|---|---|---|
|
| 45 |
+
| **core** — CIFAR-100, 10 tasks | 36.5M | 0.599 | 0.589 | **0.0146** | **41.0×** | 0.929 | 8.4% |
|
| 46 |
+
| **scale** — CIFAR-100, 10 tasks | 52.6M | 0.615 | 0.551 | **0.0204** | **27.3×** | 0.933 | 10.0% |
|
| 47 |
+
| **tiny** — Tiny-ImageNet, 10 tasks | 36.5M | 0.416 | 0.503 | **0.0173** | **29.1×** | 0.956 | 0.3% |
|
| 48 |
+
| **āśrama** — CIFAR-100, **20 tasks** | 36.5M | 0.606 | 0.595 | **0.0474** | **12.5×** | 0.960 | 1.3% |
|
| 49 |
+
|
| 50 |
+
**Read:** catastrophic forgetting is cut **12–41×** across two model sizes, two datasets, and stream lengths
|
| 51 |
+
of 10 and 20 tasks. The agent both *remembers* (forgetting → ~0.01–0.05) and *learns better* (accuracy
|
| 52 |
+
roughly **doubles** vs the naive baseline, which collapses to its last task).
|
| 53 |
+
|
| 54 |
+

|
| 55 |
+
|
| 56 |
+

|
| 57 |
+
|
| 58 |
+
## 4. Per-model detail (live inference)
|
| 59 |
+
|
| 60 |
+
| Model | Data | Avg acc | Naive→Agent forget | Reduction | Gated@cov | OOD accept | ECE before→after | Score |
|
| 61 |
+
|---|---|---|---|---|---|---|---|---|
|
| 62 |
+
| core_s0 | CIFAR-100 | 0.616 | 0.565→0.018 | 31.8× | 0.943@0.21 | 16.1% | 0.172→0.023 | 7/7 |
|
| 63 |
+
| core_s1 | CIFAR-100 | 0.592 | 0.621→0.014 | 45.1× | 0.950 | 6.4% | 0.172→0.043 | 7/7 |
|
| 64 |
+
| core_s2 | CIFAR-100 | 0.617 | 0.583→0.012 | 49.9× | 0.918 | 2.6% | 0.118→0.025 | 7/7 |
|
| 65 |
+
| core_s3 | CIFAR-100 | 0.587 | 0.553→0.015 | 37.1× | 0.927 | 8.2% | 0.150→0.024 | 7/7 |
|
| 66 |
+
| core_s4 | CIFAR-100 | 0.585 | 0.621→0.015 | 41.1× | 0.907 | 8.4% | 0.163→0.035 | 7/7 |
|
| 67 |
+
| scale_s0 | CIFAR-100 | 0.620 | 0.542→0.021 | 25.4× | 0.921 | 8.7% | 0.229→0.027 | 7/7 |
|
| 68 |
+
| scale_s1 | CIFAR-100 | 0.610 | 0.570→0.019 | 29.3× | 0.944 | 11.2% | 0.195→0.032 | 7/7 |
|
| 69 |
+
| tin_s0 | Tiny-ImageNet | 0.411 | 0.503→0.017 | 29.2× | 1.000 | 0.4% | 0.226→0.025 | 7/7 |
|
| 70 |
+
| tin_s1 | Tiny-ImageNet | 0.421 | 0.502→0.017 | 29.0× | 0.912 | 0.2% | 0.196→0.034 | 7/7 |
|
| 71 |
+
| ashrama_s0 | CIFAR-100 (20t) | 0.592 | 0.603→0.049 | 12.3× | 0.951 | 1.7% | 0.225→0.046 | 6/7 |
|
| 72 |
+
| ashrama_s1 | CIFAR-100 (20t) | 0.621 | 0.586→0.046 | 12.8× | 0.969 | 1.0% | 0.246→0.057 | 7/7 |
|
| 73 |
+
|
| 74 |
+
## 5. Analysis
|
| 75 |
+
|
| 76 |
+
**Scaling (36.5M → 52.6M).** Increasing capacity keeps the effect and nudges accuracy up (0.599 → 0.615).
|
| 77 |
+
The forgetting-reduction *ratio* is a touch lower at 52.6M (27× vs 41×), but absolute agent-forgetting stays
|
| 78 |
+
tiny (0.020 vs 0.015) — i.e. both models forget almost nothing; the ratio mostly reflects naive-baseline
|
| 79 |
+
variance. **The architecture is genuinely backbone-agnostic across sizes.**
|
| 80 |
+
|
| 81 |
+
**Difficulty — dataset.** Tiny-ImageNet (200 fine-grained classes at 32 px) is much harder, so raw accuracy
|
| 82 |
+
drops to ~0.42. Crucially, **forgetting reduction holds (29×)** and the model becomes *more* conservative:
|
| 83 |
+
it abstains on **99.7%** of OOD inputs and clears only its most-confident in-distribution predictions —
|
| 84 |
+
exactly the right behavior when uncertain.
|
| 85 |
+
|
| 86 |
+
**Difficulty — stream length.** Doubling the stream (10 → 20 tasks, āśrama) is the hardest continual setting:
|
| 87 |
+
twice as many tasks to retain with more interference. Reduction drops to **12.5×** (agent-forgetting 0.047) —
|
| 88 |
+
**lower than the 10-task runs, and honestly so** — yet all 20/20 tasks remain above chance and the model still
|
| 89 |
+
abstains/calibrates cleanly. A >12× cut over a 20-task lifelong run is a strong result.
|
| 90 |
+
|
| 91 |
+

|
| 92 |
+
*Per-task accuracy after the full stream — every task stays well above chance; the agent does not collapse
|
| 93 |
+
to its last task (which is what the naive baseline does).*
|
| 94 |
+
|
| 95 |
+
**Anti-hallucination (pramāṇa).** Calibrated abstention works everywhere: gated accuracy **0.91–1.00** (vs raw
|
| 96 |
+
~0.42–0.67), and OOD blind-accept **0.2%–16%**. The harder the data, the lower the model's confidence and the
|
| 97 |
+
more it abstains — a desirable, safety-aligned property. Coverage is correspondingly lower on hard sets
|
| 98 |
+
(a deliberate trade: it commits less, but is right when it does).
|
| 99 |
+
|
| 100 |
+

|
| 101 |
+
|
| 102 |
+
**Calibration.** Temperature scaling reduces ECE everywhere (e.g. 0.172 → 0.023), so reported confidence can
|
| 103 |
+
be trusted — the precondition for the abstention gate to be meaningful.
|
| 104 |
+
|
| 105 |
+
**Interpretability (mind-state).** Every model exposes a legible trajectory: plasticity headroom **falls over
|
| 106 |
+
life** (e.g. 0.92 → 0.37; 0.77 → 0.14 on the 20-task run), the agent **ages through all four āśramas**
|
| 107 |
+
(brahmacarya → gṛhastha → vānaprastha → saṃnyāsa), and **turīya drift stays bounded** (~0.50–0.59). You can
|
| 108 |
+
read the agent's regulation as it lives — not a black box.
|
| 109 |
+
|
| 110 |
+

|
| 111 |
+
|
| 112 |
+
## 6. The one 6/7, explained (no goalpost-moving)
|
| 113 |
+
|
| 114 |
+
**āśrama_s0** failed only **capability 1 (learns the task)**: avg accuracy **0.592 vs the 0.60 bar**
|
| 115 |
+
(= 3× chance for 5-class tasks). That's **2.96× chance** — a hair under an arbitrary threshold. Its
|
| 116 |
+
*continual_memory* check passed with **20/20 tasks retained and 12.3× forgetting reduction**, and āśrama_s1
|
| 117 |
+
(same config) scored 0.621 → 7/7. This is **benchmark-threshold variance on a borderline metric**, not a model
|
| 118 |
+
deficiency. We report it as-is rather than relax the criterion.
|
| 119 |
+
|
| 120 |
+
## 7. Honest caveats
|
| 121 |
+
|
| 122 |
+
- **POC scale.** Small/mid models, 32 px imagery. Demonstrates the *architecture*, not SOTA accuracy.
|
| 123 |
+
- **Forgetting reduction ratios are noisy** across seeds (driven partly by naive-baseline variance); the
|
| 124 |
+
trustworthy claim is *absolute agent-forgetting ≈ 0.01–0.05 everywhere*.
|
| 125 |
+
- **Low coverage on hard datasets** is the flip side of strong abstention — fewer commitments, higher precision.
|
| 126 |
+
- **OOD uses SVHN with CIFAR-100 normalization** for all models (a single fixed OOD probe); a per-dataset OOD
|
| 127 |
+
suite would sharpen the tiny-imagenet numbers.
|
| 128 |
+
- **Vedic↔ML mappings are engineering analogies**, clearly flagged. Nothing here is conscious.
|
| 129 |
+
|
| 130 |
+
## 8. Reproducibility
|
| 131 |
+
|
| 132 |
+
```bash
|
| 133 |
+
# train (per phase, resumable, idempotent):
|
| 134 |
+
bash scale/phases.sh # core → scale → pramana → tinyimagenet → ashrama
|
| 135 |
+
# benchmark any checkpoint (live inference, 7-capability report + JSON):
|
| 136 |
+
CUDA_VISIBLE_DEVICES=0 python3 scale/capability_bench.py --ckpt runs/<tag>.pt
|
| 137 |
+
```
|
| 138 |
+
|
| 139 |
+
Artifacts: 11 checkpoints (`runs/*.pt`), 11 training results (`runs/*.json`), 11 capability reports
|
| 140 |
+
(`runs/*_capbench.json`), and this report. The uploadable model is `antahkarana_cifar100_wrn28-10.pt`
|
| 141 |
+
(36.5M, with Ω/θ* consolidation state) + `load_akn.py` + `MODEL_CARD.md` in `scale/hf_package/`.
|
| 142 |
+
|
| 143 |
+
---
|
| 144 |
+
|
| 145 |
+
*Generated from live-inference benchmarks on trained checkpoints. Code: MIT. Built on the Upaniṣads,
|
| 146 |
+
Sāṃkhya, Yoga, and PyTorch · snnTorch.*
|
MODEL_CARD.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
library_name: pytorch
|
| 4 |
+
tags:
|
| 5 |
+
- continual-learning
|
| 6 |
+
- cognitive-architecture
|
| 7 |
+
- vedic-ai
|
| 8 |
+
- catastrophic-forgetting
|
| 9 |
+
- wide-resnet
|
| 10 |
+
- cifar-100
|
| 11 |
+
datasets:
|
| 12 |
+
- cifar100
|
| 13 |
+
pipeline_tag: image-classification
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# Antaḥkaraṇa-Net — scaled checkpoint (WRN-28-10, Split-CIFAR-100)
|
| 17 |
+
|
| 18 |
+
A **36.5M-parameter WideResNet** trained as one continual-learning agent under the full
|
| 19 |
+
Antaḥkaraṇa control ring (saṃskāra · guṇa · āśrama · tapas · pramāṇa · turīya). This is
|
| 20 |
+
the **scale-up** of the original [Antaḥkaraṇa-Net](https://huggingface.co/deepakdsoni/antahkarana)
|
| 21 |
+
proof-of-concept: the same Vedic-mind architecture, now on a real WideResNet across
|
| 22 |
+
**10 sequential CIFAR-100 tasks** — and the no-forgetting result holds.
|
| 23 |
+
|
| 24 |
+
> **What this checkpoint *is*:** the trained trunk + per-task heads **plus** the saved
|
| 25 |
+
> saṃskāra consolidation state (Ω importance and θ* reference weights). It is a research
|
| 26 |
+
> artifact demonstrating *lifelong learning without forgetting at scale* — not a
|
| 27 |
+
> general-purpose classifier.
|
| 28 |
+
|
| 29 |
+
## Results — Split-CIFAR-100, 10 tasks × 10 classes (5-seed means, real runs on an A10)
|
| 30 |
+
|
| 31 |
+
| Metric | Naive (no faculties) | **Antaḥkaraṇa agent** |
|
| 32 |
+
|---|---|---|
|
| 33 |
+
| **Catastrophic forgetting** ↓ | 0.589 | **0.0146 (~41× lower)** |
|
| 34 |
+
| Average accuracy ↑ | 0.304 | **0.600** |
|
| 35 |
+
| Pramāṇa gated accuracy | — | **~0.93** (abstains when not confident) |
|
| 36 |
+
|
| 37 |
+
Per-seed forgetting reductions: **31.8× / 45.1× / 49.9× / 37.1× / 41.1×**.
|
| 38 |
+
A larger **WRN-28-12 (~52M)** run reproduces the effect: forgetting **0.542 → 0.021 (25.4×)**.
|
| 39 |
+
|
| 40 |
+
The agent both **remembers** (forgetting nearly eliminated) and **learns better**
|
| 41 |
+
(accuracy ~doubled), because consolidation protects prior tasks while the
|
| 42 |
+
forgetting-aware guṇa controller relaxes protection where it isn't needed.
|
| 43 |
+
|
| 44 |
+

|
| 45 |
+
|
| 46 |
+
**Full benchmark** (11 models, 7 capabilities, live inference) → [`BENCHMARK_REPORT.md`](BENCHMARK_REPORT.md).
|
| 47 |
+
Across two model sizes (36.5M / 52.6M), two datasets (CIFAR-100, Tiny-ImageNet), and 10- and 20-task
|
| 48 |
+
streams: forgetting cut **12–41×**, calibrated abstention (gated acc 0.91–1.00, abstains on up to 99.7% of
|
| 49 |
+
OOD), and a legible mind-state trajectory. **10 of 11 models pass 7/7 capability checks.**
|
| 50 |
+
|
| 51 |
+

|
| 52 |
+
|
| 53 |
+
## Files
|
| 54 |
+
|
| 55 |
+
- `antahkarana_cifar100_wrn28-10.pt` — the checkpoint (`model_state`, `config`, `results`, `omega`, `theta_star`)
|
| 56 |
+
- `load_akn.py` — **self-contained** loader (full model definition inside; only needs PyTorch)
|
| 57 |
+
|
| 58 |
+
## Usage
|
| 59 |
+
|
| 60 |
+
```python
|
| 61 |
+
import torch
|
| 62 |
+
from load_akn import load
|
| 63 |
+
|
| 64 |
+
model, ck = load("antahkarana_cifar100_wrn28-10.pt") # eval mode
|
| 65 |
+
# CIFAR-100 normalized 32×32 input; task in [0..9] selects the head
|
| 66 |
+
x = torch.randn(1, 3, 32, 32)
|
| 67 |
+
logits = model(x, task=0) # -> (1, 10)
|
| 68 |
+
|
| 69 |
+
print(ck["results"]["agent"]) # the honest metrics
|
| 70 |
+
print("Ω present:", "omega" in ck) # saṃskāra importance, for inspection / resume
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
## Training
|
| 74 |
+
|
| 75 |
+
WideResNet-28-10 trunk + one linear head per task, trained **from scratch** through the
|
| 76 |
+
four-state cycle (wake → dream/replay → sleep/consolidate). Consolidation:
|
| 77 |
+
`Ω ← (1−λ)Ω + γ·Fisher`, penalty `β·ΣΩ(θ−θ*)²`, with β set by the forgetting-aware guṇa
|
| 78 |
+
controller. 25 epochs/task, Adam. Code: [`scale/akn_train.py`](https://huggingface.co/deepakdsoni/antahkarana).
|
| 79 |
+
|
| 80 |
+
## Honest scope
|
| 81 |
+
|
| 82 |
+
Research proof-of-concept at modest scale (WRN on CIFAR-100). The Vedic↔ML mappings are
|
| 83 |
+
engineering analogies, clearly flagged; nothing here is conscious. Full method, every
|
| 84 |
+
number, and the component scorecard are in the
|
| 85 |
+
[main repo](https://huggingface.co/deepakdsoni/antahkarana). Code: MIT.
|
load_akn.py
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
load_akn.py — self-contained loader for the Antaḥkaraṇa-Net scaled checkpoint.
|
| 3 |
+
|
| 4 |
+
No repo needed: this file carries the full model definition, so you can load the
|
| 5 |
+
released `.pt` and run inference / inspect the saved consolidation state (Ω, θ*)
|
| 6 |
+
with just PyTorch.
|
| 7 |
+
|
| 8 |
+
from load_akn import load
|
| 9 |
+
model, ckpt = load("antahkarana_cifar100_wrn28-10.pt")
|
| 10 |
+
# model(x, task) -> logits for that task's head ; task in [0..n_tasks-1]
|
| 11 |
+
|
| 12 |
+
The checkpoint dict contains:
|
| 13 |
+
model_state — the trained WideResNet trunk + per-task heads
|
| 14 |
+
config — {depth, width, n_tasks, classes_per_task}
|
| 15 |
+
results — the honest metrics (forgetting, accuracy, pramāṇa gating, per-task)
|
| 16 |
+
omega / theta_star (optional) — saṃskāra importance Ω and reference weights θ*
|
| 17 |
+
"""
|
| 18 |
+
from __future__ import annotations
|
| 19 |
+
import torch, torch.nn as nn, torch.nn.functional as F
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# --------------------------------------------------------------- WideResNet (CIFAR)
|
| 23 |
+
class _BasicBlock(nn.Module):
|
| 24 |
+
def __init__(self, in_p, out_p, stride, drop=0.0):
|
| 25 |
+
super().__init__()
|
| 26 |
+
self.bn1 = nn.BatchNorm2d(in_p); self.conv1 = nn.Conv2d(in_p, out_p, 3, stride, 1, bias=False)
|
| 27 |
+
self.bn2 = nn.BatchNorm2d(out_p); self.conv2 = nn.Conv2d(out_p, out_p, 3, 1, 1, bias=False)
|
| 28 |
+
self.drop = drop
|
| 29 |
+
self.equalInOut = (in_p == out_p and stride == 1)
|
| 30 |
+
self.shortcut = None if self.equalInOut else nn.Conv2d(in_p, out_p, 1, stride, 0, bias=False)
|
| 31 |
+
|
| 32 |
+
def forward(self, x):
|
| 33 |
+
if not self.equalInOut:
|
| 34 |
+
x = F.relu(self.bn1(x)); out = F.relu(self.bn2(self.conv1(x)))
|
| 35 |
+
else:
|
| 36 |
+
out = F.relu(self.bn1(x)); out = F.relu(self.bn2(self.conv1(out)))
|
| 37 |
+
if self.drop > 0:
|
| 38 |
+
out = F.dropout(out, self.drop, self.training)
|
| 39 |
+
out = self.conv2(out)
|
| 40 |
+
return out + (x if self.equalInOut else self.shortcut(x))
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
class _WideResNet(nn.Module):
|
| 44 |
+
def __init__(self, depth=28, widen=10, drop=0.0):
|
| 45 |
+
super().__init__()
|
| 46 |
+
assert (depth - 4) % 6 == 0
|
| 47 |
+
n = (depth - 4) // 6
|
| 48 |
+
ch = [16, 16 * widen, 32 * widen, 64 * widen]
|
| 49 |
+
self.conv1 = nn.Conv2d(3, ch[0], 3, 1, 1, bias=False)
|
| 50 |
+
self.block1 = self._make(ch[0], ch[1], n, 1, drop)
|
| 51 |
+
self.block2 = self._make(ch[1], ch[2], n, 2, drop)
|
| 52 |
+
self.block3 = self._make(ch[2], ch[3], n, 2, drop)
|
| 53 |
+
self.bn1 = nn.BatchNorm2d(ch[3]); self.nChannels = ch[3]
|
| 54 |
+
|
| 55 |
+
def _make(self, in_p, out_p, n, stride, drop):
|
| 56 |
+
return nn.Sequential(*[_BasicBlock(in_p if i == 0 else out_p, out_p,
|
| 57 |
+
stride if i == 0 else 1, drop) for i in range(n)])
|
| 58 |
+
|
| 59 |
+
def features(self, x):
|
| 60 |
+
out = self.conv1(x); out = self.block1(out); out = self.block2(out); out = self.block3(out)
|
| 61 |
+
out = F.relu(self.bn1(out)); out = F.avg_pool2d(out, 8)
|
| 62 |
+
return out.view(-1, self.nChannels)
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class AntahkaranaWRN(nn.Module):
|
| 66 |
+
"""Shared WRN trunk (φ) + one linear head per task (buddhi)."""
|
| 67 |
+
def __init__(self, depth, widen, n_tasks, classes_per_task):
|
| 68 |
+
super().__init__()
|
| 69 |
+
self.backbone = _WideResNet(depth, widen)
|
| 70 |
+
self.heads = nn.ModuleList([nn.Linear(self.backbone.nChannels, classes_per_task)
|
| 71 |
+
for _ in range(n_tasks)])
|
| 72 |
+
|
| 73 |
+
def features(self, x):
|
| 74 |
+
return self.backbone.features(x)
|
| 75 |
+
|
| 76 |
+
def forward(self, x, task: int):
|
| 77 |
+
return self.heads[task](self.features(x))
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def load(path: str, map_location="cpu"):
|
| 81 |
+
"""Return (model_in_eval_mode, full_checkpoint_dict)."""
|
| 82 |
+
ck = torch.load(path, map_location=map_location, weights_only=False)
|
| 83 |
+
c = ck["config"]
|
| 84 |
+
model = AntahkaranaWRN(c["depth"], c["width"], c["n_tasks"], c["classes_per_task"])
|
| 85 |
+
model.load_state_dict(ck["model_state"])
|
| 86 |
+
model.eval()
|
| 87 |
+
return model, ck
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
if __name__ == "__main__":
|
| 91 |
+
import sys
|
| 92 |
+
p = sys.argv[1] if len(sys.argv) > 1 else "antahkarana_cifar100_wrn28-10.pt"
|
| 93 |
+
model, ck = load(p)
|
| 94 |
+
c, r = ck["config"], ck["results"]
|
| 95 |
+
n_params = sum(t.numel() for t in model.parameters())
|
| 96 |
+
print(f"loaded {p}")
|
| 97 |
+
print(f" WRN-{c['depth']}-{c['width']} | {n_params/1e6:.1f}M params | "
|
| 98 |
+
f"{c['n_tasks']} tasks × {c['classes_per_task']} classes")
|
| 99 |
+
ag, na = r["agent"], r["naive"]
|
| 100 |
+
print(f" forgetting : naive {na['forgetting']:.3f} -> agent {ag['forgetting']:.4f}"
|
| 101 |
+
+ (f" ({r['forgetting_reduction']:.1f}x lower)" if r.get("forgetting_reduction") else ""))
|
| 102 |
+
print(f" accuracy : naive {na['avg_acc']:.3f} -> agent {ag['avg_acc']:.3f}")
|
| 103 |
+
print(f" pramāṇa : gated acc {ag['gated_accuracy']:.3f} @ coverage {ag['gated_coverage']:.2f}")
|
| 104 |
+
print(f" saṃskāra Ω/θ* present: {('omega' in ck and 'theta_star' in ck)}")
|
| 105 |
+
# tiny forward smoke
|
| 106 |
+
x = torch.randn(2, 3, 32, 32)
|
| 107 |
+
print(f" forward(x, task=0) -> logits {tuple(model(x, 0).shape)}")
|
plots/bench_forgetting.png
ADDED
|
plots/bench_mindstate.png
ADDED
|
plots/bench_pramana.png
ADDED
|
plots/bench_retention.png
ADDED
|
plots/bench_scorecard.png
ADDED
|