Skip to main content
© 2026 ePowerAI — free, open courseware. No login required.
CoursesContact
ePOWERAI
CoursesContact
Week 8: Adaptive First-Order Methods
Optimization

Foundations

  1. 01Week 1: Optimization for Learning
  2. 02Week 2: Convex Sets and Functions
  3. 03Week 3: Gradient Descent Theory

Model problems

  1. 04Week 4: Least Squares and Conditioning
  2. 05Week 5: Classification Losses

First-order stack

  1. 06Week 6: Stochastic Gradient Descent
  2. 07Week 7: Momentum and Acceleration
  3. 08Week 8: Adaptive First-Order Methods
  4. 09Week 9: Practical Training Dynamics

Structure

  1. 10Week 10: Nonsmooth and Composite Objectives
  2. 11Week 11: Constraints: Projections and Penalties
  3. 12Week 12: Duality for Practitioners

Nonconvex practice

  1. 13Week 13: Nonconvex Deep Learning
  2. 14Week 14: Capstone — Theory Meets Training
Week 08· Optimization· First-order stack6 min read

Week 8: Adaptive First-Order Methods

Learning Outcomes
  • Write AdaGrad: accumulate squared gradients and divide learning rate per-parameter
  • Explain AdaGrad's failure mode (accumulator grows forever) and how RMSProp fixes it with EMA
  • Write AdamAdaptive Moment Estimation (optimizer) as RMSProp + momentum + bias correction
  • Describe what adaptivity buys (sparse gradients, varying scales) and what it hides
Prerequisites

Background: Week 6 (SGDStochastic Gradient Descent) and Week 7 (momentum). Adam combines the momentum idea (Week 7) with adaptive per-parameter step sizes introduced here.

Later weeks: Adam is the go-to optimiser for nonconvex deep learning (Week 13) and appears in both RL (policy gradient) and generative model training (Week 14).

One learning rate does not fit all#

In deep networks, different parameters have vastly different scales:

  • Weights in early layers might have typical gradient magnitudes of 10−210^{-2}10−2
  • Weights in later layers might have gradients of 10−510^{-5}10−5
  • Embedding parameters for rare words get updated very infrequently (sparse gradients)

A single global learning rate η\etaη cannot serve all parameters well. If η\etaη is tuned for the fastest-changing parameters, the slow-changing ones barely move. If η\etaη is large enough for the slow parameters, the fast ones oscillate or diverge.

Adaptive methods solve this by maintaining a per-parameter effective learning rate, automatically scaled by the historical magnitude of that parameter's gradient.

AdaGrad#

AdaGrad (Duchi et al., 2011) was the first widely-used adaptive method. It accumulates the squares of all past gradients:

Gk=∑t=1kgt⊙gt(elementwise square and sum)G_k = \sum_{t=1}^k g_t \odot g_t \quad \text{(elementwise square and sum)}Gk​=∑t=1k​gt​⊙gt​(elementwise square and sum)

wk+1=wk−ηGk+ε⊙gkw_{k+1} = w_k - \frac{\eta}{\sqrt{G_k + \varepsilon}} \odot g_kwk+1​=wk​−Gk​+ε​η​⊙gk​

where ⊙\odot⊙ is elementwise multiplication and ε=10−8\varepsilon = 10^{-8}ε=10−8 prevents division by zero.

How it works. Parameters with historically large gradients get a smaller effective learning rate. Parameters with historically small gradients get a larger one.

The failure mode. GkG_kGk​ is monotonically increasing, so it never forgets. In the limit k→∞k \to \inftyk→∞, Gk→∞G_k \to \inftyGk​→∞ and the effective learning rate η/Gk\eta/\sqrt{G_k}η/Gk​​ goes to zero for all parameters, so training stalls. This is why AdaGrad fell out of favour for deep learning.

RMSProp#

RMSProp (Tieleman & Hinton, 2012) fixes AdaGrad's accumulating-divisor problem by replacing the sum with an exponential moving average (EMAExponential Moving Average):

vk=β2 vk−1+(1−β2) gk⊙gkv_k = \beta_2 \, v_{k-1} + (1 - \beta_2) \, g_k \odot g_kvk​=β2​vk−1​+(1−β2​)gk​⊙gk​

wk+1=wk−ηvk+ε⊙gkw_{k+1} = w_k - \frac{\eta}{\sqrt{v_k + \varepsilon}} \odot g_kwk+1​=wk​−vk​+ε​η​⊙gk​

where β2∈[0,1)\beta_2 \in [0, 1)β2​∈[0,1) (typically 0.9990.9990.999) controls the memory length. The EMA forgets old gradients: approximately the last 1/(1−β2)≈10001/(1-\beta_2) \approx 10001/(1−β2​)≈1000 steps influence vkv_kvk​.

