Gradient descent · a field guide

The optimizer family tree, organized by the state it keeps

Every optimizer here is the same step — walk downhill — differing only in how it transforms the gradient and what extra memory it carries to do so. So the tree branches by state, not by publication date. The accent green always marks the one new thing a node adds over its parent.

θθ − η · 𝚏(g, state) pick f and state → pick your optimizer
new state / idea added here + added line vs parent ~ changed line vs parent inherited state
MAP

The lineage at a glance

Branches are the three ways to spend memory: a first moment2 (velocity), a second moment3 (per-parameter scale), or a structured preconditioner5 (whole-matrix curvature). Adam is literally the merge of the momentum and RMSProp branches. The dashed node is the one deterministic / full-batch method (L-BFGS) — everything else is built for stochastic mini-batches. The dotted node up top is the gradient-free world (ES, MeZO, EGGROLL): it changes where g comes from, not what you do with it. Tap any node to jump to its card; numbered marks like these jump to short footnotes at the bottom.

Stochastic · mini-batch

SGD · Momentum · Nesterov · AdaGrad · RMSProp · Adam(W) · Lion · Adafactor · Muon · Shampoo · K-FAC · PSGD

Designed to make progress from one noisy mini-batch gradient at a time. The whole tree above lives here — noise tolerance is the point.

Deterministic · full-batch

Newton · BFGS · L-BFGS (secant / quasi-Newton)

Infer curvature from gradient differences (B·s = y, the secant condition8) and usually pair with a line search — both assume a stable objective. Mini-batch noise corrupts the (s, y) pairs, so these are rare in deep learning.

LAB

Race them on a landscape

The master equation, running live: same start, same landscape, same η dial — only f(g, state) differs. The structured branch appears through its honest 2-D stand-ins: Full-matrix keeps a real 2×2 accumulator G = Σ g·gᵀ (the full-matrix-AdaGrad / Shampoo idea), and Muon's Ortho(M) on a 1×2 “matrix” reduces to unit-norm momentum. + marks the minima. Reading the map: you're looking straight down at the loss surface. Each line joins points of equal loss — tightly packed lines mean steep, the shading darkens uphill, and the small arrows point downhill. Hover to read the loss under the cursor; click to move the start point. (Per-optimizer step scaling is applied so one η dial is fair to all.)

click to set a new start point
top-down view · lines join equal loss · darker = higher · arrows point downhill

Landscape

Optimizers · tap to toggle

FN

Footnotes — the concepts, briefly

Every recurring term above, defined once. The numbered marks throughout the page land here.

  1. EMA — exponential moving average

    s ← ρ·s + (1−ρ)·x. A running average that forgets at rate ρ; its memory horizon is roughly 1/(1−ρ) steps (β=0.9 ≈ the last 10 gradients, β=0.999 ≈ the last 1000). Almost every buffer in this tree is an EMA of something.

  2. First moment

    The mean. In statistics the k-th moment of a random variable is E[xᵏ]; the first is E[x]. An EMA of the raw gradient estimates E[g] — the average direction — which is exactly what a velocity/momentum buffer is. It smooths mini-batch noise and builds speed along directions that keep agreeing with themselves.

  3. Second moment

    E[g²], per coordinate — the average squared gradient, i.e. the uncentered variance. Its square root is an RMS (root mean square — hence RMS­Prop). Dividing the step by √E[g²] gives every parameter its own learning rate: coordinates with habitually large gradients get reined in, quiet ones get amplified.

  4. Bias correction

    An EMA initialized at zero underestimates at first: after t steps it has only accumulated a fraction (1−βᵗ) of the true average. Adam divides by that fraction (m̂ = m/(1−β₁ᵗ), v̂ = v/(1−β₂ᵗ)) so early steps aren't artificially tiny. The correction fades to 1 as t grows.

  5. Preconditioner

    Any matrix P in θ ← θ − η·P·g that reshapes the gradient before stepping. The ideal is Newton's P = H⁻¹ (inverse Hessian) — perfect but unaffordable. Adam/RMSProp use a diagonal P (1/(√v+ε) per coordinate); Shampoo, K-FAC and PSGD spend more memory on structured full matrices that also capture correlations between parameters.

  6. Orthogonalization — Ortho(M)

    Write the SVD M = UΣVᵀ: U, V hold the directions, Σ the magnitudes. Then Ortho(M) := UVᵀ — same directions, every singular value set to 1. It's the nearest orthogonal(-ish) matrix to M, and equivalently (MMᵀ)−½·M. The point: a raw momentum matrix is dominated by a few large singular directions; orthogonalizing makes the update push equally along all of them.

  7. Newton–Schulz iteration

    Computing UVᵀ by actual SVD is slow and GPU-unfriendly. Newton–Schulz instead iterates a fixed odd matrix polynomial, X ← a·X + b·(XXᵀ)X + c·(XXᵀ)²X, on the normalized momentum. Each pass squashes all singular values toward 1, so ~5 iterations of pure matmuls (bf16-safe) ≈ Ortho(M) — no decomposition ever computed. Muon uses tuned coefficients (a≈3.44, b≈−4.78, c≈2.03) that converge fast without needing high precision.

  8. Secant / quasi-Newton

    Don't compute the Hessian — infer it from how the gradient moved: demand B·s = y where s = Δθ and y = Δg (the secant condition, the multivariate cousin of a finite-difference slope). BFGS refines an estimate with each new (s, y) pair; L-BFGS keeps only the last m pairs and rebuilds H⁻¹g on the fly. Mini-batch noise corrupts y (the gradient changed because the batch changed, not θ), which is why this family stays full-batch.

  9. Fisher information / natural gradient

    The Fisher matrix F measures how much the model's output distribution shifts per unit change of each parameter. Stepping along F⁻¹·g — the natural gradient — takes uniform steps in output space rather than parameter space, making the update invariant to how the network happens to be parameterized. K-FAC makes F tractable per layer as a Kronecker product A ⊗ G (input-activation covariance ⊗ output-gradient covariance), so F⁻¹g ≈ A⁻¹·g·G⁻¹.

  10. Zeroth-order / evolution strategies

    Methods that never see a true gradient — they probe the loss directly. The two-point estimate ĝ = [ℒ(θ+εz) − ℒ(θ−εz)] ⁄ 2ε · z measures the slope along one random direction z: in expectation an unbiased (but very noisy) sketch of the gradient of a slightly smoothed loss. Evolution strategies average many such perturbations weighted by fitness; larger populations mean less noise. The appeal: only forward passes needed — tiny memory, and non-differentiable objectives are fine. The cost: each probe yields one scalar, so high dimensions demand many probes or structured noise (EGGROLL's low-rank perturbations).

The whole tree in five lines