summaryrefslogtreecommitdiff
path: root/experiments/smoke.py
diff options
context:
space:
mode:
authorYurenHao0426 <Blackhao0426@gmail.com>2026-07-22 05:00:28 -0500
committerYurenHao0426 <Blackhao0426@gmail.com>2026-07-22 05:00:28 -0500
commit7b6cdfb9656d3b59edae442c99ba3412ecc32cfc (patch)
tree8af7c96539a510454bbc7695a8d659b6a5dc5e42 /experiments/smoke.py
parent0660bd1f6274e7982438506eec67870b105a0285 (diff)
sdil: add feedback-first apical calibration
Diffstat (limited to 'experiments/smoke.py')
-rw-r--r--experiments/smoke.py30
1 files changed, 29 insertions, 1 deletions
diff --git a/experiments/smoke.py b/experiments/smoke.py
index a49e4c6..9971800 100644
--- a/experiments/smoke.py
+++ b/experiments/smoke.py
@@ -6,7 +6,7 @@ import sys
import torch
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from sdil.core import (SDILNet, SDILConfig, sdil_step,
+from sdil.core import (SDILNet, SDILConfig, apical_calibration_step, sdil_step,
node_perturbation_targets, simultaneous_node_perturbation_targets,
neutral_p_update, teaching_signal)
from sdil.baselines import dfa_config
@@ -188,6 +188,33 @@ def check_direct_node_perturbation():
print("CHECK0f direct node perturbation: exact q update; A untouched")
+def check_feedback_first_calibration():
+ """A-only calibration must leave the entire forward network unchanged."""
+ torch.manual_seed(23)
+ x = torch.randn(32, 5)
+ y = torch.randint(0, 3, (32,))
+ yoh = onehot(y, 3)
+ net = SDILNet([5, 7, 7, 3], act="relu", device="cpu", seed=11,
+ residual=True, vectorizer_mode="context_gated")
+ weights_before = [weight.clone() for weight in net.W]
+ biases_before = [bias.clone() for bias in net.b]
+ apical_before = [weight.clone() for weight in net.A]
+ gates_before = [weight.clone() for weight in net.A_gate]
+ cfg = SDILConfig(eta_A=0.02, learn_A=True, learn_P=True,
+ pert_ndirs=1, pert_mode="simultaneous")
+ apical_calibration_step(
+ net, x, y, yoh, cfg, pert_mode="simultaneous", pert_ndirs=2)
+ assert all(torch.equal(before, after)
+ for before, after in zip(weights_before, net.W))
+ assert all(torch.equal(before, after)
+ for before, after in zip(biases_before, net.b))
+ assert any(not torch.equal(before, after)
+ for before, after in zip(apical_before, net.A))
+ assert any(not torch.equal(before, after)
+ for before, after in zip(gates_before, net.A_gate))
+ print("CHECK0g feedback-first calibration: A changed; W/readout frozen")
+
+
def main():
torch.manual_seed(0)
dev = "cpu"
@@ -197,6 +224,7 @@ def main():
check_traffic_seed_isolation()
check_state_conditioned_vectorizers()
check_direct_node_perturbation()
+ check_feedback_first_calibration()
print("loading MNIST subset...")
tr, te, n_in, n_out = get_dataset("mnist", batch_size=128, device=dev)
xb, yb = next(iter(tr))