eac123 commited on
Commit
11de80f
·
verified ·
1 Parent(s): 297c289

§4.8 v2 variants: registered predictions, computed verdicts, families registered everywhere

Browse files
Files changed (1) hide show
  1. make_report.py +106 -8
make_report.py CHANGED
@@ -20,7 +20,7 @@ REPO = "eac123/ptr-recurrent-depth"
20
  PLOTS = "plots"
21
 
22
  FAMILIES = ["fixed4x1", "rec1x4", "rec2x2", "rec1xdynamic", "rec4x4",
23
- "fixed4-long", "rec1aligned"]
24
  LABELS = {
25
  "fixed4x1": "fixed-4 (4 blocks x 1)",
26
  "rec1x4": "recurrent 1x4 (train R=4)",
@@ -29,9 +29,12 @@ LABELS = {
29
  "rec4x4": "recurrent 4x4 (train R=4)",
30
  "fixed4-long": "fixed-4 long (100k steps)",
31
  "rec1aligned": "rec-1x-aligned (train R=k)",
 
 
32
  }
33
  TRAIN_ITERS = {"fixed4x1": 1, "rec1x4": 4, "rec2x2": 2, "rec1xdynamic": 8,
34
- "rec4x4": 4, "fixed4-long": 1, "rec1aligned": None}
 
35
 
36
 
37
  def pull():
@@ -121,7 +124,7 @@ def plot_acc_vs_iters(evals, out,
121
 
122
  def plot_perk_zoom(evals, out,
123
  fams=("fixed4x1", "rec1x4", "rec1xdynamic", "rec4x4",
124
- "rec1aligned"), kmax=16):
125
  """Within-and-just-beyond training range: accuracy per hop count k."""
126
  fig, ax = plt.subplots(figsize=(8.5, 5))
127
  ks = np.arange(1, kmax + 1)
@@ -144,6 +147,17 @@ def plot_perk_zoom(evals, out,
144
  fig.tight_layout(); fig.savefig(out, dpi=150); plt.close(fig)
145
 
146
 
 
 
 
 
 
 
 
 
 
 
 
147
  def perk_rows(evals, fams, klo, khi):
148
  ks = list(range(klo, khi + 1))
149
  lines = ["| family | " + " | ".join(f"k={k}" for k in ks) + " |",
@@ -208,7 +222,8 @@ def plot_training(evals, out):
208
 
209
  SHORT = {"fixed4x1": "fixed-4", "rec1x4": "rec-1x4", "rec2x2": "rec-2x2",
210
  "rec1xdynamic": "rec-1x-dyn", "rec4x4": "rec-4x4",
211
- "fixed4-long": "fixed-4-long", "rec1aligned": "rec-1x-aligned"}
 
212
 
213
 
214
  def plot_headline_bars(evals, out):
@@ -261,13 +276,15 @@ def plot_budget_map(evals, out):
261
  OFF = {"fixed4x1": (8, -14, "left"), "rec1x4": (0, -16, "center"),
262
  "rec2x2": (10, -4, "left"), "rec1xdynamic": (8, 8, "left"),
263
  "rec4x4": (-8, 10, "right"), "fixed4-long": (8, -14, "left"),
264
- "rec1aligned": (8, -16, "left")}
 
265
  for f in FAMILIES:
266
  if not evals[f]:
267
  continue
268
  p, fl = budget_of(evals[f])
269
  ax.scatter(p, fl, s=90, zorder=3,
270
- marker="s" if f == "rec1aligned" else "o")
 
271
  dx, dy, ha = OFF[f]
272
  ax.annotate(LABELS[f], (p, fl), fontsize=7, ha=ha,
273
  xytext=(dx, dy), textcoords="offset points")
@@ -509,6 +526,49 @@ def report(evals, rows):
509
  f"{lm:.3f}, k=16 {le['acc_vs_k']['16']:.3f}, "
510
  f"k=64 {le['acc_vs_k']['64']:.3f} -> {verdict}",
511
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
  lines = [
513
  "# Technical report: recurrent depth vs fixed depth on pointer chasing",
514
  "",
@@ -695,10 +755,12 @@ def report(evals, rows):
695
  "mappings per cell, mean over seeds):",
696
  "",
697
  *perk_rows(evals, ["fixed4x1", "rec1x4", "rec2x2", "rec1xdynamic",
698
- "rec4x4", "fixed4-long", "rec1aligned"], 1, 8),
 
699
  "",
700
  *perk_rows(evals, ["fixed4x1", "rec1x4", "rec2x2", "rec1xdynamic",
701
- "rec4x4", "fixed4-long", "rec1aligned"], 9, 16),
 
702
  "",
703
  "![per-k zoom](plots/perk_zoom.png)",
704
  "",
@@ -790,6 +852,42 @@ def report(evals, rows):
790
  "",
791
  *al_lines,
792
  "",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
  "## 5. Conclusions",
794
  "",
795
  "1. **Recurrent depth buys learnability that neither parameters nor",
 
20
  PLOTS = "plots"
21
 
22
  FAMILIES = ["fixed4x1", "rec1x4", "rec2x2", "rec1xdynamic", "rec4x4",
23
+ "fixed4-long", "rec1aligned", "rec1m4", "rec1m4dense"]
24
  LABELS = {
25
  "fixed4x1": "fixed-4 (4 blocks x 1)",
26
  "rec1x4": "recurrent 1x4 (train R=4)",
 
29
  "rec4x4": "recurrent 4x4 (train R=4)",
30
  "fixed4-long": "fixed-4 long (100k steps)",
31
  "rec1aligned": "rec-1x-aligned (train R=k)",
32
+ "rec1m4": "rec-1x m4 (R=k+4, end-of-chain loss)",
33
+ "rec1m4dense": "rec-1x m4+dense (R=k+4, stem, dense loss)",
34
  }
35
  TRAIN_ITERS = {"fixed4x1": 1, "rec1x4": 4, "rec2x2": 2, "rec1xdynamic": 8,
36
+ "rec4x4": 4, "fixed4-long": 1, "rec1aligned": None,
37
+ "rec1m4": None, "rec1m4dense": None}
38
 
39
 
40
  def pull():
 
124
 
125
  def plot_perk_zoom(evals, out,
126
  fams=("fixed4x1", "rec1x4", "rec1xdynamic", "rec4x4",
127
+ "rec1aligned", "rec1m4", "rec1m4dense"), kmax=16):
128
  """Within-and-just-beyond training range: accuracy per hop count k."""
129
  fig, ax = plt.subplots(figsize=(8.5, 5))
130
  ks = np.arange(1, kmax + 1)
 
147
  fig.tight_layout(); fig.savefig(out, dpi=150); plt.close(fig)
148
 
149
 
150
+ def frontier(m, thr=0.9):
151
+ """Last k with mean accuracy >= thr (scanning from k=1)."""
152
+ best = 0
153
+ for k in range(1, len(m) + 1):
154
+ if m[k - 1] >= thr:
155
+ best = k
156
+ else:
157
+ break
158
+ return best
159
+
160
+
161
  def perk_rows(evals, fams, klo, khi):
162
  ks = list(range(klo, khi + 1))
163
  lines = ["| family | " + " | ".join(f"k={k}" for k in ks) + " |",
 
222
 
223
  SHORT = {"fixed4x1": "fixed-4", "rec1x4": "rec-1x4", "rec2x2": "rec-2x2",
224
  "rec1xdynamic": "rec-1x-dyn", "rec4x4": "rec-4x4",
225
+ "fixed4-long": "fixed-4-long", "rec1aligned": "rec-1x-aligned",
226
+ "rec1m4": "m4", "rec1m4dense": "m4+dense"}
227
 
228
 
229
  def plot_headline_bars(evals, out):
 
276
  OFF = {"fixed4x1": (8, -14, "left"), "rec1x4": (0, -16, "center"),
277
  "rec2x2": (10, -4, "left"), "rec1xdynamic": (8, 8, "left"),
278
  "rec4x4": (-8, 10, "right"), "fixed4-long": (8, -14, "left"),
279
+ "rec1aligned": (8, -16, "left"),
280
+ "rec1m4": (8, 8, "left"), "rec1m4dense": (8, -16, "left")}
281
  for f in FAMILIES:
282
  if not evals[f]:
283
  continue
284
  p, fl = budget_of(evals[f])
285
  ax.scatter(p, fl, s=90, zorder=3,
286
+ marker="s" if f != "rec1x4" and f.startswith("rec1")
287
+ else "o")
288
  dx, dy, ha = OFF[f]
289
  ax.annotate(LABELS[f], (p, fl), fontsize=7, ha=ha,
290
  xytext=(dx, dy), textcoords="offset points")
 
526
  f"{lm:.3f}, k=16 {le['acc_vs_k']['16']:.3f}, "
527
  f"k=64 {le['acc_vs_k']['64']:.3f} -> {verdict}",
528
  ]
529
+
530
+ # --- v2 aligned variants (stage 5) ---
531
+ def variant_lines(fam, stair_margin=4):
532
+ ev = evals[fam]
533
+ if not ev:
534
+ return [f"*(stage-5 runs not finished: {fam})*"]
535
+ acc = np.array([[e["acc_vs_k"][str(k)] for k in range(1, 17)]
536
+ for e in ev])
537
+ m = acc.mean(0)
538
+ fm = frontier(m)
539
+ hi, lo = [], []
540
+ for e in ev:
541
+ for r, cells in e["acc_vs_iters"].items():
542
+ for kk, v in cells.items():
543
+ (hi if int(kk) <= int(r) - stair_margin else lo).append(v)
544
+ st = float(np.mean(hi) - np.mean(lo))
545
+ return [
546
+ f"- in-distribution (k=1..8 mean): {ms(fam, id_mean)}",
547
+ f"- frontier (last k with >=0.9 mean acc): **k={fm}**",
548
+ f"- k=16 {m[15]:.3f}, k=32 "
549
+ f"{np.mean([e['acc_vs_k']['32'] for e in ev]):.3f}, k=64 "
550
+ f"{np.mean([e['acc_vs_k']['64'] for e in ev]):.3f}",
551
+ f"- staircase check (acc high iff k <= R-{stair_margin}): "
552
+ f"{st:+.3f}",
553
+ ]
554
+
555
+ al2_lines = (["**A / m4 (margin, end-of-chain loss):**"]
556
+ + variant_lines("rec1m4")
557
+ + ["", "**B / m4+dense (margin + stem + dense):**"]
558
+ + variant_lines("rec1m4dense"))
559
+ if evals["rec1m4"] and evals["rec1m4dense"]:
560
+ p1 = np.mean([id_mean(e) for e in evals["rec1m4"]]) < 0.5
561
+ mB = float(np.array([[e["acc_vs_k"][str(k)] for k in range(1, 9)]
562
+ for e in evals["rec1m4dense"]]).mean())
563
+ mBm = np.array([[e["acc_vs_k"][str(k)] for k in range(1, 17)]
564
+ for e in evals["rec1m4dense"]]).mean(0)
565
+ p2 = mB >= 0.9
566
+ p3 = frontier(mBm) >= 12
567
+ al2_lines += [
568
+ f"- (P1) {('**supported**' if p1 else '**not supported**')}",
569
+ f"- (P2) {('**supported**' if p2 else '**not supported**')}",
570
+ f"- (P3) {('**supported**' if p3 else '**not supported**')}",
571
+ ]
572
  lines = [
573
  "# Technical report: recurrent depth vs fixed depth on pointer chasing",
574
  "",
 
755
  "mappings per cell, mean over seeds):",
756
  "",
757
  *perk_rows(evals, ["fixed4x1", "rec1x4", "rec2x2", "rec1xdynamic",
758
+ "rec4x4", "fixed4-long", "rec1aligned", "rec1m4",
759
+ "rec1m4dense"], 1, 8),
760
  "",
761
  *perk_rows(evals, ["fixed4x1", "rec1x4", "rec2x2", "rec1xdynamic",
762
+ "rec4x4", "fixed4-long", "rec1aligned", "rec1m4",
763
+ "rec1m4dense"], 9, 16),
764
  "",
765
  "![per-k zoom](plots/perk_zoom.png)",
766
  "",
 
852
  "",
853
  *al_lines,
854
  "",
855
+ "### 4.8 v2 aligned variants: margin R = k+4, stem layer, dense supervision",
856
+ "",
857
+ "The 4.7 diagnosis says the R=k objective fails because of (i) exact",
858
+ "halting at depth k, and (ii) no per-step signal. The v2 variants",
859
+ "(user design) target both, separately:",
860
+ "",
861
+ "- **A / m4** (3 seeds): R = k + 4 with end-of-chain supervision",
862
+ " only. The margin removes exact halting - the model needs 'at",
863
+ " least k unrolls', and can idle for the last 4. Everything else",
864
+ " identical to rec-1x4.",
865
+ "- **B / m4+dense** (3 seeds): R = k + 4, one untied stem block",
866
+ " before the loop, and dense supervision - every unroll t gets an",
867
+ " auxiliary head predicting f^{min(t,k)}(x), i.e. each unroll does",
868
+ " its own hop and then holds. This is the per-step signal the R=k",
869
+ " run lacked, and it acts as a curriculum: unroll 1 only has to",
870
+ " learn the lookup, later unrolls inherit it.",
871
+ "",
872
+ "At evaluation both read out at R = k + 4 for every k - the trained",
873
+ "inference mode - including k > 8.",
874
+ "",
875
+ "*Predictions registered before the runs:*",
876
+ "",
877
+ "- (P1) margin alone does **not** rescue learning (the credit-",
878
+ " assignment problem, not exact halting, was the blocker); it",
879
+ " should learn faster than R=k but plateau low.",
880
+ "- (P2) dense + stem **does** rescue: >= 0.9 mean accuracy across",
881
+ " k = 1..8, and a fixed-R sweep showing a staircase (accuracy high",
882
+ " iff k <= R - 4) rather than a peak at one R.",
883
+ "- (P3) if the fix is real, B extends beyond k=8 better than every",
884
+ " existing family (R = k+4 is its trained mode at any k), bounded",
885
+ " by OOD step embeddings (unroll indices > 11 were never trained).",
886
+ "",
887
+ "*Results:*",
888
+ "",
889
+ *al2_lines,
890
+ "",
891
  "## 5. Conclusions",
892
  "",
893
  "1. **Recurrent depth buys learnability that neither parameters nor",