AsianPlayer/TriDrive / code /eval /report_modality_table.py
AsianPlayer's picture
download
raw
14.7 kB
"""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.