Key ideas
Training = minimising a loss . The gradient is the vector of partial derivatives; it points uphill, so we step against it1.
Critical points () are minima, maxima or saddle points. In 1-D, ⇒ local min, ⇒ local max, ⇒ no conclusion (, , ). In -D, look at the Hessian : positive definite ⇒ min, negative definite ⇒ max, mixed signs ⇒ saddle. A maximum at an endpoint of an interval, or at a kink, need not have . Gradient descent rarely stays at a saddle: a tiny offset along a direction of negative curvature grows geometrically.
Convexity. A set is convex if it contains every segment between its points (balls of any norm, half-spaces, lines). is convex if , equivalently ; then every local minimum is global. Sums and maxima of convex functions are convex; minima are not, and neither is . Neural network losses are non-convex — e.g. permuting the hidden units gives equivalent weight settings.
Gradient descent (GD): . Too small crawls, too large overshoots and diverges1. On the update is , which converges iff 3. With several curvatures the steepest one caps () while the flattest one sets the speed, so a large condition number means slow progress3. Given the gradient, one update costs for parameters. Stop when the gradient or the updates become tiny, or after an iteration budget.
Second-order ideas1. Newton: — the minimiser of the local quadratic Taylor model, exact in one step on a quadratic; on non-convex use so the step still goes downhill. A full Hessian has entries (1 million parameters → numbers), so practice uses diagonal preconditioning, a per-coordinate learning rate — it only helps when the steep and flat directions are aligned with the axes; rotate the problem and the benefit is gone7.
SGD2. One example (or a minibatch) per step: cost instead of . The stochastic gradient is an unbiased estimate of the full gradient; averaging over a minibatch of i.i.d. examples divides its variance by (SD by ). Because the noise does not vanish at the optimum, must decay; for convex problems gives an rate2. Sampling examples with replacement touches only about of them 2. Full-batch GD is the only one of GD/SGD/minibatch whose updates do not depend on the order of the data.
Momentum keeps a leaky average , . It averages about recent gradients, so noise cancels and the effective step is (10× for )3; it damps oscillation across a narrow valley and accepts larger .
Adaptive methods (per-coordinate scaling):
| Method | State | Step |
|---|---|---|
| Adagrad | — rate decays like 4,7 | |
| RMSProp | same; leaky average fixes the decay4 | |
| Adam | , | , , 5 |
Adam (defaults , ) keeps two extra numbers per parameter; bias correction undoes the zero initialisation5. On step 1, , so the first move has size whatever the gradient's scale. Its learning rate should still decay: near a minimum, noisy gradients keep from vanishing, so the iterates jitter at a scale set by . Schedules: step or polynomial decay, cosine (slow decay at first, a small rate to refine at the end), and warm-up — raise from a small value, because a large rate at the start, when updates from random weights are large and poorly aimed, can diverge8.
Computing derivatives. Symbolic, numerical (finite differences — truncation error for large , round-off for tiny ) and automatic differentiation, exact to working precision6. Forward mode carries a tangent with each value (dual numbers , ) and needs one pass per input; reverse mode (backpropagation) needs one pass per output, ideal for a scalar loss with millions of parameters6.
Formulas
Chain rule for : .
Worked example
, so and each GD step multiplies the coordinates by and . Stability needs , i.e. . From with : one step gives — flips sign but shrinks. With the factor is and explodes, although would still converge. : loses at most 20% per step at the largest stable .
In code
import torch
for g in [1000.0, -0.002]: # very different gradient sizes
w = torch.tensor([0.0], requires_grad=True)
opt = torch.optim.Adam([w], lr=0.01)
(g * w).sum().backward() # dL/dw = g
opt.step()
print(round(w.item(), 6)) # -0.01, then 0.01
x = torch.tensor([1.0, 1.0], requires_grad=True)
f = 0.5 * (x[0] ** 2 + 10 * x[1] ** 2)
f.backward()
print(x.grad) # tensor([ 1., 10.])
Common pitfalls
- does not mean an extremum (saddle or inflection, e.g. at 0).
- The steepest direction limits the step size — a learning rate safe for flat directions can diverge along steep ones3.
- SGD needs a decaying learning rate to converge; a constant one leaves it jittering2.
- "Stochastic" means random sampling of examples, not just using minibatches.
- Adagrad's effective rate keeps shrinking; RMSProp/Adam use leaky averages instead4.
- Skipping Adam's bias correction distorts the first steps: on step 1 the uncorrected ratio is times the corrected one5.
- Momentum in "EMA form" () has no boost; with you must shrink by to keep the same step.
- Finite differences with tiny are not more accurate — round-off dominates6.
References
- Dive into Deep Learning — Sec. 12.3.1 One-Dimensional Gradient Descent; 12.3.2 Multivariate Gradient Descent; 12.3.3 Adaptive Methods (Newton's Method, Preconditioning, Line Search)
- Dive into Deep Learning — Sec. 12.4.1 Stochastic Gradient Updates; 12.4.2 Dynamic Learning Rate; 12.4.3 Convergence Analysis for Convex Objectives; 12.4.4 Stochastic Gradients and Finite Samples
- Dive into Deep Learning — Sec. 12.6.1 Basics (Leaky Averages; An Ill-conditioned Problem; Effective Sample Weight); 12.6.3 Theoretical Analysis
- Dive into Deep Learning — Sec. 12.8.1 The Algorithm (recap of Adagrad and the leaky-average fix)
- Dive into Deep Learning — Sec. 12.10.1 The Algorithm; 12.10.3 Yogi; 12.10.4 Summary
- Wikipedia: Automatic differentiation — Difference from other differentiation methods; Forward and reverse accumulation (Two types of automatic differentiation; Forward accumulation; Reverse accumulation); Automatic differentiation using dual numbers
- Dive into Deep Learning — Sec. 12.7.2 Preconditioning; 12.7.3 The Algorithm
- Dive into Deep Learning — Sec. 12.11.3.3 Cosine Scheduler; 12.11.3.4 Warmup