summaryrefslogtreecommitdiff
path: root/experiments
diff options
context:
space:
mode:
authorYurenHao0426 <Blackhao0426@gmail.com>2026-07-22 17:01:10 -0500
committerYurenHao0426 <Blackhao0426@gmail.com>2026-07-22 17:01:10 -0500
commiteeb50b079dc2831947b09b174877fe454eaf387c (patch)
treef971fc6a18c9bd2fa8b0a75102070ffc77fb8f2f /experiments
parent380a2a5e56c8edaecb2e0cc1a0bfc592e5b0f72c (diff)
experiment: add dynamic neutral residual projection
Diffstat (limited to 'experiments')
-rw-r--r--experiments/conv_local_smoke.py33
-rw-r--r--experiments/diagnose_kp_traffic_nonfinite.py10
2 files changed, 41 insertions, 2 deletions
diff --git a/experiments/conv_local_smoke.py b/experiments/conv_local_smoke.py
index dbae759..cdf1ad0 100644
--- a/experiments/conv_local_smoke.py
+++ b/experiments/conv_local_smoke.py
@@ -1003,6 +1003,26 @@ def kp_mixed_traffic_checks():
assert stable_fit["min_residual_soma_slope"] < -9e-4
assert stable_fit["max_applied_stability_margin"] >= 1e-3
+ # A deliberately inaccurate slow predictor leaves an affine neutral mode.
+ # The fast controller must remove that mode using only paired neutral
+ # soma/traffic observations, without changing the predictor parameters or
+ # reading the task instruction during its coefficient fit.
+ frozen_before_projection = [value.clone() for value in
+ net.P_traffic + net.P_traffic_bias]
+ projected = net.mixed_apical_components(
+ instruction, forward["hiddens"], "innovation",
+ neutral_projection=True)
+ projection = projected["neutral_projection"]
+ projected_instruction_error = max(float((left - right).abs().max())
+ for left, right in zip(
+ projected["innovation"], instruction))
+ assert projected_instruction_error < 1e-14
+ assert projection["post_projection_traffic_rms_ratio"] < 1e-14
+ assert projection["max_absolute_post_projection_soma_slope"] < 1e-14
+ assert projection["instruction_observations"] == 0
+ assert all(torch.equal(before, after) for before, after in zip(
+ frozen_before_projection, net.P_traffic + net.P_traffic_bias))
+
for slope, bias in zip(net.P_traffic, net.P_traffic_bias):
slope.zero_()
bias.zero_()
@@ -1098,6 +1118,14 @@ def kp_mixed_traffic_checks():
assert all(not value.requires_grad for value in
net.W + net.Q + net.P_traffic + net.P_traffic_bias
+ [net.W_out, net.R_out, net.b_out])
+ projected_result = conv_kp_mixed_traffic_step(
+ net, x, y, ConvSDILConfig(
+ eta=1e-4, eta_output=1e-4, eta_P=0.1, momentum=0.0,
+ weight_decay=0.0, learn_A=False, learn_P=True),
+ step=2, rule="innovation", predictor_every=0,
+ neutral_projection=True)
+ assert math.isfinite(projected_result["loss"])
+ assert projected_result["neutral_projection"] is not None
assert net.mixed_elementwise_ops_per_example("matched") > (
net.mixed_elementwise_ops_per_example("raw"))
return {
@@ -1109,6 +1137,11 @@ def kp_mixed_traffic_checks():
"residual_traffic_rms_ratio"],
"kp_traffic_closed_form_residual_slope": closed_form[
"max_absolute_residual_soma_slope"],
+ "kp_traffic_projected_instruction_error": projected_instruction_error,
+ "kp_traffic_projected_residual_ratio": projection[
+ "post_projection_traffic_rms_ratio"],
+ "kp_traffic_projected_residual_slope": projection[
+ "max_absolute_post_projection_soma_slope"],
"kp_traffic_matched_norm_error": max(norm_errors),
"kp_traffic_matched_direction_error": max(direction_errors),
"kp_traffic_reciprocal_correlation_error": max(correlation_errors),
diff --git a/experiments/diagnose_kp_traffic_nonfinite.py b/experiments/diagnose_kp_traffic_nonfinite.py
index 7b7389f..d438e01 100644
--- a/experiments/diagnose_kp_traffic_nonfinite.py
+++ b/experiments/diagnose_kp_traffic_nonfinite.py
@@ -91,6 +91,7 @@ def main():
default="nlms20")
parser.add_argument("--predictor_every", type=int, default=16)
parser.add_argument("--stability_margin", type=float, default=0.0)
+ parser.add_argument("--neutral_projection", action="store_true")
parser.add_argument("--device", default="cuda")
parser.add_argument("--max_steps", type=int, default=352)
parser.add_argument("--out", required=True)
@@ -176,7 +177,8 @@ def main():
break
result = conv_kp_mixed_traffic_step(
net, x, y, config, step, args.rule,
- predictor_every=args.predictor_every)
+ predictor_every=args.predictor_every,
+ neutral_projection=args.neutral_projection)
state = network_state(net)
bad = nonfinite_groups(state)
for name, indices in bad.items():
@@ -210,6 +212,7 @@ def main():
"traffic_rms": result["traffic_rms"],
"predictor_updated": result["did_predictor_update"],
"predictor_mse": result["predictor_mse"],
+ "neutral_projection": result["neutral_projection"],
"parameter_state": state,
})
if active_bad or active_metric_names:
@@ -226,13 +229,16 @@ def main():
if row["predictor_mse"] is not None:
numeric.append(float(row["predictor_mse"]))
output = {
- "protocol": "kp_mixed_traffic_nonfinite_diagnosis_v1",
+ "protocol": ("kp_dynamic_neutral_projection_diagnosis_v1"
+ if args.neutral_projection
+ else "kp_mixed_traffic_nonfinite_diagnosis_v1"),
"scope": "training_only_no_validation_or_test_evaluation",
"provenance": provenance(),
"rule": args.rule,
"predictor_mode": args.predictor_mode,
"predictor_every": args.predictor_every,
"stability_margin": args.stability_margin,
+ "neutral_projection": args.neutral_projection,
"max_steps": args.max_steps,
"split": split,
"traffic_calibration": calibration,