The Full Diagnostic Checklist#
Before choosing an optimiser, run through this checklist:
-
Convex or not? If the loss is convex (linear/logistic regression, SVM dual), global optimality is achievable. If nonconvex (deep nets), you're navigating a landscape — focus on architecture and initialisation.
-
Smoothness estimate: What is , the Lipschitz constant of the gradient? For quadratics , . For deep nets, estimate via a power-iteration sweep on a mini-batch Hessian. Start with .
-
Condition number: Estimate . Large () means GD will be slow — add momentum or use Adam.
-
Noise level: What is the variance of mini-batch gradients? High noise (small , heterogeneous data) → use momentum or Adam + warmup + gradient clipping. Low noise (large , homogeneous data) → plain SGD may suffice.
-
Constraint structure: Are there box constraints, a simplex constraint, or a norm bound? If projections are cheap (ball, box), use projected GD. If not, consider soft penalties.
Method Selection Table#
| Problem profile | Recommended optimiser | Step size | Batch size | |---|---|---|---| | Small, convex, well-conditioned () | GD | | (full) | | Large , convex, moderate | SGD | , decay | 32–256 | | Large , convex, ill-conditioned () | SGD + momentum | , | 32–256 | | Large , nonconvex, sparse gradients | Adam | , defaults | 32–512 | | Nonconvex, best generalisation needed | SGD + momentum + cosine LR | tuned , | 256–1024 | | Constrained (ball/box/simplex) | Projected GD/SGD | for GD | as above | | Composite (smooth + ) | Proximal gradient (ISTA) | | as above |
The default in 2026: Adam/AdamW with cosine LR schedule and small warmup. This is the safe choice when prototyping. Switch to SGD + momentum + cosine only when maximising final performance on a well-understood problem.
Case Study A: Policy Gradient for RL#
Reinforcement learning optimises a policy to maximise expected return. The policy gradient estimator is:
where is an advantage estimate.
Optimisation profile:
- Nonconvex: The policy objective is highly nonconvex — no global optimality guarantees
- High variance: The advantage estimates are noisy, creating large gradient variance even with moderate
- Non-stationary: The data distribution shifts as the policy changes, and value function estimates co-evolve
Standard recipe: Adam with , , , batch size determined by environment parallelism. Gradient clipping at norm –. Linear LR decay or constant . The value function baseline acts as a variance-reduction mechanism.
Link: Reinforcement Learning course
Case Study B: Denoising Diffusion Training#
Diffusion models and flow matching train a denoiser to predict the noise added to a clean sample. The training objective is:
Optimisation profile:
- Large-scale: Models are large (– parameters), datasets enormous
- Well-behaved objective: The L2 denoising loss has a relatively benign landscape — close to a massive least-squares problem in function space
- Low gradient noise: The per-example loss is a simple squared error with explicit targets
Standard recipe: AdamW (Adam with decoupled weight decay) with , , , cosine LR schedule with warmup. EMA of model weights (not gradient moments) for final inference. Large batch – distributed across GPUs.
Link: Generative Models course
Course Map#
| Concept | Where | Key equation | |---|---|---| | ERM | W1 | | | Convexity | W2 | | | Smoothness & rates | W3 | | | Least squares | W4 | , | | Logistic / softmax | W5 | | | SGD | W6 | (mini-batch) | | Momentum / Nesterov | W7 | | | Adam | W8 | , | | LR schedules / clipping | W9 | Cosine, warmup, | | Subgradients / proximal | W10 | | | Constraints / projections | W11 | | | Duality | W12 | , SVM dual | | Nonconvex | W13 | Overparam, init, normalisation |
What Next#
- Advanced Optimization: Second-order methods (Newton, L-BFGS), variance reduction (SVRG), distributed training, sharpness-aware minimisation (SAM), and automatic differentiation — for those who want Boyd-level depth and ML-frontier training science.
- Probability & Statistics: The modelling side — MLE/MAP, exponential families, graphical models, and information theory (entropy/KL) — the language connecting loss functions to probabilistic stories.
- Reinforcement Learning and Generative Models: These applied courses use the optimisers from this course as black-box subroutine drivers. You now understand what's inside the black box.
You're training a linear regression model with $n=1000$, $d=10$, convex and well-conditioned ($\\kappa \\approx 5$). Which optimiser and justification fits best?
For an RL policy gradient problem (high variance, nonconvex, non-stationary), the standard optimiser choice is:
Browser lab#
A mini training-diagnostics dashboard: (1) estimate (smoothness) on a synthetic LS problem, plot loss + gradient norm; (2) run Adam on a small nonconvex problem and print the diagnostic checklist output.
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng(42)
# --- Part 1: Estimate L on least squares ---
n, d = 200, 5
X = rng.normal(size=(n, d))
w_true = rng.normal(size=d)
y = X @ w_true + rng.normal(scale=0.2, size=n)
L_est = np.linalg.eigvalsh(X.T @ X / n).max()
print(f"[Diagnostic] Smoothness estimate: L ≈ {L_est:.4f}")
print(f"[Diagnostic] Recommended η for GD: 1/L ≈ {1/L_est:.4f}")
w = np.zeros(d)
eta = 1.0 / L_est
losses, grad_norms = [], []
for _ in range(60):
resid = X @ w - y
g = X.T @ resid / n
w = w - eta * g
losses.append(0.5 * np.mean(resid**2))
grad_norms.append(np.linalg.norm(g))
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4.5))
ax1.semilogy(losses); ax1.set_title("Loss"); ax1.set_xlabel("Iter"); ax1.grid(True, alpha=0.3)
ax2.semilogy(grad_norms); ax2.set_title("||grad||"); ax2.set_xlabel("Iter"); ax2.grid(True, alpha=0.3)
# --- Part 2: Nonconvex check with Adam ---
def f_nonconvex(w):
x, y = w[0], w[1]
return x**4 - 3*x**2 + 0.5*x + y**4 - 2*y**2 + 0.3*y
def grad_nonconvex(w):
x, y = w[0], w[1]
return np.array([4*x**3 - 6*x + 0.5, 4*y**3 - 4*y + 0.3])
print("\n[Diagnostic] Nonconvex problem: f(x,y) = x⁴−3x²+½x + y⁴−2y²+0.3y")
print("[Diagnostic] Status: NONCONVEX — multiple local minima")
print("[Diagnostic] Method: Adam (default), η=0.05")
print("[Diagnostic] No constraints, moderate noise expected")
w = np.array([2.0, 2.0])
m = np.zeros(2); v = np.zeros(2)
eta_a, b1, b2, eps = 0.05, 0.9, 0.999, 1e-8
losses_nc = []
for t in range(1, 151):
g = grad_nonconvex(w)
m = b1*m + (1-b1)*g; v = b2*v + (1-b2)*g**2
mh = m/(1-b1**t); vh = v/(1-b2**t)
w = w - eta_a * mh/(np.sqrt(vh)+eps)
losses_nc.append(f_nonconvex(w))
ax_nc = plt.gcf().add_subplot(1, 2, 2)
# Overwrite ax2 with the nonconvex results
ax2.clear()
ax2.plot(losses_nc)
ax2.set_title("Nonconvex Loss (Adam)"); ax2.set_xlabel("Iter")
ax2.grid(True, alpha=0.3)
plt.tight_layout(); plt.show()
print(f"\n[Diagnostic] Final loss: {losses_nc[-1]:.6f}")