PIXELBANKv8.2.1
Menu
Back to Concepts
Optimization2019

AdamW vs Adam

Decoupled Weight Decay Regularization

Ilya Loshchilov, Frank Hutter

Read the Paper on arXiv

Paper Overview

Adam (Kingma & Ba, 2015) is the most widely used optimizer in deep learning, combining momentum (exponential moving average of gradients, β1=0.9\beta_1 = 0.9) with adaptive per-parameter learning rates via RMSProp (exponential moving average of squared gradients, β2=0.999\beta_2 = 0.999). With bias correction to counteract zero-initialization, Adam automatically scales each parameter's step size inversely proportional to the root-mean-square of its historical gradients — large-gradient parameters get smaller steps, sparse-gradient parameters get larger steps.

However, a subtle implementation detail created a widespread bug across deep learning frameworks: treating weight decay as L2 regularization (adding λθ\lambda \theta to the gradient before the adaptive update). In SGD, L2 regularization and weight decay are mathematically equivalent. But in Adam, the L2 gradient term λθ\lambda \theta gets divided by v^t+ϵ\sqrt{\hat{v}_t} + \epsilon alongside the task gradient — meaning the effective regularization strength varies inversely with gradient magnitude. Parameters with large, frequent gradients (large v^t\hat{v}_t) are under-regularized, while sparse parameters are over-regularized. This is exactly backwards from what we want.