RMSProp maintains adaptivity (each parameter gets its own scale) without the monotonic-stall problem. It became the default in many frameworks before Adam took over.

Adam#

AdamAdaptive Moment Estimation (optimizer) (Kingma & Ba, 2015) combines the best of both worlds:

  1. Momentum (Week 7) for the gradient direction: mk=β1mk−1+(1−β1)gkm_k = \beta_1 m_{k-1} + (1-\beta_1) g_kmk​=β1​mk−1​+(1−β1​)gk​
  2. RMSProp for per-parameter scaling: vk=β2vk−1+(1−β2)gk⊙gkv_k = \beta_2 v_{k-1} + (1-\beta_2) g_k \odot g_kvk​=β2​vk−1​+(1−β2​)gk​⊙gk​

The full Adam update:

mk=β1mk−1+(1−β1)gkm_k = \beta_1 m_{k-1} + (1 - \beta_1) g_kmk​=β1​mk−1​+(1−β1​)gk​ vk=β2vk−1+(1−β2)gk⊙gkv_k = \beta_2 v_{k-1} + (1 - \beta_2) g_k \odot g_kvk​=β2​vk−1​+(1−β2​)gk​⊙gk​ m^k=mk1−β1k,v^k=vk1−β2k(bias correction)\hat m_k = \frac{m_k}{1 - \beta_1^k}, \quad \hat v_k = \frac{v_k}{1 - \beta_2^k} \quad \text{(bias correction)}m^k​=1−β1k​mk​​,v^k​=1−β2k​vk​​(bias correction) wk+1=wk−ηv^k+ε⊙m^kw_{k+1} = w_k - \frac{\eta}{\sqrt{\hat v_k} + \varepsilon} \odot \hat m_kwk+1​=wk​−v^k​​+εη​⊙m^k​

Bias correction: At initialisation, m0=0m_0 = 0m0​=0 and v0=0v_0 = 0v0​=0. The EMA estimates start biased toward zero. Dividing by 1−βk1 - \beta^k1−βk corrects this: at k=1k=1k=1, m1/(1−β1)=g1m_1/(1-\beta_1) = g_1m1​/(1−β1​)=g1​ exactly, and as k→∞k \to \inftyk→∞ the correction factor approaches 1.

Standard hyperparameters:

  • η=0.001\eta = 0.001η=0.001 (or 1×10−31 \times 10^{-3}1×10−3)
  • β1=0.9\beta_1 = 0.9β1​=0.9 (momentum decay)
  • β2=0.999\beta_2 = 0.999β2​=0.999 (RMSProp decay)
  • ε=10−8\varepsilon = 10^{-8}ε=10−8

These defaults work remarkably well across a wide range of deep learning problems, one reason Adam became the de facto standard.

Practice defaults and what adaptivity hides#

When Adam works well:

  • Sparse gradients (embeddings, NLP)
  • Non-stationary objectives (GANs, RL, though care is needed)
  • Default choice when you don't want to tune η\etaη extensively

When to fall back to SGD + momentum:

  • When you need the best possible generalisation on a well-understood problem
  • Computer vision benchmarks (where SGD + momentum with careful tuning often beats Adam)
  • When theoretical convergence guarantees matter

What adaptivity hides. Adam's per-parameter scaling can mask poor conditioning, obscuring the diagnosis. The theoretical convergence guarantees for Adam are weaker than for SGD. Under certain adversarial constructions, Adam can diverge even on convex problems. The β2\beta_2β2​ parameter needs to be close enough to 1 for the RMSProp term to provide a stable denominator.

Knowledge check#

Exercise · Multiple choice

Which component of Adam prevents the effective learning rate from vanishing for parameters with historically small gradients?

The RMSProp-style denominator √(v_k) with β₂ < 1
The momentum term m_k with β₁ = 0.9
The bias correction 1/(1−β₂^k)
The learning rate η itself
Question 1 of 4

AdaGrad's main failure mode in deep learning is:

The gradient accumulator G_k grows forever, driving the effective LR to zero
It requires second derivatives
It doesn't use momentum
It only works for convex functions

Browser lab: Adam vs SGD + momentum#

Compare AdamAdaptive Moment Estimation (optimizer) vs SGD + momentum on a toy nonconvex 2D loss with an elongated valley. Plot iterate paths to visualise the adaptivity.

python · runs in browser
import numpy as np
import matplotlib.pyplot as plt

def f(w):
    x, y = w[0], w[1]
    return 0.5 * x**2 + 5.0 * y**2 + 2.0 * np.sin(x) * np.sin(y)

