Skip to content

Commit 1458c99

Browse files
Add ECS probe-loss TraceWall optimizer
1 parent a23f2f3 commit 1458c99

27 files changed

Lines changed: 3444 additions & 0 deletions
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: ECS probe-loss TraceWall tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- "agent/**"
8+
paths:
9+
- "optimizers/ecs_probe_loss_trace_wall/**"
10+
- ".github/workflows/ecs-probe-loss-trace-wall-tests.yml"
11+
pull_request:
12+
branches:
13+
- main
14+
paths:
15+
- "optimizers/ecs_probe_loss_trace_wall/**"
16+
- ".github/workflows/ecs-probe-loss-trace-wall-tests.yml"
17+
workflow_dispatch:
18+
19+
permissions:
20+
contents: read
21+
22+
concurrency:
23+
group: ecs-probe-loss-trace-wall-${{ github.workflow }}-${{ github.ref }}
24+
cancel-in-progress: true
25+
26+
jobs:
27+
unit-and-smoke-tests:
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 20
30+
steps:
31+
- name: Check out repository
32+
uses: actions/checkout@v4
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: "3.11"
38+
cache: pip
39+
cache-dependency-path: optimizers/ecs_probe_loss_trace_wall/pyproject.toml
40+
41+
- name: Install CPU PyTorch and test dependencies
42+
run: |
43+
python -m pip install --upgrade pip
44+
python -m pip install --index-url https://download.pytorch.org/whl/cpu torch torchvision
45+
python -m pip install numpy pandas scipy matplotlib nbformat
46+
python -m pip install --no-deps -e optimizers/ecs_probe_loss_trace_wall
47+
48+
- name: Compile package and run tests
49+
run: |
50+
python -m compileall -q \
51+
optimizers/ecs_probe_loss_trace_wall/ecs_trace_wall \
52+
optimizers/ecs_probe_loss_trace_wall/tests
53+
PYTHONPATH=optimizers/ecs_probe_loss_trace_wall \
54+
python -m unittest discover \
55+
-s optimizers/ecs_probe_loss_trace_wall/tests -v

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,15 @@ every training epoch. Plots use a fixed color-blind-safe palette and two-sided
4444
displacement aligned with that vector. Its matched MNIST suite tests the
4545
same projector on AdamW, Adam, and ordinary SGD with classical momentum.
4646

