Skip to main content
© 2026 ePowerAI. All rights reserved.
CoursesContact
eAI
CoursesContact
Week 9: Practical Training Dynamics
Optimization
01Week 1: Optimization for Learning
02Week 2: Convex Sets and Functions
03Week 3: Gradient Descent Theory
04Week 4: Least Squares and Conditioning
05Week 5: Classification Losses
06Week 6: Stochastic Gradient Descent
07Week 7: Momentum and Acceleration
08Week 8: Adaptive First-Order Methods
09Week 9: Practical Training Dynamics
10Week 10: Nonsmooth and Composite Objectives
11Week 11: Constraints: Projections and Penalties
12Week 12: Duality for Practitioners
13Week 13: Nonconvex Deep Learning
14Week 14: Capstone — Theory Meets Training
Week 09· Optimization· First-order stack22 min read

Week 9: Practical Training Dynamics

✦Learning Outcomes
  • Enumerate common LR schedules (step, cosine, exponential) and when each helps
  • Explain warmup: ramp η\etaη from small to target in early steps to avoid early instability
  • Apply gradient clipping (norm and value) to prevent gradient explosion
  • Diagnose plateau, oscillation, and divergence from loss and gradient-norm plots
◆Prerequisites

Background: Weeks 6–8 (SGDStochastic Gradient Descent, momentum, AdamAdaptive Moment Estimation (optimizer)). This week is the practical complement — you already know the algorithms; now learn to tune and debug them.

Later weeks: These diagnostic skills are essential for the nonconvex training in Week 13 and the capstone diagnostics in Week 14.

Learning Rate Schedules#

A constant learning rate is rarely optimal. The right schedule depends on the problem and the optimiser:

Step decay: Reduce η\etaη by a factor γ\gammaγ every TTT epochs (or steps). Simple and effective for SGD: ηt=η0⋅γ⌊t/T⌋\eta_t = \eta_0 \cdot \gamma^{\lfloor t / T \rfloor}ηt​=η0​⋅γ⌊t/T⌋

Typical: γ=0.1\gamma = 0.1γ=0.1, T=30T = 30T=30 epochs (so η\etaη drops to 0.1η00.1\eta_00.1η0​, then 0.01η00.01\eta_00.01η0​, etc.).

Cosine annealing: Smoothly decays η\etaη following a cosine curve from η0\eta_0η0​ to ηmin⁡\eta_{\min}ηmin​ over TTT iterations: ηt=ηmin⁡+η0−ηmin⁡2(1+cos⁡πtT)\eta_t = \eta_{\min} + \frac{\eta_0 - \eta_{\min}}{2}\left(1 + \cos\frac{\pi t}{T}\right)ηt​=ηmin​+2η0​−ηmin​​(1+cosTπt​)

Cosine schedules are popular in vision and generative model training because they avoid sudden drops that can destabilise training.

Exponential decay: ηt=η0⋅γt\eta_t = \eta_0 \cdot \gamma^tηt​=η0​⋅γt. Continuous decay — good when you need a smooth schedule without discrete drops. Rarely used as the primary schedule; more common as a component of warmup.

Cyclical and warm restarts: η\etaη oscillates between ηmin⁡\eta_{\min}ηmin​ and ηmax⁡\eta_{\max}ηmax​ with period TTT. The oscillations can help escape saddle points in nonconvex landscapes.

When each helps:

  • Step decay: well-understood problems where you know when loss plateaus
  • Cosine annealing: modern default for vision and generative models — smooth, no tuning of drop epochs
  • Cyclical: nonconvex problems where exploration matters
  • Constant: debugging and early experimentation (remove one variable)

Warmup#

In the first few hundred training steps, the model parameters are poorly initialised and the gradient estimates are noisy. Large steps early on can send parameters to irrecoverably bad regions of the loss landscape.

Linear warmup increases η\etaη from a small value to the target η0\eta_0η0​ over NwarmupN_{\text{warmup}}Nwarmup​ steps:

ηt=η0⋅tNwarmupfor t≤Nwarmup\eta_t = \eta_0 \cdot \frac{t}{N_{\text{warmup}}} \quad \text{for } t \leq N_{\text{warmup}}ηt​=η0​⋅Nwarmup​t​for t≤Nwarmup​

Typical: Nwarmup=2000N_{\text{warmup}} = 2000Nwarmup​=2000–400040004000 steps for transformer training. Less critical for small models trained with SGD on simple objectives.

Why warmup is especially important for Adam: Adam's adaptive denominator v^k\hat v_kv^k​ is unstable early on (the EMA estimates are based on very few samples). Warmup gives Adam time to build reliable mmm and vvv estimates before taking large steps.

Gradient Clipping#

