summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhaoyuren <13851610112@163.com>2026-07-28 21:17:38 +0800
committerhaoyuren <13851610112@163.com>2026-07-28 21:17:38 +0800
commit3b5f01cb4db9efc4ceb2ba17709bbfc82a63e660 (patch)
treead4e2321373fc9e551ffeb2ca27f5533ca9e9bdb
parent18bf25f34f6d352605086aa8fe63977baacc315b (diff)
Add appendix table generator and generated LaTeX fragments
generate_paper_tables.py reads the row-level CSVs and emits the four appendix tables (initialization calibration rows, finite-time cells, CNN calibration rows, learning-rate regimes) with the paper's nested uncertainty convention. The fragments are included by the manuscript via \input; no table value is transcribed manually. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-rw-r--r--outputs/tables/cnn_initialization_rows.tex14
-rw-r--r--outputs/tables/finite_time_cells.tex21
-rw-r--r--outputs/tables/initialization_rows.tex36
-rw-r--r--outputs/tables/learning_rate_regimes.tex21
-rw-r--r--scripts/generate_paper_tables.py177
5 files changed, 269 insertions, 0 deletions
diff --git a/outputs/tables/cnn_initialization_rows.tex b/outputs/tables/cnn_initialization_rows.tex
new file mode 100644
index 0000000..9066ce0
--- /dev/null
+++ b/outputs/tables/cnn_initialization_rows.tex
@@ -0,0 +1,14 @@
+\begin{tabular}{@{}lrccc@{}}
+\toprule
+Rule & Init & Prediction & Measured & SE \\
+\midrule
+DFA & 0 & 0.647613 & 0.652511 & 0.0051 \\
+DFA & 1 & 0.591587 & 0.587769 & 0.0066 \\
+DFA & 2 & 0.771871 & 0.776294 & 0.0053 \\
+DFA & 3 & 0.815630 & 0.814164 & 0.0052 \\
+FA & 0 & 0.647613 & 0.648186 & 0.005 \\
+FA & 1 & 0.591587 & 0.599896 & 0.0064 \\
+FA & 2 & 0.771871 & 0.777543 & 0.0055 \\
+FA & 3 & 0.815630 & 0.814227 & 0.0052 \\
+\bottomrule
+\end{tabular}
diff --git a/outputs/tables/finite_time_cells.tex b/outputs/tables/finite_time_cells.tex
new file mode 100644
index 0000000..20f76be
--- /dev/null
+++ b/outputs/tables/finite_time_cells.tex
@@ -0,0 +1,21 @@
+\begin{tabular}{@{}rrccccc@{}}
+\toprule
+Depth & Width & Measured & SE & Frozen & Linear & Relinearized \\
+\midrule
+1 & 32 & 0.051369 & 0.0079 & 0.057429 & 0.051108 & 0.053289 \\
+1 & 64 & 0.042081 & 0.0026 & 0.046148 & 0.041747 & 0.043214 \\
+1 & 96 & 0.040667 & 0.0041 & 0.044705 & 0.040255 & 0.041735 \\
+2 & 32 & 0.199114 & 0.015 & 0.245567 & 0.196161 & 0.213008 \\
+2 & 64 & 0.152697 & 0.0082 & 0.176001 & 0.150869 & 0.159079 \\
+2 & 96 & 0.218336 & 0.022 & 0.247394 & 0.216029 & 0.225711 \\
+3 & 32 & 0.206504 & 0.037 & 0.278753 & 0.196695 & 0.226089 \\
+3 & 64 & 0.252548 & 0.035 & 0.301208 & 0.246641 & 0.263831 \\
+3 & 96 & 0.312576 & 0.029 & 0.376889 & 0.306903 & 0.326215 \\
+4 & 32 & 0.222365 & 0.061 & 0.285694 & 0.212004 & 0.236205 \\
+4 & 64 & 0.281210 & 0.013 & 0.360586 & 0.274093 & 0.302059 \\
+4 & 96 & 0.451119 & 0.02 & 0.554664 & 0.441827 & 0.473896 \\
+6 & 32 & 0.202818 & 0.0058 & 0.291825 & 0.206767 & 0.221531 \\
+6 & 64 & 0.346053 & 0.042 & 0.518519 & 0.312131 & 0.371649 \\
+6 & 96 & 0.535727 & 0.032 & 0.733133 & 0.501304 & 0.565975 \\
+\bottomrule
+\end{tabular}
diff --git a/outputs/tables/initialization_rows.tex b/outputs/tables/initialization_rows.tex
new file mode 100644
index 0000000..0654013
--- /dev/null
+++ b/outputs/tables/initialization_rows.tex
@@ -0,0 +1,36 @@
+\begin{tabular}{@{}rrccc@{}}
+\toprule
+Depth & Init & Prediction & FA measured (SE) & DFA measured (SE) \\
+\midrule
+1 & 0 & 0.053588 & 0.052887 (0.00037) & 0.053807 (0.00041) \\
+1 & 1 & 0.062410 & 0.062244 (0.00048) & 0.062625 (0.00048) \\
+1 & 2 & 0.028953 & 0.029159 (0.00023) & 0.029212 (0.00023) \\
+1 & 3 & 0.040257 & 0.040253 (0.00028) & 0.040521 (0.00028) \\
+1 & 4 & 0.038773 & 0.038649 (0.00032) & 0.039119 (0.00031) \\
+1 & 5 & 0.078297 & 0.078008 (0.0006) & 0.078183 (0.00056) \\
+2 & 0 & 0.218902 & 0.218122 (0.0024) & 0.221537 (0.0024) \\
+2 & 1 & 0.279596 & 0.280372 (0.0027) & 0.280990 (0.0025) \\
+2 & 2 & 0.364830 & 0.361380 (0.003) & 0.364535 (0.003) \\
+2 & 3 & 0.307008 & 0.306619 (0.0024) & 0.309576 (0.0025) \\
+2 & 4 & 0.182403 & 0.181656 (0.0021) & 0.182641 (0.0023) \\
+2 & 5 & 0.309058 & 0.307749 (0.0023) & 0.309189 (0.0022) \\
+3 & 0 & 0.470739 & 0.468836 (0.0036) & 0.466214 (0.0041) \\
+3 & 1 & 0.444351 & 0.446781 (0.0033) & 0.448788 (0.0034) \\
+3 & 2 & 0.374155 & 0.373663 (0.0027) & 0.373020 (0.0032) \\
+3 & 3 & 0.277165 & 0.276679 (0.0039) & 0.278645 (0.0043) \\
+3 & 4 & 0.368780 & 0.367594 (0.0037) & 0.369790 (0.0039) \\
+3 & 5 & 0.480622 & 0.479752 (0.0036) & 0.477239 (0.0039) \\
+4 & 0 & 0.509811 & 0.507382 (0.0033) & 0.507785 (0.0036) \\
+4 & 1 & 0.504652 & 0.502008 (0.0033) & 0.501042 (0.0039) \\
+4 & 2 & 0.433303 & 0.429889 (0.0037) & 0.437931 (0.0041) \\
+4 & 3 & 0.493355 & 0.498489 (0.004) & 0.490059 (0.0045) \\
+4 & 4 & 0.282292 & 0.278860 (0.0029) & 0.278743 (0.0027) \\
+4 & 5 & 0.527837 & 0.525461 (0.0035) & 0.525114 (0.004) \\
+6 & 0 & 0.655509 & 0.660608 (0.0035) & 0.652847 (0.0043) \\
+6 & 1 & 0.694866 & 0.703226 (0.0049) & 0.702721 (0.0051) \\
+6 & 2 & 0.688833 & 0.689167 (0.004) & 0.687606 (0.0044) \\
+6 & 3 & 0.497143 & 0.494329 (0.0032) & 0.491664 (0.0035) \\
+6 & 4 & 0.595326 & 0.586449 (0.0038) & 0.591266 (0.0037) \\
+6 & 5 & 0.607480 & 0.611624 (0.0038) & 0.616644 (0.0038) \\
+\bottomrule
+\end{tabular}
diff --git a/outputs/tables/learning_rate_regimes.tex b/outputs/tables/learning_rate_regimes.tex
new file mode 100644
index 0000000..85a8048
--- /dev/null
+++ b/outputs/tables/learning_rate_regimes.tex
@@ -0,0 +1,21 @@
+\begin{tabular}{@{}rlcccc@{}}
+\toprule
+Depth & Regime & BP rate & Mean FA rate & Gap & SE \\
+\midrule
+1 & Same rate & 0.001 & 0.001 & 0.05906 & 0.0039 \\
+1 & Initial compensation & 0.001 & 0.001041 & 0.04053 & 0.0031 \\
+1 & Independently selected & 0.128 & 0.064 & 0.56940 & 0.01 \\
+2 & Same rate & 0.001 & 0.001 & 0.19917 & 0.014 \\
+2 & Initial compensation & 0.001 & 0.001317 & 0.09729 & 0.01 \\
+2 & Independently selected & 0.128 & 0.032 & 0.64210 & 0.051 \\
+3 & Same rate & 0.001 & 0.001 & 0.27346 & 0.026 \\
+3 & Initial compensation & 0.001 & 0.001607 & 0.16262 & 0.024 \\
+3 & Independently selected & 0.064 & 0.016 & 1.13002 & 0.024 \\
+4 & Same rate & 0.001 & 0.001 & 0.29340 & 0.021 \\
+4 & Initial compensation & 0.001 & 0.001917 & 0.18442 & 0.017 \\
+4 & Independently selected & 0.064 & 0.016 & 1.30812 & 0.06 \\
+6 & Same rate & 0.001 & 0.001 & 0.40664 & 0.038 \\
+6 & Initial compensation & 0.001 & 0.002591 & 0.28850 & 0.027 \\
+6 & Independently selected & 0.064 & 0.004 & 1.75739 & 0.026 \\
+\bottomrule
+\end{tabular}
diff --git a/scripts/generate_paper_tables.py b/scripts/generate_paper_tables.py
new file mode 100644
index 0000000..ed66dae
--- /dev/null
+++ b/scripts/generate_paper_tables.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python3
+"""Generate LaTeX table fragments for the paper appendices from row-level CSVs.
+
+Each fragment contains only a tabular environment; captions and labels live in
+the paper source. Uncertainty follows the paper's nesting convention: feedback
+draws are averaged within each forward initialization first, and standard
+errors are computed across forward-initialization means.
+"""
+
+from __future__ import annotations
+
+import argparse
+import csv
+import math
+import statistics
+from collections import defaultdict
+from pathlib import Path
+
+
+def parse_args() -> argparse.Namespace:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("--depth-dir", type=Path, default=Path("outputs/aaai_depth_experiments"))
+ parser.add_argument(
+ "--cnn-dir", type=Path, default=Path("outputs/cnn_initialization_validation")
+ )
+ parser.add_argument(
+ "--lr-dir", type=Path, default=Path("outputs/learning_rate_compensation")
+ )
+ parser.add_argument("--outdir", type=Path, default=Path("outputs/tables"))
+ return parser.parse_args()
+
+
+def read_rows(path: Path) -> list[dict[str, str]]:
+ if not path.exists():
+ raise FileNotFoundError(path)
+ with path.open() as handle:
+ return list(csv.DictReader(handle))
+
+
+def sem(values: list[float]) -> float:
+ if len(values) < 2:
+ return float("nan")
+ return statistics.stdev(values) / math.sqrt(len(values))
+
+
+def write_fragment(path: Path, lines: list[str]) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text("\n".join(lines) + "\n")
+ print(f"wrote {path}")
+
+
+def initialization_table(depth_dir: Path, outdir: Path) -> None:
+ rows = read_rows(depth_dir / "initialization_rows.csv")
+ cells: dict[tuple[int, int], dict[str, dict[str, float]]] = defaultdict(dict)
+ for row in rows:
+ key = (int(row["depth"]), int(row["init_seed"]))
+ cells[key][row["rule"]] = {
+ "pred": float(row["predicted_deficit"]),
+ "mean": float(row["empirical_deficit"]),
+ "se": float(row["empirical_stderr"]),
+ }
+ lines = [
+ r"\begin{tabular}{@{}rrccc@{}}",
+ r"\toprule",
+ r"Depth & Init & Prediction & FA measured (SE) & DFA measured (SE) \\",
+ r"\midrule",
+ ]
+ for (depth, init_seed), by_rule in sorted(cells.items()):
+ fa, dfa = by_rule["FA"], by_rule["DFA"]
+ assert abs(fa["pred"] - dfa["pred"]) < 1e-12, (depth, init_seed)
+ lines.append(
+ f"{depth} & {init_seed - 10_000} & {fa['pred']:.6f} & "
+ f"{fa['mean']:.6f} ({fa['se']:.2g}) & "
+ f"{dfa['mean']:.6f} ({dfa['se']:.2g}) \\\\"
+ )
+ lines += [r"\bottomrule", r"\end{tabular}"]
+ write_fragment(outdir / "initialization_rows.tex", lines)
+
+
+def finite_time_table(depth_dir: Path, outdir: Path) -> None:
+ rows = read_rows(depth_dir / "finite_time_rows.csv")
+ cells: dict[tuple[int, int], dict[int, dict[str, list[float]]]] = defaultdict(
+ lambda: defaultdict(lambda: defaultdict(list))
+ )
+ fields = ["empirical_gap", "fixed_gap", "velocity_gap", "retangent_gap"]
+ for row in rows:
+ cell = cells[(int(row["depth"]), int(row["width"]))][int(row["init_seed"])]
+ for field in fields:
+ cell[field].append(float(row[field]))
+ lines = [
+ r"\begin{tabular}{@{}rrccccc@{}}",
+ r"\toprule",
+ r"Depth & Width & Measured & SE & Frozen & Linear & Relinearized \\",
+ r"\midrule",
+ ]
+ for (depth, width), by_init in sorted(cells.items()):
+ init_means = {
+ field: [statistics.mean(values[field]) for _, values in sorted(by_init.items())]
+ for field in fields
+ }
+ measured = statistics.mean(init_means["empirical_gap"])
+ lines.append(
+ f"{depth} & {width} & {measured:.6f} & {sem(init_means['empirical_gap']):.2g} & "
+ f"{statistics.mean(init_means['fixed_gap']):.6f} & "
+ f"{statistics.mean(init_means['velocity_gap']):.6f} & "
+ f"{statistics.mean(init_means['retangent_gap']):.6f} \\\\"
+ )
+ lines += [r"\bottomrule", r"\end{tabular}"]
+ write_fragment(outdir / "finite_time_cells.tex", lines)
+
+
+def cnn_table(cnn_dir: Path, outdir: Path) -> None:
+ rows = read_rows(cnn_dir / "cnn_initialization_rows.csv")
+ lines = [
+ r"\begin{tabular}{@{}lrccc@{}}",
+ r"\toprule",
+ r"Rule & Init & Prediction & Measured & SE \\",
+ r"\midrule",
+ ]
+ for row in sorted(rows, key=lambda r: (r["rule"], int(r["init_seed"]))):
+ lines.append(
+ f"{row['rule']} & {int(row['init_seed']) - 10_000} & "
+ f"{float(row['predicted_deficit']):.6f} & "
+ f"{float(row['empirical_deficit']):.6f} & "
+ f"{float(row['empirical_stderr']):.2g} \\\\"
+ )
+ lines += [r"\bottomrule", r"\end{tabular}"]
+ write_fragment(outdir / "cnn_initialization_rows.tex", lines)
+
+
+def learning_rate_table(lr_dir: Path, outdir: Path) -> None:
+ rows = read_rows(lr_dir / "evaluation_rows.csv")
+ regime_order = {"same_lr": 0, "initial_compensation": 1, "independently_tuned": 2}
+ regime_label = {
+ "same_lr": "Same rate",
+ "initial_compensation": "Initial compensation",
+ "independently_tuned": "Independently selected",
+ }
+ cells: dict[tuple[int, str], dict[int, list[float]]] = defaultdict(lambda: defaultdict(list))
+ fa_rates: dict[tuple[int, str], list[float]] = defaultdict(list)
+ bp_rates: dict[tuple[int, str], set[float]] = defaultdict(set)
+ for row in rows:
+ assert row["stable"] == "True", row
+ key = (int(row["depth"]), row["regime"])
+ cells[key][int(row["init_seed"])].append(float(row["gap_to_bp"]))
+ fa_rates[key].append(float(row["fa_lr"]))
+ bp_rates[key].add(float(row["bp_lr"]))
+ lines = [
+ r"\begin{tabular}{@{}rlcccc@{}}",
+ r"\toprule",
+ r"Depth & Regime & BP rate & Mean FA rate & Gap & SE \\",
+ r"\midrule",
+ ]
+ for (depth, regime), by_init in sorted(
+ cells.items(), key=lambda item: (item[0][0], regime_order[item[0][1]])
+ ):
+ init_means = [statistics.mean(values) for _, values in sorted(by_init.items())]
+ (bp_rate,) = bp_rates[(depth, regime)]
+ lines.append(
+ f"{depth} & {regime_label[regime]} & {bp_rate:g} & "
+ f"{statistics.mean(fa_rates[(depth, regime)]):.4g} & "
+ f"{statistics.mean(init_means):.5f} & {sem(init_means):.2g} \\\\"
+ )
+ lines += [r"\bottomrule", r"\end{tabular}"]
+ write_fragment(outdir / "learning_rate_regimes.tex", lines)
+
+
+def main() -> None:
+ args = parse_args()
+ initialization_table(args.depth_dir, args.outdir)
+ finite_time_table(args.depth_dir, args.outdir)
+ cnn_table(args.cnn_dir, args.outdir)
+ learning_rate_table(args.lr_dir, args.outdir)
+
+
+if __name__ == "__main__":
+ main()