feat(generalization): periodic shrink-and-perturb every 20 epochs
Kills memorized weights by blending 85% current + 15% Xavier random. Surviving weights encode robust features. Memorized artifacts die. Configurable: shrink_perturb_interval, alpha, sigma. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -931,6 +931,13 @@ pub struct DQNHyperparameters {
|
||||
/// Prevents memorization of fixed simulation parameters.
|
||||
pub enable_domain_randomization: bool,
|
||||
|
||||
/// Periodic shrink-and-perturb interval (0=disabled, 20=every 20 epochs)
|
||||
pub shrink_perturb_interval: usize,
|
||||
/// Shrink-and-perturb alpha (0.85 = keep 85%, reinit 15%)
|
||||
pub shrink_perturb_alpha: f64,
|
||||
/// Shrink-and-perturb noise scale (Xavier)
|
||||
pub shrink_perturb_sigma: f64,
|
||||
|
||||
// Wave 16 Portfolio Features
|
||||
/// Enable action masking (filters invalid actions based on position limits)
|
||||
pub enable_action_masking: bool,
|
||||
@@ -1413,6 +1420,10 @@ impl DQNHyperparameters {
|
||||
|
||||
// Generalization: domain randomization (per-epoch jitter on sim params)
|
||||
enable_domain_randomization: true, // Default: enabled (prevents memorization of fixed sim params)
|
||||
// Generalization: periodic shrink-and-perturb (kills memorized weights)
|
||||
shrink_perturb_interval: 20, // Every 20 epochs (0=disabled)
|
||||
shrink_perturb_alpha: 0.85, // Keep 85% of weights, reinit 15%
|
||||
shrink_perturb_sigma: 0.01, // Xavier noise scale
|
||||
|
||||
// Wave 16 Portfolio Features (default: ALL ENABLED)
|
||||
enable_action_masking: true, // Default: action masking enabled
|
||||
|
||||
@@ -262,6 +262,19 @@ impl DQNTrainer {
|
||||
));
|
||||
}
|
||||
|
||||
// ── Periodic shrink-and-perturb: kill memorized weights ──
|
||||
let sp_interval = self.hyperparams.shrink_perturb_interval;
|
||||
if sp_interval > 0 && epoch > 0 && epoch % sp_interval == 0 {
|
||||
if let Some(ref mut fused) = self.fused_ctx {
|
||||
let alpha = self.hyperparams.shrink_perturb_alpha as f32;
|
||||
let sigma = self.hyperparams.shrink_perturb_sigma as f32;
|
||||
match fused.shrink_and_perturb(alpha, sigma) {
|
||||
Ok(()) => info!(epoch, alpha, sigma, "Periodic shrink-and-perturb applied"),
|
||||
Err(e) => warn!(epoch, "Shrink-and-perturb failed (non-fatal): {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Phase 3: Batched training from replay buffer ──
|
||||
let phase3_start = std::time::Instant::now();
|
||||
let train_step_count = self.run_training_steps(training_data).await?;
|
||||
|
||||
Reference in New Issue
Block a user