diff options
| -rw-r--r-- | experiments/run.py | 2 | ||||
| -rw-r--r-- | experiments/smoke.py | 4 | ||||
| -rw-r--r-- | sdil/probes.py | 11 |
3 files changed, 13 insertions, 4 deletions
diff --git a/experiments/run.py b/experiments/run.py index eb9f356..3cb2e00 100644 --- a/experiments/run.py +++ b/experiments/run.py @@ -115,6 +115,7 @@ def train(args): if args.mode != "bp": al = probes.alignment_report(net, px, py, poh, cfg) rec["cos_r_negg"] = al["cos_r_negg"] + rec["cos_innovation_negg"] = al["cos_innovation_negg"] rec["cos_apical_negg"] = al["cos_apical_negg"] rec["cos_Ac_negg"] = al["cos_Ac_negg"] rec["r_norm"] = al["r_norm"] @@ -141,6 +142,7 @@ def train(args): if args.mode != "bp": al = probes.alignment_report(net, px, py, poh, cfg) log["final"]["cos_r_negg"] = al["cos_r_negg"] + log["final"]["cos_innovation_negg"] = al["cos_innovation_negg"] log["final"]["cos_apical_negg"] = al["cos_apical_negg"] log["final"]["cos_Ac_negg"] = al["cos_Ac_negg"] os.makedirs(args.outdir, exist_ok=True) diff --git a/experiments/smoke.py b/experiments/smoke.py index f440f7f..575f0bd 100644 --- a/experiments/smoke.py +++ b/experiments/smoke.py @@ -159,6 +159,10 @@ def main(): print(f" raw apical cos(a,-g) = {apical_cos:+.3f}") print(f" pure A c cos(Ac,-g) = {sum(al_n['cos_Ac_negg'])/len(al_n['cos_Ac_negg']):+.3f}") assert residual_cos > apical_cos + 0.1 + cfg_raw = SDILConfig(use_residual=False, learn_A=False, learn_P=True) + al_raw = probes.alignment_report(net_n, x, y, yoh, cfg_raw) + assert al_raw["cos_r_negg"] == al_raw["cos_apical_negg"], ( + "reported teaching alignment must honor use_residual=False") # ---- CHECK 5: single-step loss-decrease ratio vs exact GD ---- print("\nCHECK5 single-step loss-decrease ratio vs exact GD:") diff --git a/sdil/probes.py b/sdil/probes.py index b58fe89..16aca21 100644 --- a/sdil/probes.py +++ b/sdil/probes.py @@ -55,21 +55,24 @@ def alignment_report(net, x, y, y_onehot, cfg): e = net.output_error(logits, y_onehot) c = e - out = {"cos_r_negg": [], "cos_apical_negg": [], "cos_Ac_negg": [], + out = {"cos_r_negg": [], "cos_innovation_negg": [], + "cos_apical_negg": [], "cos_Ac_negg": [], "r_norm": [], "g_norm": [], "loss": loss} for l in range(net.L - 1): g = grads[l] negg = -g a = net.apical(l, c, h[l + 1]) # raw apical (with nuisance) Ac = c @ net.A[l].t() # pure vectorizer output - r = a - net.baseline(l, h[l + 1]) # innovation + innovation = a - net.baseline(l, h[l + 1]) + teaching = innovation if cfg.use_residual else a # include the phi' gain that the plasticity rule actually applies, # so the reported alignment is what the weight update "sees" gain = net.act_prime(u[l]) - out["cos_r_negg"].append(_row_cos(r * gain, negg * gain)) + out["cos_r_negg"].append(_row_cos(teaching * gain, negg * gain)) + out["cos_innovation_negg"].append(_row_cos(innovation * gain, negg * gain)) out["cos_apical_negg"].append(_row_cos(a * gain, negg * gain)) out["cos_Ac_negg"].append(_row_cos(Ac * gain, negg * gain)) - out["r_norm"].append(r.norm(dim=1).mean().item()) + out["r_norm"].append(teaching.norm(dim=1).mean().item()) out["g_norm"].append(g.norm(dim=1).mean().item()) return out |
