import re, matplotlib; matplotlib.use('Agg'); import matplotlib.pyplot as plt def parse(p): s,c,e=[],[],[] for ln in open(p): m=re.search(r'step\s+(\d+)/\d+ \| val CE ([\d.]+) ema=([\d.]+)', ln) if m: s.append(int(m.group(1))); c.append(float(m.group(2))); e.append(float(m.group(3))) return s,c,e fz=parse('ep_run/runs/ep_resreg_warm.log'); ad=parse('ep_run/runs/ep_rr_ajr.log') fig,ax=plt.subplots(figsize=(11,5.5),dpi=140) for (s,c,e),col,lab in [(fz,'#4363d8','frozen jr=0.1'),(ad,'#e6194B','adaptive jacreg (jr_max=16)')]: ax.plot(s,c,color=col,lw=0.7,alpha=0.25) ax.plot(s,e,color=col,lw=2.3,label=lab+f' (last ema {e[-1]:.4f})') ax.axhline(2.0,color='gray',ls='--',lw=1,alpha=0.7,label='val CE = 2.0') ax.set_xlabel('training step'); ax.set_ylabel('val CE'); ax.set_ylim(1.92,2.6) ax.set_title('Frozen jr vs adaptive jacreg — C512 EP, same s2000 warm-start (only jr differs)\nbold = ema, faint = raw per-log val CE', fontsize=10.5) ax.legend(fontsize=9.5, loc='upper right'); ax.grid(alpha=0.2) fig.tight_layout(); fig.savefig('frozen_vs_adaptive.png',dpi=140,bbox_inches='tight') print(f"frozen: {len(fz[0])} pts, steps {fz[0][0]}-{fz[0][-1]}, best ema {min(fz[2]):.4f}") print(f"adaptive: {len(ad[0])} pts, steps {ad[0][0]}-{ad[0][-1]}, best ema {min(ad[2]):.4f}") print("saved")