Skip to main content
© 2026 ePowerAI — free, open courseware. No login required.
CoursesContact
ePOWERAI
CoursesContact
Week 7: Momentum and Acceleration
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 07· Optimization· First-order stack7 min read

Week 7: Momentum and Acceleration

Learning Outcomes
  • Write the heavy-ball momentum update and explain its effect: dampens oscillations, builds speed in consistent directions
  • Choose a momentum coefficient β\betaβ (common: 0.90.90.9)
  • Contrast Nesterov accelerated gradient (look-ahead gradient) with plain momentum
  • Explain why momentum reduces the O(κ)\mathcal{O}(\kappa)O(κ) iteration complexity to O(κ)\mathcal{O}(\sqrt{\kappa})O(κ​) for convex quadratics
Prerequisites

Background: Week 3 (GD convergence, condition number κ\kappaκ) and Week 6 (SGDStochastic Gradient Descent). The condition-number story from Week 3 directly motivates momentum.

Later weeks: Momentum is the "first moment" component inside AdamAdaptive Moment Estimation (optimizer) (Week 8), where it's combined with adaptive per-parameter step sizes.

Why momentum?#

Recall Week 4's ill-conditioned problem: f(w)=12(w12+100w22)f(w) = \frac{1}{2}(w_1^2 + 100 w_2^2)f(w)=21​(w12​+100w22​) with κ=100\kappa = 100κ=100. GD with η=1/L\eta = 1/Lη=1/L makes rapid progress along w1w_1w1​ (steep direction) but crawls along w2w_2w2​ (shallow direction). The iterates zigzag down a narrow valley.

Momentum fixes this by adding inertia. Instead of the gradient alone determining the step, a fraction of the previous step's direction is retained:

vk+1=βvk−η∇f(wk)v_{k+1} = \beta v_k - \eta \nabla f(w_k)vk+1​=βvk​−η∇f(wk​) wk+1=wk+vk+1w_{k+1} = w_k + v_{k+1}wk+1​=wk​+vk+1​

where vkv_kvk​ is the velocity and β∈[0,1)\beta \in [0, 1)β∈[0,1) is the momentum coefficient.

The zigzag: oscillations in the steep direction cancel out when averaged over time, while progress in the shallow direction accumulates. The result is a smoother, faster trajectory.

in a narrow valley, momentum damps the zigzag GD zigzags momentum smooths minimum

On the same ill-conditioned valley, plain GD (orange) bounces across the steep direction, while momentum (blue) damps those oscillations and accumulates progress down the shallow direction.

Heavy-ball momentum#

The heavy-ball method (Polyak, 1964) is the classic momentum formulation:

vk+1=βvk−η∇f(wk)v_{k+1} = \beta v_k - \eta \nabla f(w_k)vk+1​=βvk​−η∇f(wk​) wk+1=wk+vk+1w_{k+1} = w_k + v_{k+1}wk+1​=wk​+vk+1​

Unrolling the velocity update reveals it as an exponential moving average:

vk+1=−η∑t=0kβk−t∇f(wt)v_{k+1} = -\eta \sum_{t=0}^k \beta^{k-t} \nabla f(w_t)vk+1​=−η∑t=0k​βk−t∇f(wt​)

Recent gradients have weight ≈1\approx 1≈1, while gradients mmm steps ago have weight βm\beta^mβm. The effective "memory" of momentum is roughly 1/(1−β)1/(1-\beta)1/(1−β) steps: with β=0.9\beta = 0.9β=0.9 about 10 steps, and with β=0.99\beta = 0.99β=0.99 about 100 steps.

Practical choices for β\betaβ:

  • β=0\beta = 0β=0: recovers plain GD/SGDStochastic Gradient Descent
  • β=0.9\beta = 0.9β=0.9: standard setting, good for most problems
  • β=0.99\beta = 0.99β=0.99: longer memory, useful when gradients are very noisy (SGD with small batch)
  • β=0.999\beta = 0.999β=0.999: very long memory, used in Adam's first-moment estimate

Physical analogy: A ball rolling down a hill. The gradient is the slope (instantaneous force), momentum keeps the ball rolling in the direction it's already going. If the slope direction changes slowly, the ball accelerates; if it oscillates (zigzag valley), the oscillations cancel.

Interpreting momentum#

For a 1D quadratic f(w)=a2w2f(w) = \frac{a}{2} w^2f(w)=2a​w2, the momentum iteration becomes a second-order linear recurrence:

wk+1=(1+β−aη)wk−βwk−1w_{k+1} = (1 + \beta - a\eta) w_k - \beta w_{k-1}wk+1​=(1+β−aη)wk​−βwk−1​

