fix(hyperopt): PSO premature convergence — tune inertia/cognitive/social
Argmin defaults: inertia=0.72, cognitive=1.19, social=1.19 Problem: social >> inertia causes particles to collapse toward the global best immediately. With only 1 LHS trial as the initial best, the entire swarm clusters around that point and can't explore. Every PSO trial was worse than the random LHS trial. Fix: inertia=0.9 (high momentum, maintains exploration), cognitive=1.5 (strong personal best memory), social=0.8 (weak global pull, prevents premature convergence). Applied to both sequential and parallel optimizer paths. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -374,8 +374,18 @@ impl ArgminOptimizer {
|
||||
let lower_bounds: Vec<f64> = bounds.iter().map(|(min, _)| *min).collect();
|
||||
let upper_bounds: Vec<f64> = bounds.iter().map(|(_, max)| *max).collect();
|
||||
|
||||
// Create Particle Swarm solver
|
||||
let solver = ParticleSwarm::new((lower_bounds, upper_bounds), self.n_particles);
|
||||
// Create Particle Swarm solver with tuned parameters.
|
||||
// Default argmin: inertia=0.72, cognitive=1.19, social=1.19
|
||||
// Problem: social >> inertia → premature convergence to global best.
|
||||
// Fix: higher inertia (0.9) for exploration, lower social (0.8) to
|
||||
// reduce collapse toward the single LHS best point.
|
||||
let solver = ParticleSwarm::new((lower_bounds, upper_bounds), self.n_particles)
|
||||
.with_inertia_factor(0.9)
|
||||
.map_err(|e| anyhow::anyhow!("PSO inertia: {e}"))?
|
||||
.with_cognitive_factor(1.5)
|
||||
.map_err(|e| anyhow::anyhow!("PSO cognitive: {e}"))?
|
||||
.with_social_factor(0.8)
|
||||
.map_err(|e| anyhow::anyhow!("PSO social: {e}"))?;
|
||||
|
||||
// Run optimization (parallel execution enabled via rayon feature)
|
||||
// CRITICAL FIX (2025-11-03): Removed .target_cost(0.0) to prevent early termination
|
||||
@@ -798,7 +808,13 @@ impl ArgminOptimizer {
|
||||
let lower_bounds: Vec<f64> = bounds.iter().map(|(min, _)| *min).collect();
|
||||
let upper_bounds: Vec<f64> = bounds.iter().map(|(_, max)| *max).collect();
|
||||
|
||||
let solver = ParticleSwarm::new((lower_bounds, upper_bounds), effective_particles);
|
||||
let solver = ParticleSwarm::new((lower_bounds, upper_bounds), effective_particles)
|
||||
.with_inertia_factor(0.9)
|
||||
.map_err(|e| anyhow::anyhow!("PSO inertia: {e}"))?
|
||||
.with_cognitive_factor(1.5)
|
||||
.map_err(|e| anyhow::anyhow!("PSO cognitive: {e}"))?
|
||||
.with_social_factor(0.8)
|
||||
.map_err(|e| anyhow::anyhow!("PSO social: {e}"))?;
|
||||
|
||||
let res = Executor::new(cost_fn, solver)
|
||||
.configure(|state| state.max_iters(max_iters as u64))
|
||||
|
||||
Reference in New Issue
Block a user