def grad(w):
    x, y = w[0], w[1]
    return np.array([x + 2.0 * np.cos(x) * np.sin(y),
                     10.0 * y + 2.0 * np.sin(x) * np.cos(y)])

def adam(w0, K, eta=0.1, beta1=0.9, beta2=0.999, eps=1e-8):
    w = w0.copy(); m = np.zeros(2); v = np.zeros(2)
    path = [w.copy()]; losses = [f(w)]
    for t in range(1, K+1):
        g = grad(w)
        m = beta1 * m + (1 - beta1) * g
        v = beta2 * v + (1 - beta2) * g**2
        m_hat = m / (1 - beta1**t)
        v_hat = v / (1 - beta2**t)
        w = w - eta * m_hat / (np.sqrt(v_hat) + eps)
        path.append(w.copy()); losses.append(f(w))
    return np.array(path), np.array(losses)

def sgd_momentum(w0, K, eta=0.05, beta=0.9):
    w = w0.copy(); v = np.zeros(2)
    path = [w.copy()]; losses = [f(w)]
    for _ in range(K):
        v = beta * v - eta * grad(w)
        w = w + v
        path.append(w.copy()); losses.append(f(w))
    return np.array(path), np.array(losses)

w0 = np.array([3.0, 2.0])
K = 150
path_adam, loss_adam = adam(w0, K)
path_sgd, loss_sgd = sgd_momentum(w0, K)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.plot(path_adam[:, 0], path_adam[:, 1], label="Adam", linewidth=1.5)
ax1.plot(path_sgd[:, 0], path_sgd[:, 1], label="SGD+momentum", linewidth=1.5)
ax1.plot(w0[0], w0[1], "ko", markersize=6, label="Start")
ax1.set_xlabel("w1"); ax1.set_ylabel("w2")
ax1.set_title("Iterate Paths"); ax1.legend()
ax2.plot(loss_adam, label="Adam"); ax2.plot(loss_sgd, label="SGD+momentum")
ax2.set_xlabel("Iteration"); ax2.set_ylabel("Loss")
ax2.set_title("Loss vs Iteration")
ax2.set_yscale("log"); ax2.legend(); ax2.grid(True, alpha=0.3)
plt.tight_layout(); plt.show()

print(f"Final loss  Adam={loss_adam[-1]:.4f}  SGD+momentum={loss_sgd[-1]:.4f}")
print("Notice: Adam adapts each parameter's scale and tracks the elongated valley faster than tuned SGD+momentum here.")

Key takeaways#

  • A single global learning rate cannot serve parameters whose gradients differ by orders of magnitude; adaptive methods give each parameter its own effective rate.
  • AdaGrad divides by the accumulated squared gradient, which adapts well but stalls because the accumulator only grows.
  • RMSProp replaces the sum with an exponential moving average, removing the stall while keeping per-parameter scaling.
  • Adam is momentum plus RMSProp plus bias correction; the defaults (η=10−3\eta = 10^{-3}η=10−3, β1=0.9\beta_1 = 0.9β1​=0.9, β2=0.999\beta_2 = 0.999β2​=0.999) work across a wide range of problems.
  • Bias correction matters: without it the early moment estimates are biased toward zero.
  • Adam's adaptivity can mask bad conditioning, and its convergence guarantees are weaker than SGD's. SGD + momentum still often wins on carefully tuned, well-understood problems.

Further reading#

  • John Duchi, Elad Hazan & Yoram Singer, "Adaptive Subgradient Methods for Online Learning and Stochastic Optimization" (Journal of Machine Learning Research, 2011). AdaGrad and per-parameter scaling.
  • Tijmen Tieleman & Geoffrey Hinton, "Lecture 6.5 — RMSProp" (Coursera lecture notes, 2012). The EMA denominator that replaces AdaGrad's growing accumulator.
  • Diederik P. Kingma & Jimmy Ba, "Adam: A Method for Stochastic Optimization" (ICLR 2015). Adam and its bias-correction terms. Freely available at arXiv:1412.6980.
  • Ilya Loshchilov & Frank Hutter, "Decoupled Weight Decay Regularization" (ICLR 2019). AdamW and why decoupling weight decay matters. Freely available at arXiv:1711.05101.

Reading is free. PDF and ePub unlock with the newsletter. Join once and every lesson opens in this browser.

← Previous
Week 7: Momentum and Acceleration
Next →
Week 9: Practical Training Dynamics
On this page
  • One learning rate does not fit all
  • AdaGrad
  • RMSProp
  • Adam
  • Practice defaults and what adaptivity hides
  • Knowledge check
  • Browser lab: Adam vs SGD + momentum
  • Key takeaways
  • Further reading