The eigenvalues of this recurrence determine convergence. The optimal β\betaβ and η\etaη for a quadratic with curvature aaa are:

η∗=4(L+μ)2,β∗=(κ−1κ+1)2\eta^* = \frac{4}{(\sqrt{L} + \sqrt{\mu})^2}, \quad \beta^* = \left(\frac{\sqrt{\kappa} - 1}{\sqrt{\kappa} + 1}\right)^2η∗=(L​+μ​)24​,β∗=(κ​+1κ​−1​)2

The resulting convergence factor is κ−1κ+1\frac{\sqrt{\kappa} - 1}{\sqrt{\kappa} + 1}κ​+1κ​−1​, compared to κ−1κ+1\frac{\kappa - 1}{\kappa + 1}κ+1κ−1​ for plain GD. For κ=100\kappa = 100κ=100, GD needs ≈200\approx 200≈200 iterations for a constant-factor reduction; momentum needs ≈20\approx 20≈20, a 10× speedup.

Nesterov accelerated gradient#

Nesterov (1983) proposed a subtle but important modification:

w~k=wk+βvk\tilde w_k = w_k + \beta v_kw~k​=wk​+βvk​ vk+1=βvk−η∇f(w~k)v_{k+1} = \beta v_k - \eta \nabla f(\tilde w_k)vk+1​=βvk​−η∇f(w~k​) wk+1=wk+vk+1w_{k+1} = w_k + v_{k+1}wk+1​=wk​+vk+1​

The difference is that the gradient is evaluated at w~k=wk+βvk\tilde w_k = w_k + \beta v_kw~k​=wk​+βvk​, the point reached by continuing with the current velocity, instead of at the current position wkw_kwk​. This "look-ahead" gradient provides a correction before we commit to the velocity direction.

