- start with asgd, finish with l-bfgs

This commit is contained in:
w.pomp committed 2026-07-31 15:14:44 +02:00
1 parent 36b24332cd
commit fdac4e04c4
2 files changed
+47 -35

No files matched your search

+17 -5
View File
@@ -62,8 +62,12 @@ impl RegistrationStep {
/// Default registration steps matching elastix `FixedSmoothingImagePyramid`.
///
/// Uses a multi-resolution approach with L-BFGS optimizer and all pixels on all levels
/// for deterministic, precise convergence.
/// Uses a hybrid multi-fidelity approach:
/// - Coarse levels (sigma=4,2): ASGD optimizer with all pixels for speed
/// - Fine levels (sigma=1,0.5): L-BFGS optimizer with all pixels for accuracy
///
/// Note: Samples are cached per level (not randomized per iteration like SimpleElastix),
/// but ASGD's sigmoid momentum handles the stochastic gradients effectively.
pub fn default_steps(ndim: usize, n: usize) -> Vec<Self> {
if ndim == 1 {
return vec![Self {
@@ -89,8 +93,16 @@ impl RegistrationStep {
.map(|(level, (&s, &d))| {
let n_pixels = (n / (d * d)).max(4);
let is_finest = level == n_levels - 1;
// Use all pixels on all levels for deterministic results
let (max_iter, tol) = if is_finest { (2048, 1e-8) } else { (512, 1e-6) };
let is_coarse = level < 2;
// Hybrid: ASGD on coarse levels for speed, L-BFGS on fine levels for accuracy
// Use all pixels on all levels for consistent gradient estimates
let (optimizer, max_iter, tol) = if is_coarse {
(Optimizer::ASGD, 512, 1e-4)
} else if is_finest {
(Optimizer::LBFGS, 2048, 1e-8)
} else {
(Optimizer::LBFGS, 512, 1e-6)
};
Self {
sigma: Sigma::Absolute(vec![s; ndim]),
samples: SamplingArg::Random(n_pixels),
@@ -100,7 +112,7 @@ impl RegistrationStep {
max_iterations: max_iter,
learning_rate: 1.0,
downsample: d,
optimizer: Optimizer::LBFGS,
optimizer,
}
})
.collect()