Buckets:
| """cwm3/eval/report_modality_table.py — modality / control table of the vehicle-onset cells (WP3 R2 reviewer controls, pre-registered 2026-09-16T06:46:35Z). | |
| python eval/report_modality_table.py [--seeds 0,1,2] [--out results/tables/modality_ablation.md] | |
| Systems (all on the FINAL bases, dirs I1_<variant>_s<k>_final): V = indep (the assembled independent branches; reference), V+E = env2veh, V+U = drv2veh, | |
| all = all_minus_road2drv (the main model: env2veh + drv2veh), none (same fine-tuning, no interaction), naive (pretrained trunks + default-init fusion), | |
| naive_fresh (from-scratch fusion) and its MTL arms naive_fresh_{uw,famo,pcgrad}, all + PCGrad (all_minus_road2drv_pcgrad). | |
| Cells: veh_onset {brake_on, gas_on, steer_phase_on, veh_any_on} @3 s PR-AUC, both regimes; cost cells = hazard NLL of the vehicle and driver chains. | |
| Numbers come only from results/paired_compare.csv (tags finalc_s<k>_<A>_vs_<B>, eval/paired_compare_joint.py: identical rows, device-cluster bootstrap, | |
| n_boot 1000); verdicts = kill_checks.beats through eval/report_joint.verdict (>= 2/3 seed CIs excluding 0, same sign, |mean Δ| > seed sd). Nothing is | |
| recomputed here. The consequence-table reading at the end applies the pre-registered rules mechanically; the decisions row states the conclusion. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import sys | |
| import time | |
| from pathlib import Path | |
| import numpy as np | |
| import pandas as pd | |
| CWM3 = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(CWM3 / "eval")) | |
| import report_joint as RJ # noqa: E402 (load / verdict / OWN — the same rules as the stage tables) | |
| SYSTEMS = [("V (indep)", "indep"), ("V+E (env2veh)", "env2veh"), ("V+U (drv2veh)", "drv2veh"), ("all = V+E+U (allminus, main)", "allminus"), | |
| ("none (fine-tune, no interaction)", "none"), ("naive (pretrained + default-init fusion)", "naive"), ("naive_fresh (scratch fusion)", "naivefresh"), | |
| ("naive_fresh + UW", "naivefreshuw"), ("naive_fresh + FAMO", "naivefreshfamo"), ("naive_fresh + PCGrad", "naivefreshpcgrad"), ("all + PCGrad", "allminuspcgrad")] | |
| VEH = [("brake", "veh_onset|brake_on|3s"), ("gas", "veh_onset|gas_on|3s"), ("steer_phase", "veh_onset|steer_phase_on|3s"), ("veh_any", "veh_onset|veh_any_on|3s")] | |
| COST = [("NLL gas", "hazard_nll|gas_on"), ("NLL brake", "hazard_nll|brake_on"), ("NLL steer_phase", "hazard_nll|steer_phase_on"), | |
| ("NLL hand_return", "hazard_nll|hand_return"), ("NLL hand_leave", "hazard_nll|hand_leave"), ("NLL head_turn", "hazard_nll|head_turn_onset")] | |
| MARGIN_PR, MARGIN_NLL = -0.005, 0.01 # acceptable-degradation margins (rev 2 discipline) | |
| PLAIN_SUM = {"naivefreshuw": "naivefresh", "naivefreshfamo": "naivefresh", "naivefreshpcgrad": "naivefresh", "allminuspcgrad": "allminus"} | |
| def pair(a, b, seeds): | |
| try: | |
| return RJ.load("finalc", a, b, seeds) | |
| except Exception: # noqa: BLE001 | |
| return pd.DataFrame() | |
| def cell_rows(df, regime, cell, metric): | |
| if not len(df): | |
| return df | |
| return df[(df.regime == regime) & (df.cell == cell) & (df.metric == metric)].sort_values("seed") | |
| def fmt_delta(g, lower_better=False): | |
| """'Δ̄=+0.0123 [CI s0] [CI s1] [CI s2] VERDICT' from the per-seed rows.""" | |
| if not len(g): | |
| return "—" | |
| d = g.delta.astype(float).to_numpy() | |
| cis = " ".join(f"[{lo:+.3f},{hi:+.3f}]" for lo, hi in zip(g.delta_ci_lo.astype(float), g.delta_ci_hi.astype(float))) | |
| v = RJ.verdict(g, lower_better)["verdict"] if len(g) >= 1 else "—" | |
| return f"Δ̄={d.mean():+.4f} (n={len(d)}) {cis} **{v}**" | |
| def fmt_a(g): | |
| if not len(g): | |
| return "—" | |
| a = g.value_a.astype(float).to_numpy() | |
| return f"{a.mean():.4f} ± {a.std(ddof=1) if len(a) > 1 else 0.0:.4f}" | |
| def fmt_b(g): | |
| if not len(g): | |
| return "—" | |
| b = g.value_b.astype(float).to_numpy() | |
| return f"{b.mean():.4f} ± {b.std(ddof=1) if len(b) > 1 else 0.0:.4f}" | |
| def table(seeds, ref, cells, metric, lower_better, title): | |
| """one table per regime: rows = systems, columns = cells; each entry = A̅ ± sd | Δ vs `ref` with per-seed CIs and verdict.""" | |
| lines = [f"### {title}", ""] | |
| P = {s: pair(s, ref, seeds) for _, s in SYSTEMS if s != ref} | |
| for regime in ("manual", "engaged"): | |
| lines += [f"**{regime}**", "", "| system | " + " | ".join(n for n, _ in cells) + " |", "|---|" + "---|" * len(cells)] | |
| # the reference's own values (value_b of the main pair; asserted consistent across pairs below) | |
| ref_pair = P.get("allminus" if ref == "indep" else "none") | |
| if ref_pair is not None and len(ref_pair): | |
| lines.append(f"| {dict((s, n) for n, s in SYSTEMS)[ref]} — reference (B values) | " + | |
| " | ".join(fmt_b(cell_rows(ref_pair, regime, c, metric)) for _, c in cells) + " |") | |
| for name, s in SYSTEMS: | |
| if s == ref: | |
| continue | |
| df = P[s] | |
| if not len(df): | |
| lines.append(f"| {name} | " + " | ".join("no rows yet" for _ in cells) + " |") | |
| continue | |
| ent = [] | |
| for _, c in cells: | |
| g = cell_rows(df, regime, c, metric) | |
| ent.append(f"A̅={fmt_a(g)}; {fmt_delta(g, lower_better)}" if len(g) else "—") | |
| lines.append(f"| {name} | " + " | ".join(ent) + " |") | |
| lines.append("") | |
| return lines, P | |
| def consistency(P_indep, seeds): | |
| """indep's value_b must agree across every *_vs_indep pair on the vehicle cells (identical rows) — else the pairs were not computed on the same rows.""" | |
| notes = [] | |
| for regime in ("manual", "engaged"): | |
| for _, c in VEH: | |
| vals = {} | |
| for s, df in P_indep.items(): | |
| g = cell_rows(df, regime, c, "pr_auc") | |
| if len(g): | |
| vals[s] = g.value_b.astype(float).to_numpy() | |
| if len(vals) >= 2: | |
| arr = list(vals.values()) | |
| n = min(len(x) for x in arr) | |
| spread = max(float(np.abs(x[:n] - arr[0][:n]).max()) for x in arr) | |
| if spread > 1e-6: | |
| notes.append(f"{regime} {c}: indep value_b differs across pairs by up to {spread:.2e} (row sets differ?)") | |
| return notes | |
| def reading(P_indep, P_allminus, seeds): | |
| """the pre-registered consequence table, applied mechanically.""" | |
| out = ["### Consequence-table reading (automatic; pre-registered rules of docs/decisions.md 2026-09-16T06:46:35Z)", ""] | |
| # (1) does `none` capture the bulk of the steer-phase / gas gains? | |
| out += ["**(1) `none` vs the connections (steer_phase / gas gains).** Rule: if `none` captures the bulk of the steer-phase / gas gains, the contribution is " | |
| "rewritten as 'independent pretraining + preserved branch predictions' and the connections are credited only with the cells where `allminus − none` is significant.", "", | |
| "| regime | cell | Δ allminus−indep (verdict) | Δ none−indep (verdict) | none share of gain | Δ none−allminus (verdict; WORSE = connections credited) |", "|---|---|---|---|---|---|"] | |
| for regime in ("manual", "engaged"): | |
| for nm, c in VEH: | |
| ga = cell_rows(P_indep.get("allminus", pd.DataFrame()), regime, c, "pr_auc") | |
| gn = cell_rows(P_indep.get("none", pd.DataFrame()), regime, c, "pr_auc") | |
| gna = cell_rows(P_allminus.get("none", pd.DataFrame()), regime, c, "pr_auc") | |
| da = ga.delta.astype(float).mean() if len(ga) else np.nan | |
| dn = gn.delta.astype(float).mean() if len(gn) else np.nan | |
| share = (dn / da) if (np.isfinite(da) and abs(da) > 1e-6 and np.isfinite(dn)) else np.nan | |
| va = RJ.verdict(ga)["verdict"] if len(ga) else "—" | |
| vn = RJ.verdict(gn)["verdict"] if len(gn) else "—" | |
| vna = RJ.verdict(gna)["verdict"] if len(gna) else "—" | |
| dna = gna.delta.astype(float).mean() if len(gna) else np.nan | |
| out.append(f"| {regime} | {nm} | {da:+.4f} ({va}) | {dn:+.4f} ({vn}) | {share:.2f} | {dna:+.4f} ({vna}) |" if np.isfinite(da) else f"| {regime} | {nm} | — | — | — | — |") | |
| out.append("") | |
| # (2) env2veh alone on the engaged steer-phase gain | |
| out += ["**(2) Road stream alone (env2veh = V+E) on the engaged steer-phase gain.** Rule: if `env2veh` alone reproduces the engaged steer-phase gain, the road stream is credited.", ""] | |
| for s, label in (("env2veh", "V+E"), ("drv2veh", "V+U")): | |
| gi = cell_rows(P_indep.get(s, pd.DataFrame()), "engaged", "veh_onset|steer_phase_on|3s", "pr_auc") | |
| gm = cell_rows(P_allminus.get(s, pd.DataFrame()), "engaged", "veh_onset|steer_phase_on|3s", "pr_auc") | |
| ga = cell_rows(P_indep.get("allminus", pd.DataFrame()), "engaged", "veh_onset|steer_phase_on|3s", "pr_auc") | |
| if len(gi): | |
| out.append(f"- {label} − indep: {fmt_delta(gi)}; {label} − allminus: {fmt_delta(gm) if len(gm) else '—'}; allminus − indep: {fmt_delta(ga) if len(ga) else '—'}") | |
| else: | |
| out.append(f"- {label}: no rows yet") | |
| out.append("") | |
| # (3) MTL vs plain summation | |
| out += ["**(3) MTL vs plain summation on the own cells** (veh / drv / demand onset PR-AUC@3 s; rule: significantly better on ANY own cell → reported as such and adopted for the scratch comparison).", "", | |
| "| MTL arm | vs plain sum | own cells BEATS | own cells WORSE | own cells NOT_WORSE / INCONCLUSIVE |", "|---|---|---|---|---|"] | |
| for s, base in PLAIN_SUM.items(): | |
| df = pair(s, base, seeds) | |
| if not len(df): | |
| out.append(f"| {s} | {base} | no rows yet | | |") | |
| continue | |
| beats, worse, other = [], [], 0 | |
| for regime in ("manual", "engaged"): | |
| for c in sorted(RJ.OWN): | |
| g = cell_rows(df, regime, c, "pr_auc") | |
| if not len(g): | |
| continue | |
| v = RJ.verdict(g)["verdict"] | |
| (beats if v == "BEATS" else worse if v == "WORSE" else []).append(f"{regime}/{c.split('|')[1]} ({g.delta.astype(float).mean():+.4f})") | |
| other += v not in ("BEATS", "WORSE") | |
| out.append(f"| {s} | {base} | {', '.join(beats) or 'none'} | {', '.join(worse) or 'none'} | {other} |") | |
| out.append("") | |
| return out | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--seeds", default="0,1,2") | |
| ap.add_argument("--out", default=str(CWM3 / "results" / "tables" / "modality_ablation.md")) | |
| a = ap.parse_args() | |
| seeds = [int(s) for s in a.seeds.split(",")] | |
| stamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) | |
| lines = [f"# Modality / control ablation of the vehicle-onset cells — WP3 R2 reviewer controls (generated {stamp}; eval/report_modality_table.py)", "", | |
| "Pre-registered 2026-09-16T06:46:35Z (docs/decisions.md). All systems on the FINAL bases (pack v2, causal targets v2, `V0_can4s_s<k>_stats2 / " | |
| "U0_kin_can_noK_s<k>_kcv2_clip8_ln / E0_pooled_P_s<k>_v2`), recipe verbatim, seeds " + ",".join(map(str, seeds)) + ", test split, both regimes. " | |
| "Source `results/paired_compare.csv`, tags `finalc_s<k>_<A>_vs_<B>` (eval/paired_compare_joint.py: identical rows, device-cluster bootstrap n_boot 1000, Δ = A − B). " | |
| "Verdicts: kill_checks.beats (≥ 2/3 seed CIs excluding 0, same sign, |mean Δ| > seed sd); paired CIs are the primary evidence, seed counts descriptive. " | |
| f"Acceptable-degradation margins: onset PR-AUC {MARGIN_PR:+.3f}, hazard NLL {MARGIN_NLL:+.2f} nats ('no significant drop' ≠ 'not worse').", "", | |
| "Systems: V = indep (assembled independent branches, no training), V+E = env2veh (road→vehicle only), V+U = drv2veh (driver→vehicle only), " | |
| "all = all_minus_road2drv (env2veh + drv2veh, the main model), none (same joint fine-tuning, NO interaction module), naive (pretrained trunks + " | |
| "default-init fusion MLP), naive_fresh (fusion trained from scratch, all trunks random) and its MTL arms (train/mtl.py: UW = Kendall 2018, FAMO = Liu 2023, " | |
| "PCGrad = Yu 2020 on the shared parameters), all + PCGrad. Cells: onset PR-AUC@3 s of manual / engaged brake, gas, steer_phase and veh_any " | |
| "(higher better); cost cells: hazard NLL of the vehicle and driver chains (lower better).", ""] | |
| t1, P_indep = table(seeds, "indep", VEH, "pr_auc", False, "Table 1 — vehicle onset PR-AUC@3 s: A̅ ± sd over seeds, paired Δ vs V (indep) per seed [CI], verdict") | |
| t2, P_allminus = table(seeds, "allminus", VEH, "pr_auc", False, "Table 2 — the same cells, paired Δ vs all (allminus, the main model)") | |
| t3, _ = table(seeds, "indep", COST, "nll", True, f"Table 3 — hazard-NLL cost cells (lower better; Δ̄ > {MARGIN_NLL:+.2f} nats exceeds the pre-registered margin), paired Δ vs V (indep)") | |
| t4, _ = table(seeds, "allminus", COST, "nll", True, "Table 4 — hazard-NLL cost cells, paired Δ vs all (allminus)") | |
| notes = consistency(P_indep, seeds) | |
| lines += t1 + t2 + t3 + t4 | |
| lines += ["### Row-set consistency check", ""] + ([f"- {n}" for n in notes] or ["- indep's paired values agree across every *_vs_indep pair on the vehicle cells (same rows)."]) + [""] | |
| lines += reading(P_indep, P_allminus, seeds) | |
| # margin flags: PR-AUC drops beyond -0.005 on the vehicle cells vs indep | |
| flags = [] | |
| for name, s in SYSTEMS: | |
| df = P_indep.get(s) | |
| if df is None or not len(df): | |
| continue | |
| for regime in ("manual", "engaged"): | |
| for nm, c in VEH: | |
| g = cell_rows(df, regime, c, "pr_auc") | |
| if len(g) and g.delta.astype(float).mean() < MARGIN_PR: | |
| flags.append(f"{name}: {regime} {nm} Δ̄ = {g.delta.astype(float).mean():+.4f} (below the {MARGIN_PR:+.3f} margin; verdict {RJ.verdict(g)['verdict']})") | |
| for nm, c in COST[:3]: | |
| g = cell_rows(df, regime, c, "nll") | |
| if len(g) and g.delta.astype(float).mean() > MARGIN_NLL: | |
| flags.append(f"{name}: {regime} {nm} Δ̄ = {g.delta.astype(float).mean():+.4f} nats (above the {MARGIN_NLL:+.2f} margin; verdict {RJ.verdict(g, True)['verdict']})") | |
| lines += ["### Margin flags vs indep (vehicle cells)", ""] + ([f"- {f}" for f in flags] or ["- none of the systems exceeds a pre-registered degradation margin on the vehicle cells vs indep"]) + [""] | |
| out = Path(a.out) | |
| out.parent.mkdir(parents=True, exist_ok=True) | |
| out.write_text("\n".join(lines) + "\n") | |
| print("\n".join(lines[-40:])) | |
| print(f"\nwritten {out}") | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 14.7 kB
- Xet hash:
- ed706ebf558f449c98eae4c5be89bb41d77cfa8065f8b5dfdb738702ba28755c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.