In recurrent networks, transformers, and unstable training setups, gradient norms can occasionally explode — a single bad mini-batch produces gradients with norms in the thousands. Without clipping, the parameter update can be catastrophic.

Clip by global norm: If the total gradient norm exceeds a threshold CCC, rescale the entire gradient vector:

if ∥g∥2>C,g←C∥g∥2⋅g\text{if } \|g\|_2 > C, \quad g \leftarrow \frac{C}{\|g\|_2} \cdot gif ∥g∥2​>C,g←∥g∥2​C​⋅g

This preserves the gradient direction while capping the magnitude. Typical C=1.0C = 1.0C=1.0 or 5.05.05.0 for RNNs/transformers.

Clip by value: Clamp each coordinate individually to [−v,v][-v, v][−v,v]:

gi←max⁡(−v,min⁡(v,gi))g_i \leftarrow \max(-v, \min(v, g_i))gi​←max(−v,min(v,gi​))

Less common in deep learning; more useful when individual gradient components can be pathologically large.

Diagnosing from Curves#

Your training loss curve is a diagnostic instrument. Here's what to look for:

Healthy training:

  • Training loss decreases smoothly and monotonically
  • Validation loss tracks training loss with a small gap
  • Gradient norm decreases gradually

Plateau: Loss is flat, gradients are small but nonzero.

  • Possible causes: η\etaη too small; stuck in a saddle point (nonconvex); poor initialisation
  • Try: increase η\etaη, add momentum, or switch to Adam

Oscillation: Loss bounces up and down significantly between steps.

  • Possible causes: η\etaη too large; batch size too small (noisy gradients)
  • Try: reduce η\etaη, increase batch size, or add momentum to smooth

Divergence: Loss rises monotonically, often to NaN.

  • Likely cause: η\etaη far too large; gradient explosion
  • Try: immediately reduce η\etaη by 10×, add gradient clipping

Overfitting signal: Training loss continues to drop while validation loss rises.

  • Not an optimisation problem per se — you're minimising the wrong thing (ERM gap)
  • Solutions: regularisation, data augmentation, early stopping

The gradient norm curve complements the loss curve. A healthy run shows:

  • Gradient norm near zero at convergence
  • No sudden spikes (if so, clipping is needed)
  • Gradual decay proportional to the loss decrease

When to Stop#

Early stopping: Halt training when validation loss stops improving for ppp consecutive epochs (patience). This prevents overfitting and is an implicit form of regularisation — stopping GD early on an overparameterised model biases the solution toward the initialisation, which often helps generalisation.

Practical rule: Track the best validation loss seen so far, and stop if it hasn't improved in 5–10 epochs. Restore the parameters from the epoch with the best validation loss.

Exercise · Multiple choice

A flat loss curve with small but nonzero gradient norms most likely indicates:

A plateau — η may be too small or you're in a saddle
Divergence — η is far too large
Convergence to the global optimum
A bug in the data pipeline
Question 1 of 4

A cosine annealing schedule for the learning rate:

Smoothly decays η from η₀ to η_min following a cosine curve
Drops η by a factor of 10 at fixed intervals
Increases η over time
Keeps η constant throughout training

Browser lab#

Train a small linear regression model with different LR schedules (constant, step decay, cosine) and plot loss vs epoch on the same axes.

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

rng = np.random.default_rng(42)
n, d = 500, 5
w_true = rng.normal(size=d)
X = rng.normal(size=(n, d))
y = X @ w_true + rng.normal(scale=0.5, size=n)

def train(X, y, w0, eta_fn, K):
    w = w0.copy(); losses = []
    for k in range(K):
        g = X.T @ (X @ w - y) / n
        w = w - eta_fn(k) * g
        losses.append(0.5 * np.mean((X @ w - y)**2))
    return losses

w0 = rng.normal(scale=0.1, size=d)
K = 80

constant = train(X, y, w0, lambda k: 0.1, K)
step_decay = train(X, y, w0, lambda k: 0.1 * (0.5 ** (k // 20)), K)
cosine = train(X, y, w0, lambda k: 0.01 + 0.5 * 0.09 * (1 + np.cos(np.pi * k / K)), K)

plt.figure(figsize=(9, 5))
plt.plot(constant, label="Constant η=0.1")
plt.plot(step_decay, label="Step decay (×0.5 every 20)")
plt.plot(cosine, label="Cosine annealing")
plt.yscale("log"); plt.xlabel("Iteration"); plt.ylabel("Loss")
plt.title("Loss vs Iteration: Three LR Schedules")
plt.legend(); plt.grid(True, alpha=0.3); plt.show()
← Previous
Week 8: Adaptive First-Order Methods
Next →
Week 10: Nonsmooth and Composite Objectives
On this page
  • Learning Rate Schedules
  • Warmup
  • Gradient Clipping
  • Diagnosing from Curves
  • When to Stop
  • Browser lab