File size: 1,563 Bytes
7ed86c3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | """Per-fold checkpoint selection on dev CER, using numbers already in the training log.
The v3 runs selected best.pt on bits_per_char, but bpc and dev CER decorrelate late in
training (r~0.82) -- bpc bottoms out and rises while CER keeps improving. So best.pt can
be ~0.02 dev CER worse than the run's end state. Both best.pt and last.pt are legitimate
checkpoints; choosing between them on DEV CER is standard model selection (dev is exactly
what selection is for) and costs no GPU, because every eval's dev CER is in the log.
python3 analysis/pick_ckpt.py # report
python3 analysis/pick_ckpt.py --write # write chosen_ckpt.txt into each run dir
"""
import glob, json, os, re, sys
I=os.path.expandvars("$STOICHEIA_DATA/insc_data/runs")
write="--write" in sys.argv
print(f"{'run':<28}{'best.pt cer':>12}{'last.pt cer':>12} choice")
for d in sorted(glob.glob(f"{I}/whole_v*")):
ev=os.path.join(d,"eval.jsonl")
if not os.path.exists(ev): continue
rows=[json.loads(l) for l in open(ev)]
if not rows: continue
# best.pt = argmin bpc (how these runs were selected); last.pt = final eval
bb=min(rows,key=lambda r:r["bits_per_char"])
last=rows[-1]
pick="best.pt" if bb["dev_cer"]<=last["dev_cer"] else "last.pt"
gain=abs(bb["dev_cer"]-last["dev_cer"])
flag="" if pick=="best.pt" else f" (+{gain:.4f} CER recovered)"
print(f"{os.path.basename(d):<28}{bb['dev_cer']:>12.4f}{last['dev_cer']:>12.4f} {pick}{flag}")
if write:
open(os.path.join(d,"chosen_ckpt.txt"),"w").write(pick+"\n")
|