AdamW (Loshchilov & Hutter, 2019) fixes this by decoupling weight decay from the gradient-based update. Instead of adding λθ\lambda \theta to the gradient (which then passes through Adam's adaptive scaling), AdamW applies weight decay as a separate multiplicative step: θ(1ηλ)θ\theta \leftarrow (1 - \eta\lambda)\theta before the gradient update, where η\eta is the learning rate and λ\lambda is the weight decay coefficient. This ensures every parameter shrinks by the same fraction per step, regardless of its gradient history.

This seemingly small change leads to significantly better generalization, especially for Transformers. On CIFAR-10 with a ResNet, Loshchilov & Hutter showed that AdamW achieves the same test accuracy as SGD with momentum — closing a gap that had previously been attributed to Adam being a "worse optimizer." AdamW is now the default optimizer in PyTorch (torch.optim.AdamW), Hugging Face Transformers, and is used to train BERT, GPT-2/3/4, ViT, LLaMA, Stable Diffusion, and virtually all modern architectures. Typical hyperparameters: η=104\eta = 10^{-4} to 10310^{-3}, λ=0.01\lambda = 0.01 to 0.10.1, β1=0.9\beta_1 = 0.9, β2=0.999\beta_2 = 0.999, ϵ=108\epsilon = 10^{-8}.

Chapter Roadmap

Click any topic to jump in

1
SGD + Momentum

Exponential moving average of gradients damps oscillations and averages noise across iterations.

2
Adam

Adds per-parameter adaptive learning rates via second moment of gradients.

adds adaptive LR
3
L2 vs Weight Decay

Equivalent in SGD, but Adam's adaptive scaling couples regularization to gradient history, under-regularizing frequent parameters.

exposes L2 bug
4
AdamW

Decouples weight decay from the gradient update, restoring uniform regularization across all parameters.

5
When to Use

AdamW is the default for Transformers; hyperparameters tune independently.

Before understanding Adam, we need to understand vanilla SGD's limitations and how momentum — the exponential moving average of gradients that forms Adam's 'first moment' — addresses them by accumulating directional information across iterations.

The Problem

Vanilla stochastic gradient descent (SGD) computes the gradient L(θt)\nabla L(\theta_t) on a mini-batch and takes a step θt+1=θtαL(θt)\theta_{t+1} = \theta_t - \alpha \nabla L(\theta_t). This has fundamental limitations that become severe for deep networks with millions of parameters:

  • Oscillation in ravines: Most loss landscapes are highly elongated — the Hessian eigenvalue ratio (condition number) can exceed 10410^4 for deep networks. The gradient points along the steepest descent direction, which in a ravine is nearly perpendicular to the optimal path. This causes violent zigzagging: each step overshoots along the narrow dimension while making little progress along the long dimension. For a 2D quadratic with eigenvalues λ1=100\lambda_1 = 100 and λ2=1\lambda_2 = 1, the gradient-to-optimal-direction angle is arctan(100)89.4°\arctan(100) \approx 89.4° — nearly orthogonal.

  • No memory of past gradients: Each step uses only the current mini-batch gradient, which is a noisy estimate of the true gradient (mini-batch variance 1/B\propto 1/B for batch size BB). With batch size 32 on a dataset of 50K samples, each gradient estimate sees only 0.064% of the data. The optimizer has no mechanism to average out this noise across iterations.

  • Sensitive to learning rate: The optimal learning rate is α2/(λmax+λmin)\alpha^* \approx 2/(\lambda_{\max} + \lambda_{\min}) where λ\lambda are Hessian eigenvalues. For a poorly conditioned loss (λmax/λmin=104\lambda_{\max}/\lambda_{\min} = 10^4), this gives α2×104\alpha^* \approx 2 \times 10^{-4} — too small for fast convergence along the flat directions. Any larger α\alpha causes divergence along the steep direction; any smaller causes extremely slow progress.

  • Equal treatment of all parameters: A single global learning rate is applied to all parameters. But different layers, different weight matrices, and different dimensions of the same tensor may have vastly different gradient magnitudes. In a Transformer, embedding gradients might be 100×100\times smaller than attention logit gradients — a single learning rate cannot be optimal for both.

  • Stochastic noise amplification: Mini-batch gradients have variance that doesn't decrease with more training iterations (unlike full-batch gradient descent). SGD's trajectory looks like a random walk near the minimum, unable to converge to the exact optimum without learning rate annealing.

The Solution

Momentum (Polyak, 1964; widely adopted via Sutskever et al., 2013) adds a "velocity" vector vtv_t that accumulates an exponential moving average of past gradients. This is the foundation of Adam's first moment estimate mtm_t:

vt=βvt1+gtv_t = \beta v_{t-1} + g_t θt=θt1αvt\theta_t = \theta_{t-1} - \alpha v_t

where gt=L(θt)g_t = \nabla L(\theta_t) is the current gradient, β[0,1)\beta \in [0, 1) is the momentum coefficient, and v0=0v_0 = 0. Unrolling the recursion, vtv_t is a weighted sum of all past gradients: vt=i=0tβtigiv_t = \sum_{i=0}^{t} \beta^{t-i} g_i — recent gradients are weighted more heavily (exponential decay with half-life 1/ln(1/β)\approx 1/\ln(1/\beta) steps).

Why this solves SGD's problems:

  1. Oscillation damping: In a ravine, gradients oscillate between positive and negative along the narrow dimension. The momentum average cancels these oscillations: β(+g)+(g)0\beta \cdot (+g) + (-g) \approx 0 after a few steps. Along the consistent long-axis direction, gradients accumulate: vg/(1β)=10gv \rightarrow g/(1-\beta) = 10g at steady state with β=0.9\beta = 0.9. The effective step size along consistent directions is amplified by 1/(1β)=10×1/(1-\beta) = 10\times.

  2. Noise averaging: The exponential moving average acts as a low-pass filter on the stochastic gradient signal. With β=0.9\beta = 0.9, the effective average is over the last 1/(1β)=101/(1-\beta) = 10 gradients, reducing variance by roughly 10×10\times compared to raw SGD. This is equivalent to using a 10×10\times larger batch size — for free.

  3. Escape from saddle points and flat regions: In flat regions where gt0g_t \approx 0, accumulated velocity vtv_t from previous non-zero gradients carries the parameters forward — like a ball rolling through a valley floor. Without momentum, the optimizer would stall in flat regions indefinitely.

  4. Standard hyperparameter: β=0.9\beta = 0.9 is the near-universal default, meaning velocity is a weighted average of the last ~10 gradient steps. Nesterov momentum (vt=βvt1+g(θtαβvt1)v_t = \beta v_{t-1} + g(\theta_t - \alpha \beta v_{t-1}), evaluating the gradient at a "lookahead" position) gives a small additional improvement by incorporating curvature information, and is the default in PyTorch's SGD(nesterov=True).

Limitation that motivates Adam: Momentum gives the same effective learning rate to all parameters — it addresses the oscillation and noise problems but not the per-parameter scale problem. Parameters with consistently large gradients and parameters with small sparse gradients both use αvt\alpha v_t. This is where adaptive methods (RMSProp, Adam) enter the picture.

Key Points

1

Momentum accumulates past gradients as exponential moving average

2

Damps oscillations in ravines, accelerates in consistent directions

3

Standard β=0.9\beta = 0.9 retains 90% of previous velocity

4

Foundation for Adam optimizer (first moment estimate)

Mathematical Formulation

SGD Update

θt+1=θtαL(θt)\theta_{t+1} = \theta_t - \alpha \nabla L(\theta_t)

Basic gradient descent: step proportional to gradient

Momentum Update

vt=βvt1+L(θt),θt+1=θtαvtv_t = \beta v_{t-1} + \nabla L(\theta_t), \quad \theta_{t+1} = \theta_t - \alpha v_t

Velocity accumulates gradients; β controls momentum strength

Mathematical Intuition

Momentum turns the optimizer into a low-pass filter on the stochastic gradient signal. The EMA vt=βvt1+gtv_t = \beta v_{t-1} + g_t attenuates high-frequency oscillations (noise, ravine zig-zag) while amplifying low-frequency consistent directions by 1/(1β)1/(1-\beta). With β=0.9\beta = 0.9, this is a free 10×10\times boost in effective batch size along descent-consistent directions.