import%20marimo%0A%0A__generated_with%20%3D%20%220.23.9%22%0Aapp%20%3D%20marimo.App(%0A%20%20%20%20width%3D%22medium%22%2C%0A%20%20%20%20app_title%3D%22Experiment%202.9.4%3A%20closed-loop%20regularizer%20weights%22%2C%0A%20%20%20%20css_file%3D%22..%2F..%2Freport.css%22%2C%0A%20%20%20%20auto_download%3D%5B%22html%22%5D%2C%0A)%0A%0Awith%20app.setup(hide_code%3DTrue)%3A%0A%20%20%20%20import%20marimo%20as%20mo%20%20%23%20noqa%3A%20F401%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20from%20sca.colorcube%20import%20TRAJ_STRIDE%2C%20classify%2C%20load_results%0A%20%20%20%20from%20mini.reports%20import%20report_bundle%2C%20use_publisher%0A%20%20%20%20from%20mini.vis%20import%20light_dark%2C%20themed%0A%0A%20%20%20%20use_publisher(report_bundle(__file__))%0A%0A%20%20%20%20%23%20Store%20refs%20published%20by%20experiment.py%20(kept%20in%20sync%20by%20hand).%0A%20%20%20%20METRICS_REF%20%3D%20%22reports%2Fex-2.9.4%2Fmetrics%22%0A%20%20%20%20TRAJS_REF%20%3D%20%22reports%2Fex-2.9.4%2Ftrajectories%22%0A%0A%20%20%20%20LAM_CAP%20%3D%200.15%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Experiment%202.9.4%3A%20closed-loop%20regularizer%20weights%0A%0A%20%20%20%20%5BEx-2.9.3%5D(..%2Fex-2.9.3%2Freport.py)%20traced%20anchoring%20failures%20to%20an%0A%20%20%20%20instability%20late%20in%20training.%20The%20anchored%20solution%20is%20metastable%0A%20%20%20%20during%20the%20high%20learning-rate%20plateau%3A%20the%20regularizers%20hold%20it%20in%20place%2C%0A%20%20%20%20and%20the%20timed%20anneal%20takes%20that%20support%20away%20while%20the%20optimizer%20is%20still%0A%20%20%20%20hot.%20We%20fixed%20it%20statically%2C%20by%20halving%20the%20peak%20learning%20rate.%20That%20works%2C%0A%20%20%20%20but%20it%20sets%20the%20timing%20by%20hand.%0A%0A%20%20%20%20This%20experiment%20lets%20the%20regularizer%20weights%20respond%20to%20the%20training%0A%20%20%20%20signals%2C%20so%20a%20weight%20climbs%20while%20its%20constraint%20is%20being%20violated%20and%0A%20%20%20%20settles%20back%20down%20once%20the%20constraint%20is%20met.%0A%0A%20%20%20%20The%20mechanism%20is%20a%20small%20feedback%20controller%20(dual%20ascent%20with%0A%20%20%20%20hysteresis%5B%5Edual%5D)%20acting%20on%20the%20anchor%20and%20anti-anchor%20weights.%20It%20reads%0A%20%20%20%20only%20signals%20available%20during%20training%2C%20with%20no%20privileged%0A%20%20%20%20ground-truth%20probe%3A%0A%0A%20%20%20%20-%20Each%20controlled%20term%20keeps%20a%20running%20average%20of%20its%20own%20raw%20value%20(an%0A%20%20%20%20%20%20EMA%5B%5Eema%5D).%20The%20anchor%20term%20is%20measured%20on%20labeled%20samples%20only%2C%20so%20its%0A%20%20%20%20%20%20average%20updates%20on%20the%20~6%25%20of%20batches%20that%20carry%20a%20label.%0A%20%20%20%20-%20The%20weight%20%CE%BB%20rises%20while%20its%20average%20sits%20above%20an%20engage%20threshold%2C%0A%20%20%20%20%20%20decays%20(5%C3%97%20faster)%20once%20it%20falls%20below%20a%20release%20threshold%2C%20and%20holds%0A%20%20%20%20%20%20steady%20in%20the%20band%20between%20the%20two.%20That%20keeps%20the%20ordinary%0A%20%20%20%20%20%20early%20transient%20from%20winding%20the%20weight%20up%2C%20and%20lets%20a%20healthy%20run's%20%CE%BB%0A%20%20%20%20%20%20return%20to%20zero.%0A%20%20%20%20-%20%CE%BB%20is%20capped%20at%200.15%2C%20close%20to%20the%20dopesheet's%20constant%200.1%20from%20earlier%0A%20%20%20%20%20%20experiments.%0A%0A%20%20%20%20The%20anti-subspace%20weight%20is%20left%20uncontrolled.%20Its%20raw%20value%20has%20a%20floor%0A%20%20%20%20set%20by%20the%20red%20samples%20themselves%2C%20and%20a%20sensor%20that%20cannot%20see%20labels%20has%0A%20%20%20%20no%20way%20to%20tell%20that%20floor%20apart%20from%20leakage.%20So%20we%20hold%20it%20at%20its%20small%0A%20%20%20%20late%20value%20instead%20of%20annealing%20it.%20Learning%20rate%20and%20%60separate%60%20follow%0A%20%20%20%20the%20dopesheet%20as%20before.%0A%0A%20%20%20%20We%20ran%20ten%20conditions%2C%2032%20seeds%20each%2C%20scored%20by%20ex-2.9.2's%20%60redirect%60%0A%20%20%20%20intervention%3A%20%7Bstatic%20timed-anneal%2C%20controller%7D%20%C3%97%20peak%20LR%20%7B0.10%20risky%2C%0A%20%20%20%200.05%20safe%7D%20with%20the%20fallback%20term%3B%20the%20same%20pair%20with%20the%20fallback%20term%0A%20%20%20%20removed%2C%20at%200.10%2C%20since%20ex-2.9.3%20showed%20that%20is%20where%20catastrophic%20failures%0A%20%20%20%20actually%20appear%3B%20and%20a%20sensitivity%20grid%20over%20the%20controller's%20own%0A%20%20%20%20parameters%20(targets%20%C3%970.75%2C%20%C3%971.5%3B%20gains%20%C3%970.5%2C%20%C3%972).%20The%20experiment%20is%0A%20%20%20%20%5B%60experiment.py%60%5D(.%2Fexperiment.py)%3A%0A%0A%20%20%20%20%60%60%60bash%0A%20%20%20%20bin%2Fmini%20run%20docs%2Fm1%2Fex-2.9.4%2Fexperiment.py%20--app%20modal%20--max-containers%2016%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20%5B%5Edual%5D%3A%20Dual%20ascent%20enforces%20a%20constraint%20by%20putting%20a%20price%20on%20it.%20While%0A%20%20%20%20the%20constraint%20is%20being%20violated%20the%20price%20(here%20the%20weight%20%CE%BB)%20rises%2C%20which%0A%20%20%20%20pushes%20the%20optimizer%20to%20satisfy%20it%3B%20once%20it%20is%20met%2C%20the%20price%20relaxes.%0A%20%20%20%20Hysteresis%20means%20the%20price%20uses%20two%20thresholds%20with%20a%20gap%20between%20them%0A%20%20%20%20rather%20than%20one%2C%20the%20way%20a%20thermostat%20lets%20the%20room%20drift%20a%20little%20before%0A%20%20%20%20switching%2C%20so%20the%20weight%20doesn't%20chatter%20on%20and%20off.%0A%0A%20%20%20%20%5B%5Eema%5D%3A%20Exponential%20moving%20average%3A%20a%20running%20average%20that%20weights%20recent%0A%20%20%20%20samples%20more%20than%20old%20ones%2C%20so%20it%20follows%20a%20changing%20signal%20without%20keeping%0A%20%20%20%20its%20whole%20history.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20loaded%20%3D%20load_results(METRICS_REF%2C%20TRAJS_REF)%0A%20%20%20%20return%20(loaded%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(loaded)%3A%0A%20%20%20%20mo.stop(%0A%20%20%20%20%20%20%20%20loaded%20is%20None%2C%0A%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22No%20results%20yet%20%E2%80%94%20run%20the%20experiment%20(it%20publishes%20metrics%20to%20the%20store%20on%20completion)%3A%5Cn%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%60%60%60bash%5Cnbin%2Fmini%20run%20docs%2Fm1%2Fex-2.9.4%2Fexperiment.py%20--app%20modal%20--max-containers%2016%5Cn%60%60%60%22%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20)%0A%20%20%20%20metrics%2C%20trajs%20%3D%20loaded%0A%0A%20%20%20%20def%20cond(name%3A%20str%2C%20peak_lr%3A%20float%20%7C%20None%20%3D%20None)%20-%3E%20list%5Bdict%5D%3A%0A%20%20%20%20%20%20%20%20return%20%5Br%20for%20r%20in%20metrics%20if%20r%5B%22cond%22%5D%20%3D%3D%20name%20and%20(peak_lr%20is%20None%20or%20r%5B%22peak_lr%22%5D%20%3D%3D%20peak_lr)%5D%0A%0A%20%20%20%20def%20traj(r%3A%20dict%2C%20key%3A%20str)%20-%3E%20np.ndarray%3A%0A%20%20%20%20%20%20%20%20return%20trajs%5Bf%22%7Br%5B'run'%5D%3A03d%7D_%7Bkey%7D%22%5D%0A%0A%20%20%20%20def%20rd(rs%3A%20list%5Bdict%5D)%20-%3E%20np.ndarray%3A%0A%20%20%20%20%20%20%20%20return%20np.array(%5Br%5B%22interventions%22%5D%5B%22redirect%22%5D%5B%22score%22%5D%20for%20r%20in%20rs%5D)%0A%0A%20%20%20%20def%20n_cat(rs%3A%20list%5Bdict%5D)%20-%3E%20int%3A%0A%20%20%20%20%20%20%20%20return%20sum(classify(r)%20%3D%3D%20%22catastrophic%22%20for%20r%20in%20rs)%0A%0A%20%20%20%20steps%20%3D%20np.arange(len(traj(metrics%5B0%5D%2C%20%22z0_red%22)))%20*%20TRAJ_STRIDE%0A%20%20%20%20return%20cond%2C%20n_cat%2C%20rd%2C%20steps%2C%20traj%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(cond%2C%20n_cat%2C%20rd)%3A%0A%20%20%20%20_sn%2C%20_cn%20%3D%20cond(%22static-nofb%22)%2C%20cond(%22ctrl-nofb%22)%0A%20%20%20%20_s_bad%20%3D%20sorted(r%5B%22seed%22%5D%20for%20r%20in%20_sn%20if%20classify(r)%20%3D%3D%20%22catastrophic%22)%0A%20%20%20%20_c_bad%20%3D%20sorted(r%5B%22seed%22%5D%20for%20r%20in%20_cn%20if%20classify(r)%20%3D%3D%20%22catastrophic%22)%0A%20%20%20%20_rescued%20%3D%20%5Bs%20for%20s%20in%20_s_bad%20if%20classify(next(r%20for%20r%20in%20_cn%20if%20r%5B%22seed%22%5D%20%3D%3D%20s))%20%3D%3D%20%22clean%22%5D%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20**%7Bsum(1%20for%20_%20in%20(r%20for%20r%20in%20cond(%22static%22)%20%2B%20cond(%22ctrl%22)))%7D%20%2B%0A%20%20%20%20%7Blen(_sn)%20%2B%20len(_cn)%7D%20%2B%20128%20runs%20completed**%20across%20ten%20conditions.%20This%20is%20a%0A%20%20%20%20clear%20negative%20result.%20Without%20the%20fallback%20term%2C%20the%20feedback%20loop%20does%0A%20%20%20%20what%20it%20was%20designed%20to%20do%20on%20the%20seeds%20the%20static%20schedule%20loses%3A%20its%20%7Bn_cat(_sn)%7D%0A%20%20%20%20catastrophic%20seeds%20(%7B%22%2C%20%22.join(map(str%2C%20_s_bad))%7D)%20train%20cleanly%20under%20control%0A%20%20%20%20(redirect%20scores%0A%20%20%20%20%7B%22%2C%20%22.join(f%22%7Brd(%5Bnext(r%20for%20r%20in%20_cn%20if%20r%5B'seed'%5D%20%3D%3D%20s)%5D)%5B0%5D%3A.2f%7D%22%20for%20s%20in%20_rescued)%7D).%0A%20%20%20%20But%20the%20controller%20introduces%20%7Bn_cat(_cn)%7D%20new%20failures%20on%20other%0A%20%20%20%20seeds%20(%7B%22%2C%20%22.join(map(str%2C%20_c_bad))%7D)%2C%20so%20the%20overall%20failure%20rate%20does%20not%20improve.%0A%20%20%20%20With%20the%20fallback%20term%20on%20(the%20recipe%20we%20adopted)%2C%20no%20condition%20has%20a%20single%0A%20%20%20%20catastrophic%20failure%2C%20so%20there%20is%20nothing%20left%20for%20the%20controller%20to%20rescue.%0A%20%20%20%20So%20we%20will%20probably%20keep%20the%20static%20schedule.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20The%20fallback-free%20test%3A%20rescues%20and%20new%20failures%0A%0A%20%20%20%20Ex-2.9.3%20showed%20that%20catastrophic%20failures%20only%20appear%20when%20there's%20no%0A%20%20%20%20fallback%20term%20and%20a%20high%20LR.%20That%20makes%20it%20the%20fair%20place%20to%20test%20a%20rescue%0A%20%20%20%20mechanism.%20The%20charts%20below%20show%20anchor%20progress%20and%20leakage%20for%20all%2032%0A%20%20%20%20seeds%20under%20each%20variant.%0A%0A%20%20%20%20The%20static%20schedule%20failures%20are%20in%20the%20anchor%20panel%3A%20the%20anchor%20forms%2C%20then%0A%20%20%20%20falls%20away%20late%20in%20training.%20With%20the%20controller%2C%20the%20same%20panel%20shows%20the%0A%20%20%20%20feedback%20at%20work%2C%20with%20runs%20dipping%20hard%20in%20the%20middle%20of%20the%20plateau%20and%0A%20%20%20%20getting%20pulled%20back%20up%20to%201.%0A%0A%20%20%20%20The%20response%20has%20a%20cost%2C%20though%2C%20and%20it%20doesn't%20always%20succeed.%20The%20leak%0A%20%20%20%20panel%20shows%20runs%20where%20a%20sustained%20penalty%20drags%20pinkish%20labeled%20colors%0A%20%20%20%20onto%20the%20axis%20until%20the%20geometry%20is%20spoiled%2C%20and%20one%20run%20loses%20the%20anchor%0A%20%20%20%20outright%20with%20its%20weight%20pinned%20at%20the%20cap.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(cond%2C%20steps%2C%20traj)%3A%0A%20%20%20%20_cells%20%3D%20%5B(%22static-nofb%22%2C%20%22static%20(timed%20anneal)%22)%2C%20(%22ctrl-nofb%22%2C%20%22controller%22)%5D%0A%20%20%20%20_ncat%20%3D%20%7Bc%3A%20sum(classify(r)%20%3D%3D%20%22catastrophic%22%20for%20r%20in%20cond(c))%20for%20c%2C%20_%20in%20_cells%7D%0A%0A%20%20%20%20%40themed(%0A%20%20%20%20%20%20%20%20name%3D%22nofb-trajectories%22%2C%0A%20%20%20%20%20%20%20%20alt_text%3Df%22%22%22%0A%20%20%20%20%20%20%20%20Four%20charts%20in%20a%20two-by-two%20grid.%20Rows%20are%20the%20static%20schedule%20and%20the%20controller%2C%0A%20%20%20%20%20%20%20%20both%20without%20the%20fallback%20term%3B%20columns%20are%20anchor%20progress%20and%20leakage%2C%2032%20seeds%0A%20%20%20%20%20%20%20%20each%2C%20with%20catastrophic%20runs%20drawn%20in%20color%20over%20gray%20healthy%20ones.%20Top%20left%2C%20static%0A%20%20%20%20%20%20%20%20anchor%20progress%3A%20all%20runs%20reach%201%20by%20step%20750%3B%20of%20the%20%7B_ncat%5B%22static-nofb%22%5D%7D%20colored%0A%20%20%20%20%20%20%20%20runs%2C%20one%20falls%20away%20late%20to%20about%200.6%20while%20the%20other%20keeps%20its%20anchor%2C%20failing%0A%20%20%20%20%20%20%20%20instead%20by%20reconstruction%20collapse.%20Top%20right%2C%20static%20leak%3A%20the%20colored%20runs%20climb%20to%0A%20%20%20%20%20%20%20%20%7Bmax(r%5B%22leak%22%5D%20for%20r%20in%20cond(%22static-nofb%22))%3A.2f%7D.%20Bottom%20left%2C%20controller%20anchor%0A%20%20%20%20%20%20%20%20progress%3A%20colored%20runs%20dip%20sharply%20in%20the%20middle%20of%20the%20plateau%2C%20one%20to%20about%20minus%0A%20%20%20%20%20%20%20%200.25%2C%20and%20the%20feedback%20pulls%20most%20of%20them%20back%20to%201%3B%20one%20ends%20near%200.15%2C%20not%0A%20%20%20%20%20%20%20%20recovered.%20Bottom%20right%2C%20controller%20leak%3A%20%7B_ncat%5B%22ctrl-nofb%22%5D%7D%20colored%20runs%20blow%20up%2C%0A%20%20%20%20%20%20%20%20the%20worst%20reaching%20%7Bmax(r%5B%22leak%22%5D%20for%20r%20in%20cond(%22ctrl-nofb%22))%3A.2f%7D%2C%20from%0A%20%20%20%20%20%20%20%20over-anchoring%20under%20a%20sustained%20maximum%20penalty.%0A%20%20%20%20%20%20%20%20%22%22%22%2C%0A%20%20%20%20)%0A%20%20%20%20def%20_plot()%20-%3E%20plt.Figure%3A%0A%20%20%20%20%20%20%20%20fig%2C%20axes%20%3D%20plt.subplots(2%2C%202%2C%20figsize%3D(9.5%2C%206.5)%2C%20sharex%3DTrue%2C%20sharey%3D%22col%22)%0A%20%20%20%20%20%20%20%20gray%20%3D%20light_dark(%22%239aa5b155%22%2C%20%22%236b768655%22)%0A%20%20%20%20%20%20%20%20hues%20%3D%20%5B%22%23d55e00%22%2C%20%22%230072b2%22%2C%20%22%23009e73%22%2C%20%22%23cc79a7%22%2C%20%22%23e69f00%22%5D%0A%20%20%20%20%20%20%20%20for%20row%2C%20(c%2C%20label)%20in%20enumerate(_cells)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20rs%20%3D%20cond(c)%0A%20%20%20%20%20%20%20%20%20%20%20%20bad%20%3D%20sorted((r%20for%20r%20in%20rs%20if%20classify(r)%20%3D%3D%20%22catastrophic%22)%2C%20key%3Dlambda%20r%3A%20r%5B%22seed%22%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20col%2C%20key%20in%20enumerate((%22z0_red%22%2C%20%22leak%22))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax%20%3D%20axes%5Brow%2C%20col%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20r%20in%20rs%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20classify(r)%20!%3D%20%22catastrophic%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.plot(steps%2C%20traj(r%2C%20key)%2C%20color%3Dgray%2C%20lw%3D1)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20hue%2C%20r%20in%20zip(hues%2C%20bad%2C%20strict%3DFalse)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.plot(steps%2C%20traj(r%2C%20key)%2C%20color%3Dhue%2C%20lw%3D1.6%2C%20label%3Df%22seed%20%7Br%5B'seed'%5D%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.axvspan(750%2C%201500%2C%20color%3Dlight_dark(%22%231a5f8a%22%2C%20%22%236ab0d4%22)%2C%20alpha%3D0.07%2C%20lw%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.grid(alpha%3D0.3)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.legend(loc%3D%22center%20left%22%2C%20fontsize%3D8)%0A%20%20%20%20%20%20%20%20%20%20%20%20axes%5Brow%2C%200%5D.set_ylabel(f%22%7Blabel%7D%5Cnz%E2%82%80(pure%20red)%22)%0A%20%20%20%20%20%20%20%20axes%5B0%2C%201%5D.set_ylabel(%22leak%20(mean%20%7Cz%E2%82%80%7C%2C%20non-red)%22)%0A%20%20%20%20%20%20%20%20axes%5B1%2C%201%5D.set_ylabel(%22leak%20(mean%20%7Cz%E2%82%80%7C%2C%20non-red)%22)%0A%20%20%20%20%20%20%20%20axes%5B0%2C%200%5D.set_ylim(-1.05%2C%201.05)%0A%20%20%20%20%20%20%20%20axes%5B0%2C%201%5D.set_ylim(0%2C%200.9)%0A%20%20%20%20%20%20%20%20for%20ax%20in%20axes%5B1%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22step%22)%0A%20%20%20%20%20%20%20%20axes%5B0%2C%200%5D.set_title(%22Anchor%20progress%22)%0A%20%20%20%20%20%20%20%20axes%5B0%2C%201%5D.set_title(%22Leakage%22)%0A%20%20%20%20%20%20%20%20fig.suptitle(%22Without%20the%20fallback%20term%3A%20the%20controller%20keeps%20every%20anchor%2C%20but%20spoils%20other%20runs%22%2C%20y%3D0.99)%0A%20%20%20%20%20%20%20%20return%20fig%0A%0A%20%20%20%20mo.Html(_plot())%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(cond%2C%20traj)%3A%0A%20%20%20%20_cn%20%3D%20cond(%22ctrl-nofb%22)%0A%20%20%20%20_bad%20%3D%20%5Br%20for%20r%20in%20_cn%20if%20classify(r)%20%3D%3D%20%22catastrophic%22%5D%0A%20%20%20%20_sat_bad%20%3D%20sum(1%20for%20r%20in%20_bad%20if%20r%5B%22lam_anchor_mean%22%5D%20%3E%200.13)%0A%20%20%20%20_sat_ok%20%3D%20sum(1%20for%20r%20in%20_cn%20if%20classify(r)%20%3D%3D%20%22clean%22%20and%20r%5B%22lam_anchor_mean%22%5D%20%3E%200.13)%0A%20%20%20%20_n_ok%20%3D%20sum(1%20for%20r%20in%20_cn%20if%20classify(r)%20%3D%3D%20%22clean%22)%0A%20%20%20%20_r27%20%3D%20next(r%20for%20r%20in%20cond(%22static-nofb%22)%20if%20r%5B%22seed%22%5D%20%3D%3D%2027)%0A%20%20%20%20_c27%20%3D%20next(r%20for%20r%20in%20_cn%20if%20r%5B%22seed%22%5D%20%3D%3D%2027)%0A%20%20%20%20_drop%20%3D%20int(np.flatnonzero(traj(_r27%2C%20%22z0_red%22)%20%3C%200.7)%5B-1%5D)%20*%20TRAJ_STRIDE%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20The%20weight's%20trajectory%20separates%20the%20two%20outcomes.%20In%20the%20rescues%2C%20%CE%BB%20engages%20while%0A%20%20%20%20the%20anchor%20is%20forming%2C%20then%20releases%20once%20the%20constraint%20is%20met.%20On%20seed%2027%20(the%20static%0A%20%20%20%20schedule's%20worst%2C%20still%20below%20z%E2%82%80%20%3D%200.7%20at%20step%20%7B_drop%7D)%2C%20the%20controlled%20run%20holds%20z%E2%82%80%0A%20%20%20%20near%201%20through%20the%20plateau%2C%20with%20%CE%BB%20decaying%20to%20%7B_c27%5B%22lam_anchor_end%22%5D%3A.2f%7D.%20In%20the%0A%20%20%20%20failures%20the%20labeled%20anchor%20EMA%20never%20reaches%20its%20target%2C%20so%20%CE%BB%20climbs%20to%20the%20%7BLAM_CAP%7D%0A%20%20%20%20cap%20and%20stays%20there%3A%20%7B_sat_bad%7D%20of%20%7Blen(_bad)%7D%20catastrophic%20runs%20had%20mean%20%CE%BB%20%3E%200.13%2C%0A%20%20%20%20versus%20%7B_sat_ok%7D%20of%20%7B_n_ok%7D%20clean%20ones.%0A%0A%20%20%20%20This%20is%20a%20problem%20with%20the%20sensor.%20The%20anchor%20term%20is%20measured%20on%20noisy%0A%20%20%20%20labels%2C%20and%20a%20pinkish%20color%20placed%20off%20the%20axis%20on%20purpose%20looks%20the%20same%2C%0A%20%20%20%20to%20that%20measurement%2C%20as%20a%20red%20that%20has%20drifted%20off%20it.%20On%20most%20seeds%20the%0A%20%20%20%20average%20settles%20below%20target%20anyway%3B%20on%20some%20it%20can't%2C%20and%20overcorrects.%20One%0A%20%20%20%20run%20lost%20its%20anchor%20even%20with%20its%20weight%20pinned%20at%20maximum.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20With%20the%20fallback%20term%0A%0A%20%20%20%20The%20fallback%20term%20from%20ex-2.9.2%20turns%20out%20to%20prevent%20every%20catastrophic%0A%20%20%20%20failure%20on%20its%20own%3A%20none%20in%20448%20fallback-trained%20runs%20across%20this%0A%20%20%20%20experiment%20and%20ex-2.9.3%2C%20against%207%20of%20224%20without%20it.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(cond%2C%20n_cat%2C%20rd)%3A%0A%20%20%20%20_cells%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22static%22%2C%200.10%2C%20%22static%5Cn0.10%22)%2C%0A%20%20%20%20%20%20%20%20(%22ctrl%22%2C%200.10%2C%20%22ctrl%5Cn0.10%22)%2C%0A%20%20%20%20%20%20%20%20(%22static%22%2C%200.05%2C%20%22static%5Cn0.05%22)%2C%0A%20%20%20%20%20%20%20%20(%22ctrl%22%2C%200.05%2C%20%22ctrl%5Cn0.05%22)%2C%0A%20%20%20%20%20%20%20%20(%22ctrl-tau0.75%22%2C%200.10%2C%20%22ctrl%5Cn%CF%84%C3%970.75%22)%2C%0A%20%20%20%20%20%20%20%20(%22ctrl-tau1.5%22%2C%200.10%2C%20%22ctrl%5Cn%CF%84%C3%971.5%22)%2C%0A%20%20%20%20%20%20%20%20(%22ctrl-eta0.5%22%2C%200.10%2C%20%22ctrl%5Cn%CE%B7%C3%970.5%22)%2C%0A%20%20%20%20%20%20%20%20(%22ctrl-eta2%22%2C%200.10%2C%20%22ctrl%5Cn%CE%B7%C3%972%22)%2C%0A%20%20%20%20%5D%0A%20%20%20%20_scores%20%3D%20%7Blbl%3A%20rd(cond(c%2C%20lr))%20for%20c%2C%20lr%2C%20lbl%20in%20_cells%7D%0A%20%20%20%20_leaks%20%3D%20%7Blbl%3A%20np.array(%5Br%5B%22leak%22%5D%20for%20r%20in%20cond(c%2C%20lr)%5D)%20for%20c%2C%20lr%2C%20lbl%20in%20_cells%7D%0A%20%20%20%20_ncats%20%3D%20%7Blbl%3A%20n_cat(cond(c%2C%20lr))%20for%20c%2C%20lr%2C%20lbl%20in%20_cells%7D%0A%0A%20%20%20%20%40themed(%0A%20%20%20%20%20%20%20%20name%3D%22fallback-cells%22%2C%0A%20%20%20%20%20%20%20%20alt_text%3Df%22%22%22%0A%20%20%20%20%20%20%20%20Two%20stacked%20strip%20plots%20over%20eight%20fallback-trained%20conditions%3A%20the%20static%20schedule%0A%20%20%20%20%20%20%20%20and%20the%20controller%20at%20peak%20LR%200.10%20and%200.05%2C%20then%20four%20controller%20variants%20at%200.10%0A%20%20%20%20%20%20%20%20with%20shifted%20targets%20(%C3%970.75%2C%20%C3%971.5)%20and%20gains%20(%C3%970.5%2C%20%C3%972).%20Top%3A%20redirect%20scores%2C%20with%0A%20%20%20%20%20%20%20%20medians%20all%20between%20%7Bmin(np.median(v)%20for%20v%20in%20_scores.values())%3A.2f%7D%20and%0A%20%20%20%20%20%20%20%20%7Bmax(np.median(v)%20for%20v%20in%20_scores.values())%3A.2f%7D%20and%20a%20few%20scattered%20outliers%20below%0A%20%20%20%20%20%20%20%200.5.%20Bottom%3A%20final%20leakage%20on%20a%20log%20scale%2C%20with%20a%20dashed%20line%20at%20the%200.1%20degraded%0A%20%20%20%20%20%20%20%20threshold%20and%20a%20dotted%20line%20at%20the%200.3%20catastrophic%20threshold%3B%20the%20number%20of%0A%20%20%20%20%20%20%20%20catastrophic%20runs%20is%20printed%20under%20each%20condition.%20The%20%CF%84%C3%970.75%2C%20%CE%B7%C3%970.5%2C%20and%20%CE%B7%C3%972%20variants%0A%20%20%20%20%20%20%20%20show%20%7B_ncats%5B%22ctrl%5Cn%CF%84%C3%970.75%22%5D%7D%2C%20%7B_ncats%5B%22ctrl%5Cn%CE%B7%C3%970.5%22%5D%7D%2C%20and%20%7B_ncats%5B%22ctrl%5Cn%CE%B7%C3%972%22%5D%7D%0A%20%20%20%20%20%20%20%20catastrophic%20runs%20with%20leak%20reaching%200.4%20to%200.8%3B%20every%20static%20condition%20shows%20zero.%0A%20%20%20%20%20%20%20%20%22%22%22%2C%0A%20%20%20%20)%0A%20%20%20%20def%20_plot()%20-%3E%20plt.Figure%3A%0A%20%20%20%20%20%20%20%20fig%2C%20axes%20%3D%20plt.subplots(2%2C%201%2C%20figsize%3D(9.5%2C%206.5)%2C%20sharex%3DTrue%2C%20height_ratios%3D%5B2%2C%201.6%5D)%0A%20%20%20%20%20%20%20%20rng%20%3D%20np.random.default_rng(0)%0A%20%20%20%20%20%20%20%20accent%2C%20gray%20%3D%20light_dark(%22%231a5f8a%22%2C%20%22%236ab0d4%22)%2C%20light_dark(%22%239aa5b1%22%2C%20%22%236b7686%22)%0A%20%20%20%20%20%20%20%20colors%20%3D%20%5Bgray%2C%20accent%2C%20gray%2C%20accent%2C%20accent%2C%20accent%2C%20accent%2C%20accent%5D%0A%20%20%20%20%20%20%20%20for%20ax%2C%20data%20in%20zip(axes%2C%20(_scores%2C%20_leaks)%2C%20strict%3DTrue)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20gi%2C%20(lbl%2C%20color)%20in%20enumerate(zip(_scores%2C%20colors%2C%20strict%3DTrue))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x0%20%3D%20gi%20%2B%20rng.uniform(-0.13%2C%200.13%2C%20len(data%5Blbl%5D))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.scatter(x0%2C%20data%5Blbl%5D%2C%20s%3D14%2C%20color%3Dcolor%2C%20alpha%3D0.75%2C%20lw%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ax.plot(%5Bgi%20-%200.22%2C%20gi%20%2B%200.22%5D%2C%20%5Bnp.median(data%5Blbl%5D)%5D%20*%202%2C%20color%3Dcolor%2C%20lw%3D2)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.grid(alpha%3D0.3%2C%20axis%3D%22y%22)%0A%20%20%20%20%20%20%20%20axes%5B0%5D.set(ylabel%3D%22score%20(R%C2%B2%2C%20redirect)%22%2C%20ylim%3D(0%2C%201.02))%0A%20%20%20%20%20%20%20%20ref%20%3D%20light_dark(%22%23000%22%2C%20%22%23fff%22)%0A%20%20%20%20%20%20%20%20axes%5B1%5D.axhline(0.1%2C%20ls%3D%22--%22%2C%20lw%3D1%2C%20color%3Dref%2C%20alpha%3D0.5)%0A%20%20%20%20%20%20%20%20axes%5B1%5D.axhline(0.3%2C%20ls%3D%22%3A%22%2C%20lw%3D1%2C%20color%3Dref%2C%20alpha%3D0.5)%0A%20%20%20%20%20%20%20%20axes%5B1%5D.set(ylabel%3D%22final%20leak%22%2C%20yscale%3D%22log%22)%0A%20%20%20%20%20%20%20%20axes%5B1%5D.set_xticks(range(len(_cells))%2C%20%5Blbl%20for%20_%2C%20_%2C%20lbl%20in%20_cells%5D)%0A%20%20%20%20%20%20%20%20for%20gi%2C%20lbl%20in%20enumerate(_scores)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20axes%5B1%5D.annotate(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22%7B_ncats%5Blbl%5D%7D%20cat.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(gi%2C%200.0)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20xycoords%3D(%22data%22%2C%20%22axes%20fraction%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20xytext%3D(0%2C%204)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textcoords%3D%22offset%20points%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ha%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D8%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.8%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20handles%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.Line2D(%5B%5D%2C%20%5B%5D%2C%20marker%3D%22o%22%2C%20ls%3D%22%22%2C%20color%3Dc%2C%20label%3Dv)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20v%2C%20c%20in%20((%22static%20(timed%20anneal)%22%2C%20gray)%2C%20(%22controller%22%2C%20accent))%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20axes%5B0%5D.legend(handles%3Dhandles%2C%20loc%3D%22lower%20left%22)%0A%20%20%20%20%20%20%20%20axes%5B0%5D.set_title(%22Fallback-trained%20cells%3A%20feedback%20adds%20no%20headroom%22)%0A%20%20%20%20%20%20%20%20return%20fig%0A%0A%20%20%20%20mo.Html(_plot())%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(cond%2C%20n_cat%2C%20rd)%3A%0A%20%20%20%20_s5%2C%20_c5%20%3D%20cond(%22static%22%2C%200.05)%2C%20cond(%22ctrl%22%2C%200.05)%0A%20%20%20%20_s1%2C%20_c1%20%3D%20cond(%22static%22%2C%200.10)%2C%20cond(%22ctrl%22%2C%200.10)%0A%20%20%20%20_rc%20%3D%20lambda%20rs%3A%20np.median(%5Br%5B%22val_recon%22%5D%20for%20r%20in%20rs%5D)%20%20%23%20noqa%3A%20E731%0A%20%20%20%20_lk%20%3D%20lambda%20rs%3A%20np.median(%5Br%5B%22leak%22%5D%20for%20r%20in%20rs%5D)%20%20%23%20noqa%3A%20E731%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20At%20the%20safe%20peak%20the%20two%20approaches%20are%20interchangeable%20on%20the%20score%20(medians%0A%20%20%20%20%7Bnp.median(rd(_c5))%3A.2f%7D%20for%20the%20controller%20vs%20%7Bnp.median(rd(_s5))%3A.2f%7D%20static%3B%20floors%0A%20%20%20%20%7Brd(_c5).min()%3A.2f%7D%20vs%20%7Brd(_s5).min()%3A.2f%7D).%20The%20controller%20halves%20the%20typical%20leak%0A%20%20%20%20(%7B_lk(_c5)%3A.3f%7D%20vs%20%7B_lk(_s5)%3A.3f%7D)%2C%20since%20a%20steady%20low-level%20penalty%20does%20keep%20the%20axis%0A%20%20%20%20cleaner%20on%20average%2C%20but%20it%20worsens%20the%20tail%20past%20the%20degraded%20threshold%20and%20costs%20about%0A%20%20%20%202%E2%80%933%C3%97%20in%20reconstruction%20(%7B_rc(_c5)%3A.6f%7D%20vs%20%7B_rc(_s5)%3A.6f%7D%2C%20both%20still%20tiny).%20At%20the%20risky%0A%20%20%20%20peak%20the%20pattern%20is%20the%20same%2C%20with%20%7Bn_cat(_c1)%20%2B%20n_cat(_s1)%7D%20catastrophes%20between%20the%20two%0A%20%20%20%20conditions%2C%20thanks%20to%20the%20fallback%20term.%5Cn%5C%0A%20%20%20%20The%20sensitivity%20grid%20is%20fairly%20clear%3A%20Tightening%20the%20targets%20by%2025%25%0A%20%20%20%20(%CF%84%C3%970.75)%20or%20doubling%20the%20gain%20(%CE%B7%C3%972)%2C%20with%20the%20fallback%20term%20still%20on%2C%20produces%0A%20%20%20%20%7Bn_cat(cond(%22ctrl-tau0.75%22))%7D%20and%20%7Bn_cat(cond(%22ctrl-eta2%22))%7D%20catastrophic%20runs%0A%20%20%20%20respectively%2C%20and%20halving%20the%20gain%20leaves%20%7Bn_cat(cond(%22ctrl-eta0.5%22))%7D.%20Loosening%20the%0A%20%20%20%20targets%20(%CF%84%C3%971.5)%20is%20safe%20(%7Bn_cat(cond(%22ctrl-tau1.5%22))%7D).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(cond%2C%20n_cat)%3A%0A%20%20%20%20_tot_fb%20%3D%20sum(%0A%20%20%20%20%20%20%20%20len(cond(c%2C%20lr))%0A%20%20%20%20%20%20%20%20for%20c%2C%20lr%20in%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22static%22%2C%200.10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22static%22%2C%200.05)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22ctrl%22%2C%200.10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22ctrl%22%2C%200.05)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22ctrl-tau0.75%22%2C%200.10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22ctrl-tau1.5%22%2C%200.10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22ctrl-eta0.5%22%2C%200.10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22ctrl-eta2%22%2C%200.10)%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20_cat_sens%20%3D%20n_cat(cond(%22ctrl-tau0.75%22))%20%2B%20n_cat(cond(%22ctrl-eta2%22))%20%2B%20n_cat(cond(%22ctrl-eta0.5%22))%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Lessons%0A%0A%20%20%20%20The%20idea%20seemed%20reasonable%3A%20protection%20on%20demand%20instead%20of%20on%20a%20timer.%0A%20%20%20%20The%20controller's%20response%20is%20fine%3B%20the%20measurement%20it%20relies%20on%20is%20the%0A%20%20%20%20problem.%20The%20training-time%20signal%20for%20anchor%20health%20was%20the%0A%20%20%20%20anchor%20loss%20on%20noisy%20labels%2C%20and%20in%20this%20experiment%2C%20that%20signal%20couldn't%20tell%20a%20drifting%20red%0A%20%20%20%20from%20a%20pink%20that%20should%20be%20off-axis.%0A%0A%20%20%20%20So%20the%20stack%20we%20keep%20is%20the%20plain%20one%3A%20the%20fallback%20term%20(which%2C%20across%20two%0A%20%20%20%20experiments%2C%20has%20removed%20every%20catastrophic%20failure)%2C%20peak%20LR%200.05%2C%20the%0A%20%20%20%20original%20timed%20anneal%2C%20and%20cheap%20endpoint%20screening.%0A%0A%20%20%20%20One%20engineering%20note.%20%60mini.temporal%60's%20%60DynamicProp.set()%60%20can%20retarget%20a%0A%20%20%20%20value%20mid-flight%2C%20which%20is%20what%20a%20controller%20needs%2C%20but%20experiments%20consume%0A%20%20%20%20schedules%20through%20%60realize_timeline%60%2C%20which%20bakes%20the%20dopesheet%20into%20a%20static%0A%20%20%20%20array%20before%20training.%20Dopesheet%20keyframes%20and%20runtime%20%60set()%60%20calls%20would%0A%20%20%20%20then%20compete%20over%20the%20same%20prop.%20So%20this%20experiment's%20controller%20lives%20inside%0A%20%20%20%20the%20training%20loop%20instead%2C%20carrying%20its%20dual%20state%20in%20the%20%60lax.scan%60%20carry%2C%0A%20%20%20%20while%20the%20dopesheet%20drives%20the%20props%20it%20doesn't%20control.%20That%20split%20worked%0A%20%20%20%20well%20and%20is%20worth%20keeping%2C%20even%20though%20the%20controller%20itself%20is%20not%20adopted.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
e25c873e319f082e54131bdb61e487f8