summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYurenHao0426 <Blackhao0426@gmail.com>2026-07-27 14:51:17 -0500
committerYurenHao0426 <Blackhao0426@gmail.com>2026-07-27 14:51:17 -0500
commita5a04b29bc93bdee4dbce6fa46bfda7cfe843928 (patch)
tree6cfabf8daa2fbbf4bdb786c0a604ddf9729c7da1
parenta2df73afd68278bbc961a49bbc722d17b4d83ef0 (diff)
figure: audit standard-depth SDIL scaling
-rwxr-xr-xexperiments/finalize_accept.sh24
-rw-r--r--experiments/plot_oral_a_scaling.py654
-rw-r--r--results/figs/figure6_standard_depth_scaling.pdfbin0 -> 38102 bytes
-rw-r--r--results/figs/figure6_standard_depth_scaling.pngbin0 -> 553126 bytes
-rw-r--r--results/figs/figure6_standard_depth_scaling_caption.md18
-rw-r--r--results/figs/figure6_standard_depth_scaling_manifest.json346
6 files changed, 1042 insertions, 0 deletions
diff --git a/experiments/finalize_accept.sh b/experiments/finalize_accept.sh
index db3f9bd..c50545f 100755
--- a/experiments/finalize_accept.sh
+++ b/experiments/finalize_accept.sh
@@ -36,7 +36,10 @@ experiments/finalize_claims.sh
experiments/analyze_bci_v2_calibrated_confirmation.py \
experiments/oral_a_dynamic_scaling.py \
experiments/analyze_oral_a_dynamic_scaling.py \
+ experiments/oral_a_dynamic_scaling_v2.py \
+ experiments/analyze_oral_a_dynamic_scaling_v2.py \
experiments/plot_resnet_confirmation.py \
+ experiments/plot_oral_a_scaling.py \
experiments/plot_bci_v2_confirmation.py \
experiments/audit_manuscript.py
/home/yurenh2/miniconda3/envs/ep_pascal/bin/python3 \
@@ -108,6 +111,27 @@ if [ -f results/oral_a_dynamic_scaling_gate.json ]; then
/home/yurenh2/miniconda3/envs/ep_pascal/bin/python3 \
experiments/analyze_oral_a_dynamic_scaling.py >/dev/null
fi
+if [ -f results/oral_a_dynamic_scaling_v2_gate.json ]; then
+ /home/yurenh2/miniconda3/envs/ep_pascal/bin/python3 \
+ experiments/analyze_oral_a_dynamic_scaling_v2.py >/dev/null
+ /home/yurenh2/miniconda3/bin/python \
+ experiments/plot_oral_a_scaling.py >/dev/null
+ jq -e '
+ .strict == true and
+ .gate_status == "passed" and
+ .complete_grid == true and
+ .required_methods == ["bp", "dfa", "clean_kp", "dynamic"] and
+ .required_depths == [20, 32, 56] and
+ .required_seeds == [10, 11, 12, 13, 14] and
+ .record_count == 60 and
+ .statistics.dynamic_d20_to_d56_gain_points_mean >= 0.5 and
+ (.statistics.dynamic_d20_to_d56_gain_points | map(select(. > 0)) | length) == 5 and
+ (.statistics.dynamic_early_alignment_mean | [.[]] | min) >= 0.999 and
+ (.statistics.dynamic_mac_ratio_to_bp_mean | [.[]] | max) <= 1.34 and
+ .statistics.dynamic_logical_task_loss_queries == [0] and
+ .statistics.dynamic_neutral_observations_per_ordinary_example == [1]
+ ' results/figs/figure6_standard_depth_scaling_manifest.json >/dev/null
+fi
/home/yurenh2/miniconda3/bin/python \
experiments/plot_tracking_failure.py >/dev/null
/home/yurenh2/miniconda3/bin/python \
diff --git a/experiments/plot_oral_a_scaling.py b/experiments/plot_oral_a_scaling.py
new file mode 100644
index 0000000..a7ce6f5
--- /dev/null
+++ b/experiments/plot_oral_a_scaling.py
@@ -0,0 +1,654 @@
+#!/usr/bin/env python3
+"""Render the audited standard-depth ResNet scaling figure.
+
+The renderer reads all 60 frozen records directly, applies the original record
+validator, verifies every source hash against the passed gate, and refuses an
+incomplete panel or disagreement between raw records and gate statistics.
+"""
+import argparse
+import glob
+import hashlib
+import json
+import math
+import os
+import statistics
+
+import matplotlib
+
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import numpy as np
+
+from analyze_oral_a_dynamic_scaling import (
+ DEPTHS,
+ METHODS,
+ SEEDS,
+ validate_record,
+)
+
+
+PROTOCOL = "oral_a_dynamic_innovation_scaling_recovery_v2"
+BLUE = "#0072B2"
+LIGHT_BLUE = "#56B4E9"
+GREEN = "#009E73"
+ORANGE = "#D55E00"
+GRAY = "#4D4D4D"
+LIGHT_GRAY = "#B7B7B7"
+PDF_METADATA = {
+ "Creator": "SDIL audited standard-depth figure pipeline",
+ "Producer": "Matplotlib",
+ "CreationDate": None,
+ "ModDate": None,
+}
+
+
+def load_json(path):
+ with open(path) as handle:
+ return json.load(handle)
+
+
+def sha256(path):
+ digest = hashlib.sha256()
+ with open(path, "rb") as handle:
+ for chunk in iter(lambda: handle.read(1024 * 1024), b""):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def require(condition, message):
+ if not condition:
+ raise RuntimeError(message)
+
+
+def expected_paths(d4_dir, new_dir):
+ paths = {}
+ for depth in DEPTHS:
+ for seed in SEEDS:
+ for method in METHODS:
+ if depth == 20 and method in ("clean_kp", "dynamic"):
+ label = "clean_kp" if method == "clean_kp" else "dynamic"
+ path = os.path.join(d4_dir, f"seed{seed}_{label}.json")
+ else:
+ path = os.path.join(
+ new_dir, f"{method}_d{depth}_s{seed}.json"
+ )
+ paths[(method, depth, seed)] = path
+ return paths
+
+
+def require_exact_directories(d4_dir, new_dir):
+ expected_d4 = {
+ f"seed{seed}_{condition}.json"
+ for seed in SEEDS
+ for condition in ("clean_kp", "dynamic")
+ }
+ expected_new = {
+ f"{method}_d{depth}_s{seed}.json"
+ for depth in DEPTHS
+ for seed in SEEDS
+ for method in METHODS
+ if not (depth == 20 and method in ("clean_kp", "dynamic"))
+ }
+ observed_d4 = {
+ os.path.basename(path)
+ for path in glob.glob(os.path.join(d4_dir, "*.json"))
+ }
+ observed_new = {
+ os.path.basename(path)
+ for path in glob.glob(os.path.join(new_dir, "*.json"))
+ }
+ require(observed_d4 == expected_d4, "D4 source directory drift")
+ require(observed_new == expected_new, "standard-depth source directory drift")
+
+
+def load_panel(d4_dir, new_dir, gate_path):
+ gate = load_json(gate_path)
+ require(gate.get("protocol") == PROTOCOL, "standard-depth protocol drift")
+ require(gate.get("status") == "passed", "standard-depth gate is not passed")
+ require(gate.get("complete_grid") is True, "standard-depth grid incomplete")
+ require(
+ gate.get("standard_depth_scaling_established") is True,
+ "standard-depth claim was not established",
+ )
+ require(gate.get("review_score_after") == 9, "score-change rule drift")
+ require(
+ gate.get("checks") and all(gate["checks"].values()),
+ "standard-depth gate contains a failed check",
+ )
+ require_exact_directories(d4_dir, new_dir)
+
+ records = {}
+ rows = {}
+ paths = expected_paths(d4_dir, new_dir)
+ require(len(paths) == 60, "standard-depth panel must contain 60 cells")
+ for key, path in paths.items():
+ method, depth, seed = key
+ require(os.path.isfile(path), f"missing standard-depth record: {path}")
+ gate_digest = gate.get("source_sha256", {}).get(path)
+ require(gate_digest is not None, f"gate omits source hash: {path}")
+ require(sha256(path) == gate_digest, f"source hash drift: {path}")
+ record = load_json(path)
+ records[key] = record
+ rows[key] = validate_record(record, path, method, depth, seed)
+
+ metrics = gate["metrics"]
+ for method in METHODS:
+ for depth in DEPTHS:
+ observed = [
+ rows[(method, depth, seed)]["accuracy"] for seed in SEEDS
+ ]
+ expected = metrics["accuracy_by_method_depth_seed"][method][str(depth)]
+ require(
+ np.allclose(observed, expected, rtol=0.0, atol=0.0),
+ f"{method} depth-{depth} accuracy summary drift",
+ )
+ require(
+ math.isclose(
+ statistics.mean(observed),
+ metrics["mean_accuracy"][method][str(depth)],
+ rel_tol=0.0,
+ abs_tol=1e-15,
+ ),
+ f"{method} depth-{depth} mean summary drift",
+ )
+ observed_alignment = {
+ str(depth): [
+ rows[("dynamic", depth, seed)]["early_alignment"] for seed in SEEDS
+ ]
+ for depth in DEPTHS
+ }
+ for depth in DEPTHS:
+ require(
+ np.allclose(
+ observed_alignment[str(depth)],
+ metrics["dynamic_alignment"][str(depth)],
+ rtol=0.0,
+ atol=0.0,
+ ),
+ f"depth-{depth} alignment summary drift",
+ )
+ return gate, records, rows, paths
+
+
+def style_axis(axis):
+ axis.spines["top"].set_visible(False)
+ axis.spines["right"].set_visible(False)
+ axis.tick_params(width=1.0, length=4)
+ axis.grid(axis="y", color="#E7E7E7", linewidth=0.8, zorder=0)
+
+
+def panel_label(axis, label):
+ axis.text(
+ -0.13,
+ 1.08,
+ label,
+ transform=axis.transAxes,
+ fontsize=14.5,
+ fontweight="bold",
+ va="top",
+ )
+
+
+def accuracy_array(rows, method):
+ return np.asarray(
+ [
+ [rows[(method, depth, seed)]["accuracy"] * 100 for depth in DEPTHS]
+ for seed in SEEDS
+ ],
+ dtype=float,
+ )
+
+
+def mean_ci(values):
+ mean = values.mean(axis=0)
+ ci = 1.96 * values.std(axis=0, ddof=1) / math.sqrt(values.shape[0])
+ return mean, ci
+
+
+def plot_near_bp(axis, rows):
+ x = np.arange(len(DEPTHS))
+ specs = (
+ ("bp", "Backprop", GRAY, "o", (0, (3, 2))),
+ ("clean_kp", "Clean reciprocal", GREEN, "s", (0, (5, 2))),
+ ("dynamic", "SDIL + 4× traffic", BLUE, "D", "-"),
+ )
+ for method, label, color, marker, linestyle in specs:
+ values = accuracy_array(rows, method)
+ for seed_values in values:
+ axis.plot(x, seed_values, color=color, linewidth=0.65, alpha=0.12)
+ mean, ci = mean_ci(values)
+ axis.errorbar(
+ x,
+ mean,
+ yerr=ci,
+ color=color,
+ marker=marker,
+ markersize=5.5,
+ linewidth=2.0,
+ linestyle=linestyle,
+ capsize=3,
+ label=label,
+ zorder=3,
+ )
+ dynamic = accuracy_array(rows, "dynamic")
+ gain = (dynamic[:, -1] - dynamic[:, 0]).mean()
+ axis.text(
+ 0.045,
+ 0.08,
+ f"SDIL depth gain = {gain:+.3f} points\n"
+ "all 5 paired seeds improve",
+ transform=axis.transAxes,
+ fontsize=8.6,
+ color=BLUE,
+ bbox={
+ "boxstyle": "round,pad=0.34",
+ "facecolor": "white",
+ "edgecolor": "#D6D6D6",
+ },
+ )
+ axis.set_xticks(x, [f"ResNet-{depth}" for depth in DEPTHS])
+ axis.set_ylim(90.4, 94.0)
+ axis.set_ylabel("CIFAR-10 test accuracy (%)")
+ axis.set_title(
+ "Useful depth without a BP gap",
+ loc="left",
+ fontsize=11.3,
+ fontweight="bold",
+ pad=10,
+ )
+ axis.legend(frameon=False, fontsize=8.1, loc="upper left", ncol=1)
+ style_axis(axis)
+ panel_label(axis, "a")
+
+
+def plot_local_contrast(axis, rows):
+ x = np.arange(len(DEPTHS))
+ specs = (
+ ("dfa", "Fixed DFA", ORANGE, "o"),
+ ("clean_kp", "Clean reciprocal", GREEN, "s"),
+ ("dynamic", "SDIL + 4× traffic", BLUE, "D"),
+ )
+ for method, label, color, marker in specs:
+ values = accuracy_array(rows, method)
+ mean, ci = mean_ci(values)
+ axis.errorbar(
+ x,
+ mean,
+ yerr=ci,
+ color=color,
+ marker=marker,
+ markersize=5.5,
+ linewidth=2.0,
+ capsize=3,
+ label=label,
+ zorder=3,
+ )
+ dynamic = accuracy_array(rows, "dynamic")
+ dfa = accuracy_array(rows, "dfa")
+ advantages = (dynamic - dfa).mean(axis=0)
+ axis.text(
+ 0.05,
+ 0.08,
+ "SDIL − DFA:\n"
+ + " / ".join(f"{value:+.1f}" for value in advantages)
+ + " points",
+ transform=axis.transAxes,
+ fontsize=8.6,
+ bbox={
+ "boxstyle": "round,pad=0.34",
+ "facecolor": "white",
+ "edgecolor": "#D6D6D6",
+ },
+ )
+ axis.set_xticks(x, [f"R{depth}" for depth in DEPTHS])
+ axis.set_ylim(25, 96)
+ axis.set_ylabel("CIFAR-10 test accuracy (%)")
+ axis.set_title(
+ "Local-learning contrast",
+ loc="left",
+ fontsize=11.3,
+ fontweight="bold",
+ pad=10,
+ )
+ axis.legend(frameon=False, fontsize=8.1, loc="center right")
+ style_axis(axis)
+ panel_label(axis, "b")
+
+
+def plot_paired_gain(axis, rows):
+ methods = ("bp", "dynamic")
+ labels = ("Backprop", "SDIL + 4× traffic")
+ colors = (GRAY, BLUE)
+ markers = ("o", "D")
+ gains = []
+ for method in methods:
+ values = accuracy_array(rows, method)
+ gains.append(values[:, -1] - values[:, 0])
+ for index, values in enumerate(gains):
+ jitter = np.linspace(-0.055, 0.055, len(SEEDS))
+ axis.scatter(
+ np.full(len(SEEDS), index) + jitter,
+ values,
+ color=colors[index],
+ marker=markers[index],
+ s=34,
+ alpha=0.72,
+ edgecolor="white",
+ linewidth=0.6,
+ zorder=3,
+ )
+ mean = values.mean()
+ ci = 1.96 * values.std(ddof=1) / math.sqrt(len(values))
+ axis.errorbar(
+ [index],
+ [mean],
+ yerr=[ci],
+ color="#111111",
+ marker=markers[index],
+ markerfacecolor=colors[index],
+ markersize=7,
+ capsize=4,
+ linewidth=1.5,
+ zorder=5,
+ )
+ axis.text(
+ index,
+ mean + ci + 0.11,
+ f"{mean:+.3f}",
+ ha="center",
+ va="bottom",
+ fontsize=8.5,
+ color=colors[index],
+ )
+ axis.axhline(0, color="#7A7A7A", linewidth=0.9, linestyle="--")
+ axis.set_xlim(-0.45, 1.45)
+ axis.set_ylim(-0.1, 1.85)
+ axis.set_xticks(np.arange(2), labels)
+ axis.set_ylabel("ResNet-56 − ResNet-20\naccuracy (points)")
+ axis.set_title(
+ "Paired added-depth benefit",
+ loc="left",
+ fontsize=11.3,
+ fontweight="bold",
+ pad=10,
+ )
+ axis.text(
+ 0.04,
+ 0.08,
+ "Each point is one untouched seed.\n"
+ "Every SDIL and BP pair is positive.",
+ transform=axis.transAxes,
+ fontsize=8.6,
+ )
+ style_axis(axis)
+ panel_label(axis, "c")
+
+
+def plot_alignment_cost(axis, rows):
+ x = np.arange(len(DEPTHS))
+ alignment = np.asarray(
+ [
+ [rows[("dynamic", depth, seed)]["early_alignment"] for depth in DEPTHS]
+ for seed in SEEDS
+ ],
+ dtype=float,
+ )
+ mean, ci = mean_ci(alignment)
+ alignment_handle = axis.errorbar(
+ x,
+ mean,
+ yerr=ci,
+ color=BLUE,
+ marker="D",
+ markersize=5.5,
+ linewidth=2.0,
+ capsize=3,
+ label="Early-third alignment",
+ zorder=3,
+ )
+ axis.set_xticks(x, [f"R{depth}" for depth in DEPTHS])
+ axis.set_ylim(0.9992, 0.99982)
+ axis.set_ylabel(
+ r"$\cos(\mathrm{signal},-\nabla_h\mathcal{L})$",
+ color=BLUE,
+ )
+ axis.tick_params(axis="y", colors=BLUE)
+ axis.spines["left"].set_color(BLUE)
+
+ bp_macs = np.asarray(
+ [
+ [rows[("bp", depth, seed)]["total_macs"] for depth in DEPTHS]
+ for seed in SEEDS
+ ],
+ dtype=float,
+ )
+ dynamic_macs = np.asarray(
+ [
+ [rows[("dynamic", depth, seed)]["total_macs"] for depth in DEPTHS]
+ for seed in SEEDS
+ ],
+ dtype=float,
+ )
+ mac_ratio = dynamic_macs / bp_macs
+ cost_axis = axis.twinx()
+ cost_mean, _ = mean_ci(mac_ratio)
+ cost_handle = cost_axis.plot(
+ x,
+ cost_mean,
+ color=GREEN,
+ marker="s",
+ markersize=5,
+ linewidth=1.8,
+ linestyle=(0, (5, 2)),
+ label="MAC estimate / BP",
+ )[0]
+ cost_axis.set_ylim(1.29, 1.345)
+ cost_axis.set_ylabel("SDIL MAC estimate / BP", color=GREEN)
+ cost_axis.tick_params(axis="y", colors=GREEN)
+ cost_axis.spines["top"].set_visible(False)
+ cost_axis.spines["right"].set_color(GREEN)
+ cost_axis.grid(False)
+
+ axis.legend(
+ [alignment_handle, cost_handle],
+ ["Early-third alignment", "MAC estimate / BP"],
+ frameon=False,
+ fontsize=8.1,
+ loc="lower left",
+ )
+ axis.text(
+ 0.04,
+ 0.93,
+ "0 task-loss queries\n1 neutral observation / example",
+ transform=axis.transAxes,
+ fontsize=8.5,
+ va="top",
+ bbox={
+ "boxstyle": "round,pad=0.34",
+ "facecolor": "white",
+ "edgecolor": "#D6D6D6",
+ },
+ )
+ axis.set_title(
+ "Credit and cost remain bounded",
+ loc="left",
+ fontsize=11.3,
+ fontweight="bold",
+ pad=10,
+ )
+ style_axis(axis)
+ panel_label(axis, "d")
+ return alignment, mac_ratio
+
+
+def write_caption(path):
+ caption = """# Standard-depth ResNet scaling figure caption
+
+**Figure 6 | Dynamic somato-dendritic innovation scales across standard
+ResNet depth.** All points are frozen CIFAR-10 test endpoints from seeds
+10--14 after 200 epochs; error bars show 95% normal intervals over paired
+seeds. The renderer validates all 60 records and their source hashes against
+the passed predeclared gate. **a,** BP, clean reciprocal Kolen--Pollack credit,
+and dynamic SDIL under four-times-RMS soma-predictable apical traffic all gain
+accuracy from ResNet-20 to ResNet-56. SDIL gains 1.176 points, and all five
+paired seeds improve. **b,** On the full accuracy scale, fixed direct feedback
+alignment remains far below both reciprocal local learners at every depth;
+the complete nine-method crossover is reported separately rather than inferred
+from this four-method panel. **c,** Paired ResNet-56 minus ResNet-20 gains for
+BP and SDIL. **d,** SDIL retains a mean early-third teaching-signal cosine
+above 0.9994 while its hardware-independent affine-MAC estimate remains below
+1.34 times matched BP. Exact gradients are diagnostic-only and never used for
+learning. The SDIL rule uses no task-loss queries but does use one explicitly
+counted instruction-off neutral observation per ordinary example.
+"""
+ with open(path, "w") as handle:
+ handle.write(caption)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--d4_dir", default="results/kp_dynamic_projection_confirmation"
+ )
+ parser.add_argument(
+ "--new_dir", default="results/oral_a_dynamic_scaling_v2"
+ )
+ parser.add_argument(
+ "--gate", default="results/oral_a_dynamic_scaling_v2_gate.json"
+ )
+ parser.add_argument("--outdir", default="results/figs")
+ args = parser.parse_args()
+
+ gate, records, rows, paths = load_panel(
+ args.d4_dir, args.new_dir, args.gate
+ )
+ del records
+ os.makedirs(args.outdir, exist_ok=True)
+ plt.rcParams.update(
+ {
+ "font.family": "DejaVu Sans",
+ "font.size": 9.3,
+ "axes.linewidth": 1.0,
+ "xtick.major.width": 1.0,
+ "ytick.major.width": 1.0,
+ "pdf.fonttype": 42,
+ "ps.fonttype": 42,
+ }
+ )
+ figure, axes = plt.subplots(2, 2, figsize=(10.4, 7.45))
+ plot_near_bp(axes[0, 0], rows)
+ plot_local_contrast(axes[0, 1], rows)
+ plot_paired_gain(axes[1, 0], rows)
+ alignment, mac_ratio = plot_alignment_cost(axes[1, 1], rows)
+ figure.subplots_adjust(
+ left=0.085,
+ right=0.91,
+ bottom=0.09,
+ top=0.93,
+ hspace=0.48,
+ wspace=0.38,
+ )
+
+ stem = "figure6_standard_depth_scaling"
+ pdf_path = os.path.join(args.outdir, f"{stem}.pdf")
+ png_path = os.path.join(args.outdir, f"{stem}.png")
+ caption_path = os.path.join(args.outdir, f"{stem}_caption.md")
+ manifest_path = os.path.join(args.outdir, f"{stem}_manifest.json")
+ figure.savefig(pdf_path, metadata=PDF_METADATA)
+ figure.savefig(png_path, dpi=320)
+ plt.close(figure)
+ write_caption(caption_path)
+
+ dynamic = accuracy_array(rows, "dynamic")
+ bp = accuracy_array(rows, "bp")
+ clean_kp = accuracy_array(rows, "clean_kp")
+ dfa = accuracy_array(rows, "dfa")
+ manifest = {
+ "strict": True,
+ "protocol": PROTOCOL,
+ "gate_status": gate["status"],
+ "complete_grid": True,
+ "required_methods": list(METHODS),
+ "required_depths": list(DEPTHS),
+ "required_seeds": list(SEEDS),
+ "record_count": len(paths),
+ "statistics": {
+ "test_accuracy_mean_percent": {
+ method: {
+ str(depth): float(
+ accuracy_array(rows, method)[:, index].mean()
+ )
+ for index, depth in enumerate(DEPTHS)
+ }
+ for method in METHODS
+ },
+ "dynamic_d20_to_d56_gain_points": [
+ float(value) for value in dynamic[:, -1] - dynamic[:, 0]
+ ],
+ "dynamic_d20_to_d56_gain_points_mean": float(
+ (dynamic[:, -1] - dynamic[:, 0]).mean()
+ ),
+ "bp_d20_to_d56_gain_points": [
+ float(value) for value in bp[:, -1] - bp[:, 0]
+ ],
+ "dynamic_minus_bp_points_mean": {
+ str(depth): float((dynamic[:, index] - bp[:, index]).mean())
+ for index, depth in enumerate(DEPTHS)
+ },
+ "dynamic_minus_clean_kp_points_mean": {
+ str(depth): float(
+ (dynamic[:, index] - clean_kp[:, index]).mean()
+ )
+ for index, depth in enumerate(DEPTHS)
+ },
+ "dynamic_minus_dfa_points_mean": {
+ str(depth): float((dynamic[:, index] - dfa[:, index]).mean())
+ for index, depth in enumerate(DEPTHS)
+ },
+ "dynamic_early_alignment_mean": {
+ str(depth): float(alignment[:, index].mean())
+ for index, depth in enumerate(DEPTHS)
+ },
+ "dynamic_mac_ratio_to_bp_mean": {
+ str(depth): float(mac_ratio[:, index].mean())
+ for index, depth in enumerate(DEPTHS)
+ },
+ "dynamic_logical_task_loss_queries": sorted(
+ {
+ rows[("dynamic", depth, seed)]["logical_queries"]
+ for depth in DEPTHS
+ for seed in SEEDS
+ }
+ ),
+ "dynamic_neutral_observations_per_ordinary_example": sorted(
+ {
+ load_json(paths[("dynamic", depth, seed)])["counters"][
+ "neutral_projection_examples"
+ ]
+ / load_json(paths[("dynamic", depth, seed)])["counters"][
+ "ordinary_examples"
+ ]
+ for depth in DEPTHS
+ for seed in SEEDS
+ }
+ ),
+ },
+ "sources": [{"path": args.gate, "sha256": sha256(args.gate)}]
+ + [
+ {"path": path, "sha256": sha256(path)}
+ for path in sorted(paths.values())
+ ],
+ "outputs": [
+ os.path.basename(pdf_path),
+ os.path.basename(png_path),
+ os.path.basename(caption_path),
+ ],
+ }
+ with open(manifest_path, "w") as handle:
+ json.dump(manifest, handle, indent=2, sort_keys=True)
+ handle.write("\n")
+ print(json.dumps(manifest["statistics"], indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/results/figs/figure6_standard_depth_scaling.pdf b/results/figs/figure6_standard_depth_scaling.pdf
new file mode 100644
index 0000000..c650f27
--- /dev/null
+++ b/results/figs/figure6_standard_depth_scaling.pdf
Binary files differ
diff --git a/results/figs/figure6_standard_depth_scaling.png b/results/figs/figure6_standard_depth_scaling.png
new file mode 100644
index 0000000..8235b5a
--- /dev/null
+++ b/results/figs/figure6_standard_depth_scaling.png
Binary files differ
diff --git a/results/figs/figure6_standard_depth_scaling_caption.md b/results/figs/figure6_standard_depth_scaling_caption.md
new file mode 100644
index 0000000..62ae132
--- /dev/null
+++ b/results/figs/figure6_standard_depth_scaling_caption.md
@@ -0,0 +1,18 @@
+# Standard-depth ResNet scaling figure caption
+
+**Figure 6 | Dynamic somato-dendritic innovation scales across standard
+ResNet depth.** All points are frozen CIFAR-10 test endpoints from seeds
+10--14 after 200 epochs; error bars show 95% normal intervals over paired
+seeds. The renderer validates all 60 records and their source hashes against
+the passed predeclared gate. **a,** BP, clean reciprocal Kolen--Pollack credit,
+and dynamic SDIL under four-times-RMS soma-predictable apical traffic all gain
+accuracy from ResNet-20 to ResNet-56. SDIL gains 1.176 points, and all five
+paired seeds improve. **b,** On the full accuracy scale, fixed direct feedback
+alignment remains far below both reciprocal local learners at every depth;
+the complete nine-method crossover is reported separately rather than inferred
+from this four-method panel. **c,** Paired ResNet-56 minus ResNet-20 gains for
+BP and SDIL. **d,** SDIL retains a mean early-third teaching-signal cosine
+above 0.9994 while its hardware-independent affine-MAC estimate remains below
+1.34 times matched BP. Exact gradients are diagnostic-only and never used for
+learning. The SDIL rule uses no task-loss queries but does use one explicitly
+counted instruction-off neutral observation per ordinary example.
diff --git a/results/figs/figure6_standard_depth_scaling_manifest.json b/results/figs/figure6_standard_depth_scaling_manifest.json
new file mode 100644
index 0000000..b6c990f
--- /dev/null
+++ b/results/figs/figure6_standard_depth_scaling_manifest.json
@@ -0,0 +1,346 @@
+{
+ "complete_grid": true,
+ "gate_status": "passed",
+ "outputs": [
+ "figure6_standard_depth_scaling.pdf",
+ "figure6_standard_depth_scaling.png",
+ "figure6_standard_depth_scaling_caption.md"
+ ],
+ "protocol": "oral_a_dynamic_innovation_scaling_recovery_v2",
+ "record_count": 60,
+ "required_depths": [
+ 20,
+ 32,
+ 56
+ ],
+ "required_methods": [
+ "bp",
+ "dfa",
+ "clean_kp",
+ "dynamic"
+ ],
+ "required_seeds": [
+ 10,
+ 11,
+ 12,
+ 13,
+ 14
+ ],
+ "sources": [
+ {
+ "path": "results/oral_a_dynamic_scaling_v2_gate.json",
+ "sha256": "c0a4c0530dea26c0fffc7285e7893e6e321ba248d1e13abefbafad311a89b44f"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed10_clean_kp.json",
+ "sha256": "7c34a0e561446ad6e46575915fb8bb9cddd7b3c24c323bac1e64fea42758eb1f"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed10_dynamic.json",
+ "sha256": "dd74ca4f994e1274bf5d3b6fcc315f73b86fe0ff14c403b0f46868d476f0b5f1"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed11_clean_kp.json",
+ "sha256": "c6449d310c507a03e867046b71d280336c17c94e85ba0335cf2581389f1327ab"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed11_dynamic.json",
+ "sha256": "6a87bccb3db5fab751925d337261a19ddd08604b93f049ad80cc4e6d919fdc75"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed12_clean_kp.json",
+ "sha256": "16341d64a9ec0ad98e635d6c387effab27f4dd2dd63d218f677a8a1716d3dfae"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed12_dynamic.json",
+ "sha256": "337090a537034407a0d54b5c5a27c7502c75770814ad456cadfb9b609977a9a1"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed13_clean_kp.json",
+ "sha256": "e35f0eae6fcd41f2f9731a78eacad572e8b54f79261839faa66b0bd398c23a35"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed13_dynamic.json",
+ "sha256": "047ad3c1a724bdb5b8cdcc88b6c2ee371daa3477db1d7c8f06952aaa6c72822f"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed14_clean_kp.json",
+ "sha256": "500b22ca5cba0dcfd498eb052ac8559e04e750eb10a1945b3a33a52a5f4379eb"
+ },
+ {
+ "path": "results/kp_dynamic_projection_confirmation/seed14_dynamic.json",
+ "sha256": "70221abccb47fe43395936be4963a5f7737d1267f2d9670216d565fcff2ed976"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d20_s10.json",
+ "sha256": "e3d21e970325055bca6a30d9339a84733a9a651bee9b0c13a905e84398b55b1b"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d20_s11.json",
+ "sha256": "9e296e373e3008f9d699a5a67d75fd39fd0db3c5d46ece196ccc4299eff825f8"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d20_s12.json",
+ "sha256": "e17cc41470d4528988720d44704cc1c75bcd9002d1d832cf1aeca20982ff00cf"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d20_s13.json",
+ "sha256": "d978efcda68a316bada66168a0dbf30ac0f2df49ec842e00799a6bff3f19170f"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d20_s14.json",
+ "sha256": "36ccce2890b4c3c9eb1846ef7d3077ac1acab4ab23630f58b690e41d0d218d32"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d32_s10.json",
+ "sha256": "e169abf103873bf7e894f3ab0023aeb716f61591ade34ae6adc8397eb1dd7f2f"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d32_s11.json",
+ "sha256": "0a1d9e8a8f4333660048b8ffe40aca95eaef1a5bdbb5a0585920d100c68d5d18"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d32_s12.json",
+ "sha256": "15cd307b0e1da72a7f830beaf85eb4b7fa9d06653eeb4112c52a3b31d80b692a"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d32_s13.json",
+ "sha256": "fa25dfe4370330cce279b752d01b126331cc4dbaf02d13b703e041e24e59517f"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d32_s14.json",
+ "sha256": "296c6ba300610b59552d41dc99bf0ec1db8013bf8078c6537d4d3600cfac50cc"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d56_s10.json",
+ "sha256": "716656729a89851a0cc47a65998b4f7078b7f4fec8f65459ac24606265cc95a4"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d56_s11.json",
+ "sha256": "a6a5a70e6c3d4a4c151688cee6b1b89fcb67ca7a77b9632af87e020f7cec9a04"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d56_s12.json",
+ "sha256": "ac9176d00f3a7dc0585de5158b97945b36fc773458372d6b012e837e4973dc03"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d56_s13.json",
+ "sha256": "cba10b0c9295d0d8a30e2b34f7fa104c509169984b15a51e3c8022e25927c2d0"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/bp_d56_s14.json",
+ "sha256": "23c7221f22e9cccb76bcaa65c394a2b6e77bbc1661c024790e89160b165a7b54"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d32_s10.json",
+ "sha256": "53e629f95e40c0a09bf2e40e5ceb540b3381b7f526a54849b3b746a620fc259a"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d32_s11.json",
+ "sha256": "d21c12da44e6311db5c97ae2538f7b7b349059376edb16ea0e72653fe969f876"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d32_s12.json",
+ "sha256": "56b07513c143a3b148ccf2d9efa999006175ba5ea6c34a542eb00dd6c3470f29"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d32_s13.json",
+ "sha256": "4b33814d71143f8e3add3ae5033a4043940b37226c256c43a36f1c9fb313967f"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d32_s14.json",
+ "sha256": "af797d5586013b0e4db6cb9893c2ba8c0343cfc270221691eb7aff1fb3fb61c6"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d56_s10.json",
+ "sha256": "8f5a9796df26b72cb294a230dce365f56f751110d26aa1b69812ad32230460e8"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d56_s11.json",
+ "sha256": "21bda94033b8a00e0a2613cca189202a09e6a989df45bc728ec3238cf6167045"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d56_s12.json",
+ "sha256": "f294fa6c9be74de1d5da3cb691f79a36ca3c91b3d024f20fe0795cb27203cf0b"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d56_s13.json",
+ "sha256": "8e81eae524565e18661f75ba357e4c2b4413cc7a718d539e7bd0a06dd25027e9"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/clean_kp_d56_s14.json",
+ "sha256": "dba34e1ab4442686a1a5a60c7a136ca18fdc823758defb8fcafd0955461eb6d3"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d20_s10.json",
+ "sha256": "cdc2c819abe6416d34814e12d5aa15965ffc2c10ce7f64411e42a115e882efcb"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d20_s11.json",
+ "sha256": "cf7ca71ed75e59b1160a0e9220e954fbccc1fd3de3d2fc58584ccf18da613ec3"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d20_s12.json",
+ "sha256": "add58ff4afd96948e08858ec53ce1ae4e1e10002e84fd9f5387b75428887c13e"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d20_s13.json",
+ "sha256": "8e1f4fa5b7bdd23b71dfc67025dd81cb3620f42e575b017e240e953838e7b30c"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d20_s14.json",
+ "sha256": "876eba5327ba132af098d0872d97fad3f4801ff93a1aa5c3b85f1ee34698403c"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d32_s10.json",
+ "sha256": "af04b6f87409a763d45bfe9253e11bde704db32400779b551917ed36b92035f8"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d32_s11.json",
+ "sha256": "69087c4efa45cd13144320b547f73a5a0bcc4d3588a6fc223b10a2600a527b7e"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d32_s12.json",
+ "sha256": "f03356aa2e1761c1059148fc7d6453c1e1f568da960b50dc5610e791a8c0d937"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d32_s13.json",
+ "sha256": "1958799ce9eccb07515f72b1caa6750263528a4c520d388c44d23fb8e22b5277"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d32_s14.json",
+ "sha256": "7f3f8e890fd31e43fe46d404b4b7e1f0c3f10b4280cef6040682281080d11cd5"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d56_s10.json",
+ "sha256": "53bb57e35b7b7eb4b61b7eed92b759f99f3bd3c4fcb228fa6ee631b88a6d0a57"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d56_s11.json",
+ "sha256": "85caa64b24dfdab964a09318b09c875c044480cfe195de37ec79e5f0a1da37c6"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d56_s12.json",
+ "sha256": "55099bfe04e25914f25a12f016776a9153e68b0ab47192b2db6abbf501d1da9d"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d56_s13.json",
+ "sha256": "eb78c3653021cc0c746abaf12c1e4c2c8fdfb8463759bd990d27cd802b7aacd3"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dfa_d56_s14.json",
+ "sha256": "b87a06eb5cba577cbc03c22c149fa6a801291532f1af8a755d7f8321dd2005be"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d32_s10.json",
+ "sha256": "f482ea1d7e9d1f88ed2f80aa9a62c80d5e59b5785f10bd45860cdec6068b6529"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d32_s11.json",
+ "sha256": "ea6c562f14bd9b1b13c7b77b9179e69d8e22abd7c603109cfb041105871b47dd"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d32_s12.json",
+ "sha256": "1a7648b264feb357f240ba3e1267e7998484bc0ebbecd368a5f10b1baa890336"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d32_s13.json",
+ "sha256": "e7110e05ed867f71c36e0d6db10b8207a5c9b887dbc726e67b9832d4ff76f52b"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d32_s14.json",
+ "sha256": "d5217c25ef43f535f0fde0919a4efc17b4fcfadad4cea0fb14a43dc981c72346"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d56_s10.json",
+ "sha256": "9f9691038b9f278947080adf7dd83638d72dddd8f4f50fae6e0a584ae2a2963a"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d56_s11.json",
+ "sha256": "293bd719938dc5baeb5c609071f592878add932daa0de5f26d767ba630052af5"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d56_s12.json",
+ "sha256": "e0aa30d31a32d9ac79ee152fdbea2a564d9fdc57fef931292e0fdaebc886d63a"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d56_s13.json",
+ "sha256": "ee3d12f66ef7862af64d2ab4febdb6defddc3fbbb85002bbf5e41fe38388c3a2"
+ },
+ {
+ "path": "results/oral_a_dynamic_scaling_v2/dynamic_d56_s14.json",
+ "sha256": "ce18a0e78ff2437912ae5bf6a6244664e79e086aa3814fc78878532993f870e8"
+ }
+ ],
+ "statistics": {
+ "bp_d20_to_d56_gain_points": [
+ 0.5699999999999932,
+ 0.8700000000000045,
+ 1.4599999999999937,
+ 1.4300000000000068,
+ 0.710000000000008
+ ],
+ "dynamic_d20_to_d56_gain_points": [
+ 1.4000000000000057,
+ 1.269999999999996,
+ 0.9900000000000091,
+ 1.1400000000000006,
+ 1.0799999999999983
+ ],
+ "dynamic_d20_to_d56_gain_points_mean": 1.176000000000002,
+ "dynamic_early_alignment_mean": {
+ "20": 0.9996865272521973,
+ "32": 0.9996125328540801,
+ "56": 0.9994228409396276
+ },
+ "dynamic_logical_task_loss_queries": [
+ 0
+ ],
+ "dynamic_mac_ratio_to_bp_mean": {
+ "20": 1.3260649642373068,
+ "32": 1.3290549708518204,
+ "56": 1.3309874282025833
+ },
+ "dynamic_minus_bp_points_mean": {
+ "20": -0.04000000000000057,
+ "32": -0.047999999999998974,
+ "56": 0.1280000000000001
+ },
+ "dynamic_minus_clean_kp_points_mean": {
+ "20": 0.19600000000000078,
+ "32": -0.07800000000000011,
+ "56": 0.09000000000000057
+ },
+ "dynamic_minus_dfa_points_mean": {
+ "20": 59.705999999999996,
+ "32": 59.57000000000001,
+ "56": 61.910000000000004
+ },
+ "dynamic_neutral_observations_per_ordinary_example": [
+ 1.0
+ ],
+ "test_accuracy_mean_percent": {
+ "bp": {
+ "20": 91.624,
+ "32": 92.30199999999999,
+ "56": 92.63199999999999
+ },
+ "clean_kp": {
+ "20": 91.388,
+ "32": 92.33200000000001,
+ "56": 92.67
+ },
+ "dfa": {
+ "20": 31.877999999999997,
+ "32": 32.684,
+ "56": 30.85
+ },
+ "dynamic": {
+ "20": 91.58399999999999,
+ "32": 92.254,
+ "56": 92.75999999999999
+ }
+ }
+ },
+ "strict": true
+}