fix: update CI tests for expanded search space (45D) and wider v_range (±240)
- dqn_action_collapse_fix_test: search space grew from 39D to 45D (added c51_warmup, her_ratio, curiosity, cvar, dt_pretrain). Updated assertions to use >= 39 and dynamic index lookup for cql_alpha. - training_stability: Q-value assertion widened from 2.5 to 300.0 to match v_range ±240 (computed from reward_scale=10, gamma=0.95). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -313,9 +313,11 @@ fn test_50_epoch_convergence() -> anyhow::Result<()> {
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
let avg_q = metrics.additional_metrics.get("avg_q_value").copied().unwrap_or(0.0);
|
||||
assert_finite(avg_q, "avg_q_value");
|
||||
// v_range is now ±240 (computed from reward_scale=10, gamma=0.95).
|
||||
// Q-values should stay within the C51 support range with some margin.
|
||||
assert!(
|
||||
avg_q.abs() < 2.5,
|
||||
"ANOMALY 3: Q-value {:.4} saturating v_range ±2.0. C51 atoms exhausted.",
|
||||
avg_q.abs() < 300.0,
|
||||
"ANOMALY 3: Q-value {:.4} exceeding v_range ±240. C51 atoms exhausted.",
|
||||
avg_q
|
||||
);
|
||||
|
||||
|
||||
@@ -217,31 +217,24 @@ fn test_hyperopt_26d_includes_cql_alpha() {
|
||||
use ml::hyperopt::traits::ParameterSpace;
|
||||
|
||||
let bounds = DQNParams::continuous_bounds();
|
||||
assert_eq!(
|
||||
bounds.len(),
|
||||
39,
|
||||
"Search space should be 39D (31 base + 8 reward/policy weights), got {}D",
|
||||
assert!(
|
||||
bounds.len() >= 39,
|
||||
"Search space should be >= 39D, got {}D",
|
||||
bounds.len()
|
||||
);
|
||||
|
||||
let names = DQNParams::param_names();
|
||||
assert_eq!(
|
||||
names.len(),
|
||||
39,
|
||||
"param_names should return 39 entries, got {}",
|
||||
names.len()
|
||||
bounds.len(),
|
||||
"param_names length should match continuous_bounds length: {} vs {}",
|
||||
names.len(), bounds.len()
|
||||
);
|
||||
|
||||
// cql_alpha at index 22
|
||||
assert_eq!(
|
||||
names.get(22).copied(),
|
||||
Some("cql_alpha"),
|
||||
"Parameter 22 should be cql_alpha, got {:?}",
|
||||
names.get(22)
|
||||
);
|
||||
|
||||
// cql_alpha bounds: (0.0, 1.0) — full offline-RL range
|
||||
let (lo, hi) = bounds.get(22).copied().unwrap_or((0.0, 0.0));
|
||||
// cql_alpha must exist in search space with bounds (0.0, 1.0)
|
||||
let cql_idx = names.iter().position(|&n| n == "cql_alpha")
|
||||
.expect("cql_alpha should be in param_names");
|
||||
let (lo, hi) = bounds[cql_idx];
|
||||
assert!(
|
||||
(lo - 0.0).abs() < 1e-6 && (hi - 1.0).abs() < 1e-6,
|
||||
"cql_alpha bounds should be (0.0, 1.0), got ({}, {})",
|
||||
@@ -289,7 +282,8 @@ fn test_hyperopt_cql_alpha_round_trip() {
|
||||
params.cql_alpha = 0.25;
|
||||
|
||||
let continuous = params.to_continuous();
|
||||
assert_eq!(continuous.len(), 39);
|
||||
let bounds = DQNParams::continuous_bounds();
|
||||
assert_eq!(continuous.len(), bounds.len(), "to_continuous length should match bounds");
|
||||
|
||||
let reconstructed =
|
||||
DQNParams::from_continuous(&continuous).expect("from_continuous should succeed");
|
||||
|
||||
Reference in New Issue
Block a user