Overflow
The textbook log(1 + exp(-m)) returns inf at m = -1000, and its gradient is nan. One bad sample poisons the whole batch.
Sc. 01Constrained gradient optimization / PyTorch + NumPy
A box-constrained optimizer that stays numerically stable when the loss is badly scaled, steep, or full of overflow traps. Derivation, code, unit tests and benchmarks, built end to end as a working sample.
fewer evaluations than the best-tuned Adam on constrained Rosenbrock
learning rates to tune. The line search finds the step
unit tests passing, including stability edge cases
max relative gap between autograd and finite differences
Sc. 02The landscape
The valley floor is easy to see and hard to walk. The fence is a box constraint that cuts off the true minimum, so the answer sits on the boundary. Same start, five optimizers, every point below is a real iterate exported from demo.py.
Drag to orbit
The 3D view needs WebGL. The numbers below are unaffected.
Sc. 03What usually breaks
The textbook log(1 + exp(-m)) returns inf at m = -1000, and its gradient is nan. One bad sample poisons the whole batch.
Fixed-step gradient descent with lr = 0.005 on Rosenbrock diverges at iteration 5. With 0.001 it is still far away after 1500 steps. There is no safe constant.
The popular max(z,0) + log1p(exp(-|z|)) has the right value, but autograd gives gradient 0 at z = 0 instead of 0.5. A model started at w = 0 never moves. I found this one while building the sample.
Sc. 04The method
L-BFGS curvature on the free variables, a projection that respects the box, and an Armijo line search that refuses any step that does not pay for itself.
Projection onto the box is a componentwise clip, and a point is a KKT point exactly when a projected gradient step does not move it:
So the stopping test is \(\|x-P(x-\nabla f(x))\|_\infty\le \text{tol}\). A plain \(\|\nabla f\|\) test is wrong whenever a bound is active.
Variables pinned to a bound with the gradient pushing outward form the \(\varepsilon\)-active set \(A\). Curvature is only used on the free set \(F\):
A trial point with a non-finite loss counts as a failed test, so overflow shrinks the step instead of poisoning the iterate. If the quasi-Newton step is not a descent step, memory resets and a projected gradient step is taken.
For an \(L\)-smooth \(f\), backtracking always ends with a step bounded away from zero, without knowing \(L\):
The loss never increases, and every limit point is a KKT point. Convex problems converge at \(O(1/k)\), and strongly convex ones converge linearly. The full argument is in DERIVATION.md.
Sc. 05Benchmark
Logistic regression, 600 samples, 24 weights boxed to \([-2,2]\), feature scales spanning six orders of magnitude in curvature. The x-axis counts loss evaluations, so line-search trial steps are paid for. Adam gets six learning rates, GD gets four, and my method gets none.
| Method | evals to 1e-3 | evals to 1e-6 | evals to 1e-9 | final gap |
|---|
Sc. 06Stability
The logistic term \(\log(1+e^{-m})\) evaluated three ways on extreme margins. Red cells are where a training run silently breaks.
"double where": each branch only sees inputs where exp cannot overflowSc. 07Unit tests
Run on every export of this page. Known solutions, edge cases, regression tests for the bugs above, and the guarantees from Sc. 04 checked directly: iterates never leave the box, and the loss never goes up.
Sc. 08Drop-in code
from stableopt import ProjectedLineSearch
opt = ProjectedLineSearch(lower=-2.0, upper=2.0, tol=1e-8)
result = opt.minimize(loss_fn, w0) # loss_fn: tensor -> scalar tensor
result.x, result.fun, result.converged, result.message
result.history # per-iteration f, projected grad, step
pip install numpy torch pytest
python -m pytest -q # unit tests
python demo.py # benchmarks + site data
source
Sc. 09On a real project
Loss, constraints, boundary conditions: check smoothness, scaling and where it can overflow.
Pick the method, write the derivation and convergence notes another researcher can follow.
A clean NumPy / PyTorch module that drops into the existing pipeline.
Unit tests for edge cases and a reproducible notebook against your baseline metric.