Optimization
Adam: A Method for Stochastic Optimization
TL;DR
Defines Adam, an optimizer that adapts each parameter's step size from running estimates of the gradient's mean and variance, the default choice for training deep networks.
Why it matters
Adam made deep networks far easier to train reliably without hand-tuning learning-rate schedules, and remains a default optimizer across the field. Its update rule is short enough to implement from scratch, which makes it an ideal from-paper-to-code exercise.
Key ideas
- Track exponential moving averages of the gradient (first moment) and its square (second moment).
- Bias-correct those averages so early steps are not shrunk toward zero.
- Divide the step by the square root of the second moment, giving each parameter its own effective rate.
- Combines the benefits of momentum and per-parameter scaling in one simple rule.
Related concepts
From paper to code
Adam is the optimizer most deep networks are trained with, and its update rule is short enough to implement in a dozen lines. This walkthrough builds it from plain SGD and watches it optimise a simple function.
The problem
Plain stochastic gradient descent takes the same step size for every parameter: , where is the gradient. Two difficulties follow:
- One rate does not fit all parameters. Some directions are steep and need small steps; others are flat and could move faster. A single compromises.
- Mini-batch gradients are noisy. Each step sees a different batch, so raw gradients jitter, and the path zig-zags.
We would like each parameter to get its own effective step size, adapted from the gradient history, with the noise smoothed out.
The idea
Keep two running averages of the gradient as training proceeds:
- the first moment , a smoothed gradient (momentum), which damps noise;
- the second moment , a smoothed gradient squared, a per-parameter scale of how large gradients have been.
Divide the smoothed gradient by the square root of the second moment. A parameter with consistently large gradients gets a smaller effective step; a quiet parameter gets a larger one. Each direction adapts on its own.
Insight
Adam combines two older ideas, momentum (averaging the gradient) and per-parameter scaling (RMSProp), into one rule, and adds a bias correction so the very first steps are not artificially tiny.
The update rule
At step , with gradient and decay rates :
Because and start at zero, early estimates are biased toward zero, so they are corrected:
Then the parameter update:
The paper's defaults are , , and to avoid dividing by zero.
A minimal implementation
Minimise , a bowl that is ten times steeper along one axis than the other, which is exactly where a single learning rate struggles:
import numpy as np
def grad(theta):
# gradient of theta0^2 + 10*theta1^2
return np.array([2 * theta[0], 20 * theta[1]])
theta = np.array([5.0, 5.0])
m = np.zeros(2)
v = np.zeros(2)
alpha, b1, b2, eps = 0.1, 0.9, 0.999, 1e-8
for t in range(1, 201):
g = grad(theta)
m = b1 * m + (1 - b1) * g
v = b2 * v + (1 - b2) * g**2
m_hat = m / (1 - b1**t) # bias correction
v_hat = v / (1 - b2**t)
theta = theta - alpha * m_hat / (np.sqrt(v_hat) + eps)
print(np.round(theta, 4)) # both components near 0
What to observe
- Both components approach zero together, even though the two axes have very different curvature, the per-parameter scaling handles the steep axis and the flat one at once.
- Drop the bias correction (use
mandvdirectly): the first several steps are noticeably smaller, because the zero-initialised averages start shrunk toward zero. The correction is what fixes the early steps. - Feed the same function to plain SGD with one rate large enough for the flat axis, and it oscillates or diverges along the steep one.
Limitations
- Adam often trains fast but can generalise slightly worse than well-tuned SGD with momentum on some vision tasks, the choice is empirical.
- Naive L2 weight decay interacts badly with the adaptive scaling; the common fix is AdamW, which decouples weight decay from the gradient update.
- It is still first-order and local: it finds a nearby minimum, not a global one, and remains sensitive to the base learning rate .