47+
- [`optimizers/ecs_probe_loss_trace_wall`](optimizers/ecs_probe_loss_trace_wall):
48+
a task-directed TraceWall variant. At each correction it recomputes the
49+
self-consistent ECS, truncates all selected matrices to that support, measures
50+
cross-entropy on a rotating random subset of the training set, projects the
51+
probe gradient back into the ECS, and adds a line-searched loss-decreasing
52+
component to the completed AdamW or SGD-momentum update. Its paired notebooks
53+
include a clean baseline in the same run, matched warmup/cosine schedules,
54+
three-seed error bars, WeightWatcher diagnostics, and complete checkpoints.
55+
The official test set is used only for evaluation, never for optimization.
56+
4757
Each optimizer is kept in its own folder so implementations, notebooks, and
4858
tests can evolve independently.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
__pycache__/
2+
*.py[cod]
3+
.ipynb_checkpoints/
4+
data/
5+
runs/
6+
.pytest_cache/
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# ECS Probe-Loss TraceWall
2+
3+
This folder contains an independent optimizer experiment for the standard
4+
MNIST MLP3 model. It does **not** modify the existing trace-log, adaptive
5+
spectral guard, spectral-flow projector, or local-delta WW-PGD implementations.
6+
7+
The method replaces the previous objective of suppressing flow toward a
8+
putative trivial fixed point with a directly testable task objective measured
9+
on a rotating subset of the **training** data.
10+
11+
## Definition
12+
13+
For every selected matrix after a completed base-optimizer step, compute
14+
15+
\[
16+
W = U\Sigma V^\top,
17+
\qquad
18+
W_{\mathrm{ECS}} = U_m\Sigma_m V_m^\top,
19+
\]
20+
21+
where the retained rank \(m\) is the current bulk-effective,
22+
self-consistent trace-log ECS. All selected matrices are truncated
23+
simultaneously. On a rotating training probe subset \(B_t\), the optimizer
24+
measures
25+
26+
\[
27+
\mathcal L_{\mathrm{probe}}(t)
28+
=
29+
\frac{1}{|B_t|}
30+
\sum_{(x,y)\in B_t}
31+
\ell\!\left(f_{W_{\mathrm{ECS}}}(x),y\right).
32+
\]
33+
34+
It differentiates this loss at the truncated model, projects each matrix
35+
gradient into the same retained singular subspaces,
36+
37+
\[
38+
G_{\mathrm{ECS}}
39+
=
40+
(U_mU_m^\top)\,G\,(V_mV_m^\top),
41+
\]
42+
43+
and proposes a negative-gradient component. The completed update is
44+
45+
\[
46+
W_{t+1}
47+
=
48+
W^{\mathrm{base}}_{t+1}
49+
+
50+
a_t\,\Delta W_{\mathrm{probe,ECS}},
51+
\]
52+
53+
where \(a_t\) is selected by Armijo backtracking on the same ECS-truncated
54+
probe objective. A correction is committed only when it lowers that objective.
55+
The ECS SVD and rank are recomputed at every correction, so the task-loss
56+
channel follows the ECS if its support contracts or expands during training.
57+
58+
The default projection is the strict ECS core shown above. A rank-\(m\)
59+
manifold tangent projection is available as an explicit ablation.
60+
61+
## Rotating probe protocol
62+
63+
- The probe is drawn only from the MNIST training set.
64+
- The official MNIST test set is used only for reporting test loss and accuracy.
65+
- Probe selection uses an independent seeded random permutation.
66+
- New slices are consumed without replacement; after a complete pass, a new
67+
permutation is generated.
68+
- A draw that crosses a permutation boundary is still unique within that draw.
69+
- The primary notebooks use 512 examples per correction (two batches of 256)
70+
and one correction at each epoch boundary.
71+
72+
This avoids tuning directly on the official test set while approximating the
73+
expected loss of a changing random training probe.
74+
75+
## Paired experiment
76+
77+
Both notebooks train a clean baseline and a TraceWall arm in the same run.
78+
For every seed, the two arms:
79+
80+
- start from byte-identical weights;
81+
- receive the same minibatches in the same order;
82+
- use the same gradient clipping;
83+
- use the same optimizer hyperparameters;
84+
- use the same one-epoch linear warmup and cosine decay to 5% of the peak
85+
learning rate.
86+
87+
Only the TraceWall arm receives the post-step ECS probe-loss component.
88+
89+
Repository-standard peak settings are retained:
90+
91+
- AdamW: learning rate `1e-3`, betas `(0.9, 0.999)`, epsilon `1e-8`, weight
92+
decay `1e-2`;
93+
- SGD with classical momentum: learning rate `5e-2`, momentum `0.9`, zero
94+
dampening, no Nesterov, weight decay `1e-4`.
95+
96+
The MLP is `784 -> 512 -> 512 -> 10` with ReLU activations and no dropout or
97+
batch normalization. Each notebook runs three independent seeds for 20 epochs
98+
and reports two-sided 95% Student-t confidence intervals across complete runs.
99+
100+
## Notebooks
101+
102+
- `notebooks/MNIST_MLP3_AdamW_vs_ECS_Probe_Loss_TraceWall.ipynb`
103+
- `notebooks/MNIST_MLP3_SGD_Momentum_vs_ECS_Probe_Loss_TraceWall.ipynb`
104+
105+
Each notebook records and saves:
106+
107+
- full train/test cross-entropy, accuracy, and classification perplexity;
108+
- learning rate, parameter norm, and epoch timing;
109+
- self-consistent ECS rank, trace-log residual, adaptive normalization,
110+
retained energy, stable rank, and participation ratio;
111+
- WeightWatcher alpha, `detX_num`, `num_pl_spikes`, and `ERG_gap`;
112+
- every probe loss before/after correction;
113+
- line-search scale, acceptance, correction norms, ECS ranks, and numerical
114+
projection audits;
115+
- baseline and TraceWall checkpoints after every epoch.
116+
117+
By default outputs are written beneath `runs/`. Set
118+
`RG_TRACE_WALL_RUN_ROOT` and `RG_TRACE_WALL_DATA_DIR` to redirect experiment
119+
artifacts and the MNIST cache.
120+
121+
## Tests
122+
123+
From this folder:
124+
125+
```bash
126+
python -m unittest discover -s tests -v
127+
```
128+
129+
The tests cover scale-invariant ECS selection, SVD truncation, ECS projection,
130+
rotating-probe uniqueness and checkpoint restoration, optimizer loss descent,
131+
warmup/cosine scheduling, a paired synthetic end-to-end run, plotting, and
132+
notebook validity.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""ECS probe-loss TraceWall optimizer experiments."""
2+
3+
from .config import BaseOptimizerConfig, ExperimentConfig, TraceWallConfig
4+
from .ecs import (
5+
ECSSelection,
6+
ECSSVDState,
7+
compute_ecs_svd,
8+
participation_ratio,
9+
project_gradient_to_ecs,
10+
select_self_consistent_ecs,
11+
)
12+
from .experiment import (
13+
MLP3,
14+
PairedExperimentResult,
15+
WarmupCosineSchedule,
16+
build_base_optimizer,
17+
choose_device,
18+
evaluate,
19+
load_mnist,
20+
run_paired_experiment,
21+
set_seed,
22+
state_dict_checksum,
23+
)
24+
from .optimizer import (
25+
CorrectionRecord,
26+
ECSProbeLossTraceWall,
27+
LayerCorrectionRecord,
28+
)
29+
from .plotting import plot_all
30+
from .sampler import ProbeDraw, RotatingSubsetSampler, materialize_probe_batches
31+
32+
__all__ = [
33+
"BaseOptimizerConfig",
34+
"CorrectionRecord",
35+
"ECSProbeLossTraceWall",
36+
"ECSSelection",
37+
"ECSSVDState",
38+
"ExperimentConfig",
39+
"LayerCorrectionRecord",
40+
"MLP3",
41+
"PairedExperimentResult",
42+
"ProbeDraw",
43+
"RotatingSubsetSampler",
44+
"TraceWallConfig",
45+
"WarmupCosineSchedule",
46+
"build_base_optimizer",
47+
"choose_device",
48+
"compute_ecs_svd",
49+
"evaluate",
50+
"load_mnist",
51+
"materialize_probe_batches",
52+
"participation_ratio",
53+
"plot_all",
54+
"project_gradient_to_ecs",
55+
"run_paired_experiment",
56+
"select_self_consistent_ecs",
57+
"set_seed",
58+
"state_dict_checksum",
59+
]
60+
61+
__version__ = "0.1.0"

0 commit comments

Comments
 (0)