For convex quadratics, Nesterov achieves the provably optimal convergence rate: O(1/k2)\mathcal{O}(1/k^2)O(1/k2) for smooth convex (vs GD's O(1/k)\mathcal{O}(1/k)O(1/k)) and O(κlog⁡(1/ε))\mathcal{O}(\sqrt{\kappa} \log(1/\varepsilon))O(κ​log(1/ε)) for strongly convex.

In deep learning practice, the distinction between heavy-ball and Nesterov momentum is often minor. Both work well, and the choice is usually dictated by framework defaults.

Convergence benefit#

For a convex LLL-smooth function, Nesterov's accelerated gradient achieves:

f(xK)−f(x∗)≤2L∥x0−x∗∥2K2f(x_K) - f(x^*) \leq \frac{2L \|x_0 - x^*\|^2}{K^2}f(xK​)−f(x∗)≤K22L∥x0​−x∗∥2​

Compare to GD: 2L∥x0−x∗∥2K\frac{2L\|x_0 - x^*\|^2}{K}K2L∥x0​−x∗∥2​. The acceleration improves the denominator from KKK to K2K^2K2, a quadratic improvement in the number of iterations. To reach accuracy ε\varepsilonε, GD needs O(1/ε)\mathcal{O}(1/\varepsilon)O(1/ε) iterations; Nesterov needs O(1/ε)\mathcal{O}(1/\sqrt{\varepsilon})O(1/ε​).

When does momentum actually help?

  • Ill-conditioned convex problems: large speedup
  • Well-conditioned problems: little benefit (GD is already fast)
  • Nonconvex problems (deep nets): empirical benefit from dampening oscillations and escaping shallow regions, though theoretical guarantees are weaker
  • SGD with momentum: reduces variance in the update direction, acting as a variance-reduction technique alongside the adaptive step-size role

Knowledge check#

Exercise · Fill in the blank

If β = 0, momentum SGD reduces to plain ___.

Question 1 of 4

The heavy-ball momentum update v_{k+1} = β v_k − η ∇f(w_k) can be seen as:

An exponential moving average of past gradients
A simple scaling of the current gradient
A random perturbation of the gradient
A second-derivative approximation

Browser lab: momentum vs Nesterov#

Compare GD, momentum, and Nesterov on an ill-conditioned 2D quadratic (κ≈100\kappa \approx 100κ≈100). Plot iterate trajectories and loss vs iteration.

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

Q = np.diag([100.0, 1.0])

def f(w): return 0.5 * (w @ Q @ w)
def grad(w): return Q @ w

L = 100.0; mu = 1.0
eta_gd = 1.0 / L
eta_mom = 4.0 / (np.sqrt(L) + np.sqrt(mu))**2
beta_mom = ((np.sqrt(L/mu) - 1) / (np.sqrt(L/mu) + 1))**2

w0 = np.array([0.5, 10.0])
K = 200

def run_gd(w0, K, eta):
    w = w0.copy(); path = [w.copy()]; losses = [f(w)]
    for _ in range(K):
        w = w - eta * grad(w)
        path.append(w.copy()); losses.append(f(w))
    return np.array(path), np.array(losses)

def run_momentum(w0, K, eta, beta, nesterov=False):
    w = w0.copy(); v = np.zeros(2)
    path = [w.copy()]; losses = [f(w)]
    for _ in range(K):
        if nesterov:
            g = grad(w + beta * v)
        else:
            g = grad(w)
        v = beta * v - eta * g
        w = w + v
        path.append(w.copy()); losses.append(f(w))
    return np.array(path), np.array(losses)

path_gd, loss_gd = run_gd(w0, K, eta_gd)
path_mom, loss_mom = run_momentum(w0, K, eta_mom, beta_mom, nesterov=False)
path_nes, loss_nes = run_momentum(w0, K, eta_mom, beta_mom, nesterov=True)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.plot(path_gd[:, 0], path_gd[:, 1], alpha=0.6, label="GD")
ax1.plot(path_mom[:, 0], path_mom[:, 1], alpha=0.6, label="Momentum")
ax1.plot(path_nes[:, 0], path_nes[:, 1], alpha=0.6, label="Nesterov")
ax1.plot(0, 0, "kx", markersize=8)
ax1.set_xlabel("w1"); ax1.set_ylabel("w2")
ax1.set_title("Iterate Paths"); ax1.legend()
ax2.semilogy(loss_gd, label="GD"); ax2.semilogy(loss_mom, label="Momentum")
ax2.semilogy(loss_nes, label="Nesterov")
ax2.set_xlabel("Iteration"); ax2.set_ylabel("Loss")
ax2.set_title("Loss vs Iteration"); ax2.legend(); ax2.grid(True, alpha=0.3)
plt.tight_layout(); plt.show()

print(f"Final loss  GD={loss_gd[-1]:.2e}  Momentum={loss_mom[-1]:.2e}  Nesterov={loss_nes[-1]:.2e}")
print("Notice: on this ill-conditioned problem (κ ≈ 100), momentum and Nesterov reach low loss in far fewer iterations than GD.")

Key takeaways#

  • Heavy-ball momentum adds a velocity term, turning the update into an exponential moving average of past gradients with memory about 1/(1−β)1/(1-\beta)1/(1−β) steps.
  • It damps oscillation in steep directions while accumulating progress in shallow ones, precisely the ill-conditioned zigzag from Week 4.
  • For a quadratic, the right momentum changes the convergence factor from (κ−1)/(κ+1)(\kappa-1)/(\kappa+1)(κ−1)/(κ+1) to (κ−1)/(κ+1)(\sqrt{\kappa}-1)/(\sqrt{\kappa}+1)(κ​−1)/(κ​+1): a κ\sqrt{\kappa}κ​ speedup, about 10× at κ=100\kappa = 100κ=100.
  • Nesterov evaluates the gradient at the look-ahead point wk+βvkw_k + \beta v_kwk​+βvk​ and achieves the optimal O(1/K2)\mathcal{O}(1/K^2)O(1/K2) rate for smooth convex functions.
  • In deep learning the heavy-ball versus Nesterov distinction is usually minor; momentum's real value is variance reduction and escape from shallow regions.
  • Momentum is the first-moment component inside Adam.

Further reading#

  • Boris T. Polyak, "Some methods of speeding up the convergence of iteration methods" (USSR Computational Mathematics and Mathematical Physics, 1964). The original heavy-ball method.
  • Yurii Nesterov, "A method of solving a convex programming problem with convergence rate O(1/k2)O(1/k^2)O(1/k2)" (Soviet Mathematics Doklady, 1983). The accelerated gradient method and its optimal rate.
  • Ilya Sutskever, James Martens, George Dahl & Geoffrey Hinton, "On the importance of initialization and momentum in deep learning" (ICML 2013). Momentum as it is actually used in deep networks.

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

← Previous
Week 6: Stochastic Gradient Descent
Next →
Week 8: Adaptive First-Order Methods
On this page
  • Why momentum?
  • Heavy-ball momentum
  • Interpreting momentum
  • Nesterov accelerated gradient
  • Convergence benefit
  • Knowledge check
  • Browser lab: momentum vs Nesterov
  • Key takeaways
  • Further reading