From 24289f40a5801ce9ccbd56121de38ffc01f49060 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Fri, 22 May 2026 12:19:31 +0200 Subject: [PATCH] =?UTF-8?q?tune(aux-bce):=20lower=20POS=5FWEIGHT=5FMAX=205?= =?UTF-8?q?0=E2=86=9210=20(gentler=20class-weight=20clamp)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A+B Smoke 1 (alpha-perception-79rbn) showed pos_weight=50 caused overshooting: BCE=0.83 (worse than chance ln(2)=0.69) AND sub-chance dir_acc (0.28-0.45) at all horizons. The 50× cap pushed the model toward the rare positive class hard enough to blow up loss on 99.99% of negative samples. Lower MAX clamp to 10× lets per-horizon imbalance still scale the loss but caps the runaway gradient on extreme-rare positive classes (like K=100's 0.01% positive rate where pos_weight would otherwise be ~9999). Synthetic test still passes (clamp doesn't matter on constant signal where pos_fraction=1.0). Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/ml-alpha/src/aux_heads.rs | 7 ++++++- crates/ml-alpha/src/trainer/perception.rs | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/ml-alpha/src/aux_heads.rs b/crates/ml-alpha/src/aux_heads.rs index 7e4e53b82..9b802a067 100644 --- a/crates/ml-alpha/src/aux_heads.rs +++ b/crates/ml-alpha/src/aux_heads.rs @@ -96,7 +96,12 @@ pub const DEFAULT_HUBER_DELTA: f32 = 1.0; /// runaway logit gradients while still letting >5:1 class imbalance /// scale the positive-class loss proportionally. pub const POS_WEIGHT_MIN: f32 = 1.0; -pub const POS_WEIGHT_MAX: f32 = 50.0; +/// Lowered 50→10 after A+B Smoke 1 (alpha-perception-79rbn, 2026-05-22) +/// showed pw=50 caused class-weight overshooting: BCE=0.83 (worse than +/// chance ln(2)=0.69) AND sub-chance dir_acc at all horizons. The 50× cap +/// pushed the model toward the rare positive class hard enough to +/// blow up loss on 99.99% of negative samples. +pub const POS_WEIGHT_MAX: f32 = 10.0; /// Host-side weight storage for [`AuxHeads`] (checkpoint round-trip). #[derive(Clone, Debug)] diff --git a/crates/ml-alpha/src/trainer/perception.rs b/crates/ml-alpha/src/trainer/perception.rs index e5497286a..be9d580e2 100644 --- a/crates/ml-alpha/src/trainer/perception.rs +++ b/crates/ml-alpha/src/trainer/perception.rs @@ -97,7 +97,9 @@ const AUX_VEC_ADD_CUBIN: &[u8] = include_bytes!( /// (would down-weight the rarer class) and pw > 50 produces unstable /// gradient spikes. const POS_WEIGHT_MIN: f32 = 1.0; -const POS_WEIGHT_MAX: f32 = 50.0; +/// Mirrors `aux_heads::POS_WEIGHT_MAX`; lowered 50→10 after A+B Smoke 1 +/// (79rbn) showed pw=50 caused class-weight overshooting (BCE > ln(2)). +const POS_WEIGHT_MAX: f32 = 10.0; /// CB5 (SDD-3): Wiener-α floor for the aux BCE / Huber EMAs /// (`pearl_wiener_alpha_floor_for_nonstationary`). The aux trunk is /// non-stationary: its loss trajectory drifts as the encoder