From f058f1e792d7b2c99fbb4f555fe12c052177846b Mon Sep 17 00:00:00 2001 From: YurenHao0426 Date: Tue, 21 Jul 2026 14:25:48 -0500 Subject: figures: lock claim-critical training protocols --- experiments/plot_main_figures.py | 45 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/experiments/plot_main_figures.py b/experiments/plot_main_figures.py index 7b17b2c..9005caa 100644 --- a/experiments/plot_main_figures.py +++ b/experiments/plot_main_figures.py @@ -99,15 +99,31 @@ def require_scaling_protocol(rows): for key, expected in (("dataset", "cifar10"), ("width", 64), ("epochs", 5), ("batch_size", 128), ("act", "tanh"), ("residual", 1), - ("device", "cuda")): + ("momentum", 0.9), ("device", "cuda")): require_value(errors, row, key, args.get(key), expected) name = method(row) require_value(errors, row, "depth", args.get("depth"), args.get("depth") if args.get("depth") in DEPTHS else "one of " + repr(DEPTHS)) require_value(errors, row, "eta", args.get("eta"), 0.02 if name == "SDIL" else 0.05) + if name == "FA": + for key, expected in (("train_examples", 0), ("max_batches", 0), + ("feedback_scale", 1), + ("canonical_preprocess", 1)): + require_value(errors, row, key, args.get(key), expected) + else: + for key, expected in (("max_steps", 0), ("w_scale", 1), + ("n_in", 3072)): + require_value(errors, row, key, args.get(key), expected) if name == "SDIL": - require_value(errors, row, "pert_mode", args.get("pert_mode"), "simultaneous") - require_value(errors, row, "pert_ndirs", args.get("pert_ndirs"), 16) + for key, expected in ( + ("eta_A", 0.02), ("eta_P", 0.002), ("pert_sigma", 0.01), + ("pert_every", 4), ("pert_mode", "simultaneous"), + ("pert_ndirs", 16), ("use_residual", 1), ("learn_A", 1), + ("learn_P", 1), ("p_neutral", 1), ("p_warmup_steps", 200), + ("p_warmup_eta", 0.05), ("nuis_rho", 0), + ("predictor_mode", "diagonal"), ("normalize_delta", 0), + ("settle_steps", 0), ("kappa", 0), ("feedback", "error")): + require_value(errors, row, key, args.get(key), expected) if errors: raise RuntimeError("mixed CIFAR scaling protocols:\n" + "\n".join(errors)) @@ -131,6 +147,9 @@ def require_ep_protocol(groups): if name == "EP": require_value(errors, row, "batch_size", args.get("batch_size"), 20) require_value(errors, row, "ep_persistent", args.get("ep_persistent"), 1) + require_value(errors, row, "ep_dt", args.get("ep_dt"), 0.5) + require_value(errors, row, "canonical_preprocess", + args.get("canonical_preprocess"), 1) resolved = row.get("resolved_protocol", {}) for key in ("beta", "free_steps", "nudge_steps", "learning_rates"): require_value(errors, row, f"resolved_protocol.{key}", @@ -142,9 +161,20 @@ def require_ep_protocol(groups): require_value(errors, row, "act", args.get("act"), "tanh") require_value(errors, row, "residual", args.get("residual"), 0) require_value(errors, row, "eta", args.get("eta"), 0.05) + require_value(errors, row, "momentum", args.get("momentum"), 0.9) + require_value(errors, row, "max_steps", args.get("max_steps"), 0) if name == "SDIL": - require_value(errors, row, "pert_mode", args.get("pert_mode"), "simultaneous") - require_value(errors, row, "pert_ndirs", args.get("pert_ndirs"), 16) + for key, expected in ( + ("eta_A", 0.02), ("eta_P", 0.002), + ("pert_sigma", 0.01), ("pert_every", 4), + ("pert_mode", "simultaneous"), ("pert_ndirs", 16), + ("use_residual", 1), ("learn_A", 1), ("learn_P", 1), + ("p_neutral", 1), ("p_warmup_steps", 200), + ("p_warmup_eta", 0.05), ("nuis_rho", 0), + ("predictor_mode", "diagonal"), ("normalize_delta", 0), + ("settle_steps", 0), ("kappa", 0), + ("feedback", "error")): + require_value(errors, row, key, args.get(key), expected) if errors: raise RuntimeError("mixed exact-EP protocols:\n" + "\n".join(errors)) @@ -481,8 +511,9 @@ GTX 1080. **a,** CIFAR-10 test accuracy versus wall time for width-64 residual M five epochs. The black line is the mean-based nondominated frontier among local-learning methods. BP is a nonlocal reference and is excluded from frontier construction. Labels give hidden depth. **b,** SDIL versus canonical equilibrium propagation (EP) on exact 784–500–10 (d1) and -784–500–500–10 (d2) forward architectures, the same first 50,000 MNIST training examples, and the -same epoch counts. EP retains its published raw-pixel, hard-sigmoid energy dynamics and relaxation +784–500–500–10 (d2) forward architectures and the same first 50,000 MNIST training examples. +Within each matched architecture, every method uses the same budget: 25 epochs for d1 and 60 epochs +for d2. EP retains its published raw-pixel, hard-sigmoid energy dynamics and relaxation schedule; SDIL retains its z-scored, tanh feedforward dynamics. Thus architecture, examples, and epochs are matched, but preprocessing and state dynamics are intentionally method-native. -- cgit v1.2.3