Published July 13, 2026 | Version v0.11.5

bartulem/usv-playpen: v0.11.5

  • 1. Princeton Neuroscience Institute
  • 2. Princeton University

Description

v0.11.5

Single-engine fix. The Euclidean bivariate manifold regressor could never satisfy its own convergence test whenever the regularisation tuner picked a stiff corner of the grid, so a large fraction of folds ran the full max_iter and reported converged=False. No reported score changes — this makes the convergence flag trustworthy and stops burning 20 000 iterations per fold. The torus/QLVM path is untouched, and no rerun of existing results is required.

⚠️ Who is affected

Anyone running the continuous analysis on a Euclidean manifold (VAE / UMAP) with tune_regularization_bool: true. The torus (QLVM) path is unaffected — see below.

Fixed

  • SmoothBivariateRegression could not converge under strong regularisation. The estimator built a plain, constant-learning-rate Adam (optax.adam(learning_rate)) with no gradient clipping — while the multinomial estimator, whose docstring documents the identical failure mode, already carried both a cosine-decayed schedule and global-norm clipping. The bivariate never received that fix.

    The mechanism: under a constant step size, an Adam update is lr · m̂ / (√v̂ + ε), whose magnitude does not shrink toward zero as the gradient vanishes. The 100-step parameter-change norm therefore plateaus at a floor set by learning_rate, and the diff < tol convergence test can never fire — the loop simply runs to max_iter and reports converged=False. It is worst exactly where the objective is stiffest: a large lambda_smooth on the 2nd-derivative penalty across 600 lags is a badly ill-conditioned quadratic, and a fixed step oscillates in those high-curvature directions instead of settling.

    The fingerprint was unmistakable in the 100-fold cluster output: every non-converged fold sat at lambda_smooth ∈ {10, 100} with l2_reg = 1, and every converged fold sat at lambda_smooth ≤ 1 with l2_reg = 0.1. And inner_cv_use_one_se_rule: true deliberately steers the tuner into that most-regularised corner whenever models are statistically tied — which, on a weak-signal feature, is most of the time.

    The learning rate is now cosine-decayed to zero over max_iter and the gradient's global norm is clipped (grad_clip_norm, default 1.0), mirroring the multinomial. The objective is convex, so clipping never biases the solution; it only bounds the per-step move. max_iter becomes a static JIT argument, since the schedule needs it as a Python int at trace time.

    Verified: the corner that never converged now settles at ~15 600 / 20 000 iterations (λ_sm=100, l2=1) and ~13 600 (λ_sm=10, l2=1); previously-converging configurations still converge; the eager (non-lax) path behaves identically; and sklearn's clone / get_params round-trip the new parameter.

What this does not change

No score moves. The folds that already converged were reporting r2_spatial ≈ 0, and they still report r2_spatial ≈ 0. Giving the heavily-regularised folds a reachable convergence criterion produces cleanly converged zeros, not different ones. This is a correctness-of-reporting fix, not a result.

Existing pickles therefore do not need regenerating for their numbers — only if you want trustworthy converged flags in them.

Not affected

The torus / QLVM path. SmoothTorusManifoldRegression solves a convex objective in closed form — there is no iterative optimiser and no convergence flag on that path at all. QLVM runs require no rerun and are unchanged by this release.

Upgrading

Nothing to do. grad_clip_norm is a constructor default (1.0), not a setting — matching how the multinomial estimator already handles it — so no modeling_settings.json change is required and existing configs keep working untouched.

Full suite green (2184 passed).

Full changelog: v0.11.4...v0.11.5

Files

bartulem/usv-playpen-v0.11.5.zip

Files (55.0 MB)

Name Size Download all
md5:6be21bafc1d91d4ec10541dfe7c8c4c0
55.0 MB Preview Download

Additional details

Related works