diff options
| author | YurenHao0426 <Blackhao0426@gmail.com> | 2026-07-27 14:51:17 -0500 |
|---|---|---|
| committer | YurenHao0426 <Blackhao0426@gmail.com> | 2026-07-27 14:51:17 -0500 |
| commit | a5a04b29bc93bdee4dbce6fa46bfda7cfe843928 (patch) | |
| tree | 6cfabf8daa2fbbf4bdb786c0a604ddf9729c7da1 | |
| parent | a2df73afd68278bbc961a49bbc722d17b4d83ef0 (diff) | |
figure: audit standard-depth SDIL scaling
| -rwxr-xr-x | experiments/finalize_accept.sh | 24 | ||||
| -rw-r--r-- | experiments/plot_oral_a_scaling.py | 654 | ||||
| -rw-r--r-- | results/figs/figure6_standard_depth_scaling.pdf | bin | 0 -> 38102 bytes | |||
| -rw-r--r-- | results/figs/figure6_standard_depth_scaling.png | bin | 0 -> 553126 bytes | |||
| -rw-r--r-- | results/figs/figure6_standard_depth_scaling_caption.md | 18 | ||||
| -rw-r--r-- | results/figs/figure6_standard_depth_scaling_manifest.json | 346 |
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 Binary files differnew file mode 100644 index 0000000..c650f27 --- /dev/null +++ b/results/figs/figure6_standard_depth_scaling.pdf diff --git a/results/figs/figure6_standard_depth_scaling.png b/results/figs/figure6_standard_depth_scaling.png Binary files differnew file mode 100644 index 0000000..8235b5a --- /dev/null +++ b/results/figs/figure6_standard_depth_scaling.png 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 +} |
