Optimization: gradient descent & SGD
By the end of this page you can derive the gradient-descent update from nothing but the sign of a derivative, predict for any learning rate whether it converges, oscillates or explodes, take the gradient of $\|y-X\theta\|_2^2$ by hand, and explain exactly why sampling one training point at a time still works.
ERM is a minimisation problem; this chapter is the algorithm that solves it when no closed form exists.
- The update — $\theta^{(t)} = \theta^{(t-1)} - \alpha\,\nabla_\theta J(\theta)\big|_{\theta^{(t-1)}}$. Derived from two facts: step opposite the sign of the derivative, and proportionally to its magnitude.
- Three variants — batch GD uses all $N$ gradients per update; SGD uses one index $j$ drawn uniformly at random; mini-batch averages $K$ of them, $1 < K < N$.
- Four stopping criteria — the objective stops improving; the derivative stops changing (or is small); the iterate stops moving; the compute budget runs out.
- Learning rate on $J(w)=w^2$ — $w^{(t)} = (1-2\alpha)^t w^{(0)}$, so convergence iff $|1-2\alpha| < 1 \iff 0 < \alpha < 1$. $\alpha=0.25$ converges, $\alpha=0.5$ is exact in one step, $\alpha=1$ oscillates $1,-1,1,\dots$, $\alpha=2$ diverges $1,-3,9,-27$.
- In general — for $J(w)=cw^2$, $0 < \alpha < 1/c$ with $\alpha = 1/(2c)$ exact; equivalently $\alpha < 2/L$ where $L = J''$ is the largest curvature (in $d$ dimensions, the largest eigenvalue of the Hessian).
- Gradient — $\nabla_\theta J \in \R^d$ stacks the $d$ partial derivatives; it points along steepest ascent and is perpendicular to the level sets, so $-\nabla J$ is the descent direction. This course uses denominator layout (shaped like $\theta$).
- Two identities — $\nabla_\theta(\theta^\top v) = v$ and $\nabla_\theta(\theta^\top A\theta) = (A + A^\top)\theta$, which is $2A\theta$ when $A$ is symmetric (and $X^\top X$ always is).
- Linear regression — $\nabla_\theta\|y - X\theta\|_2^2 = -2X^\top y + 2X^\top X\theta$, zero at $X^\top X\theta = X^\top y$.
- Local vs global — a local minimum is lowest in a neighbourhood; a global minimum satisfies $J(\theta)\le J(\theta')$ for all $\theta' \in \R^d$. The gradient cannot tell them apart, so the starting point decides which you reach.
- Why SGD works — the single-sample gradient is unbiased: $\E_j[\nabla_\theta\ell_j] = \nabla_\theta J(\theta)$. Averaging $K$ of them keeps it unbiased and cuts the variance to $\sigma^2/K$ at $K$ times the cost.
Everything below is the explanation and the practice. If you are short on time, read this box, then go to the problems.
ERM is an optimization problem
Every chapter so far has ended at the same door — problem formulation, decision trees, linear regression. The door is empirical risk minimization:
$$\argmin_{h\in\H}\ \sum_{i=1}^{N} \ell\!\left(h(x^{(i)}),\, y^{(i)}\right).$$$\H$ is the hypothesis class, $h$ one candidate from it, $(x^{(i)},y^{(i)})$ the $i$-th training pair (the parenthesised superscript is an index, not a power), $\ell$ the loss, and $\argmin$ returns the argument achieving the smallest value, not the value.
Notice what kind of object that is. It is not a statement about learning; it is an optimization problem. Machine learning has, at this point in the course, been entirely reduced to "minimise this function of the parameters", so the remaining question is purely computational: how do we find that minimum efficiently?
"Efficient" is load-bearing. The previous chapter's closed form $\theta^\star=(X^\top X)^{-1}X^\top y$ costs $O(Nd^2+d^3)$; at $d=10^6$ that cubic term is $10^{18}$ operations, which is not "slow" but "never". Worse, for almost any $\H$ other than a linear model the closed form does not exist at all. So: take the simplest instance of the problem, solve it completely, and generalise the algorithm that falls out.
The simplest possible case: one sample, one parameter
Strip linear regression as far as it goes: $\X=\R$, intercept $b=0$ so $h(x)=xw$ with one knob, and $N=1$ — a single training point $(x^{(1)},y^{(1)})$. ERM becomes
$$\argmin_{w}\ \underbrace{\left(y^{(1)} - x^{(1)}\!\cdot w\right)^2}_{J(w),\ \ J:\R\to\R}.$$$J$ eats a candidate weight and returns the squared error it incurs; the data are fixed constants, the parameters-are-the-variables view from the previous chapter. (The lecture notes write the weight as $\omega$; same object.) Expanding,
$$J(w) = \left(y^{(1)}\right)^2 - 2x^{(1)}y^{(1)}w + \left(x^{(1)}\right)^2 w^2,$$a constant plus a linear term plus a positive multiple of $w^2$: a parabola opening upward, with exactly one bottom and no surprises. It stays a parabola for general $N$, because a sum of upward parabolas in $w$ is another upward parabola in $w$.
The one observation the whole algorithm is built on
Stand at any point $w$ on the parabola and compute the slope $\frac{dJ(w)}{dw}$.
- Everywhere to the right of the minimiser the derivative is positive — the curve climbs as you walk right.
- Everywhere to the left of it the derivative is negative.
That is not a coincidence about this parabola; it is what "the minimum" means, plus the fact that a parabola has only one. And it is actionable, because you can compute a derivative at a single point without knowing where the minimum is.
You are on a hillside in dense fog: no map, no view of the valley floor, but you can feel the slope under your feet. "Walk downhill" needs no global knowledge at all. Gradient descent is that rule, and its famous weakness is the fog — you find a valley, not necessarily the valley (see local minima).
From the observation to an algorithm
The notes turn it into a procedure: start anywhere; if the derivative is positive move left, if negative move right; repeat until a stopping criterion fires. That answers "which way" and leaves open how far — which is where all the interesting behaviour lives.
A fixed step of $0.1$ would be terrible: start a mile away and you need forever, get within a hair of the bottom and you step straight past it, forever. We want big strides when far away and tiny ones when close — but "how far away am I" is exactly what we do not know. The picture supplies the missing information: out at the edges the tangent is nearly vertical, near the bottom nearly flat.
The magnitude of the derivative is large whenever the point is farther from the $\argmin$, and small when we are near it. So: move by an amount proportional to the magnitude of the derivative.
"Move opposite to the sign" and "move proportionally to the magnitude" are both accomplished by a single subtraction:
$$w \ \longleftarrow\ w - \alpha\,\frac{dJ(w)}{dw}.$$A derivative of $+8$ moves us $8\alpha$ left; $-0.2$ moves us $0.02\alpha$ right. The sign handles direction, the magnitude handles step length, and nothing else in the update was designed.
"The derivative is small, so I must be close to the minimum" is the motivation for the rule, not a theorem. On a very flat function you can be small-derivative and miles away; on a saddle or plateau the derivative is near zero and you are nowhere useful. The proportional step is exactly right for quadratics and approximately right near the optimum of anything smooth. It is not a distance estimate.
The gradient descent algorithm
Gradient descent (scalar case).
- Initialise to some $w^{(0)}\in\R$.
- For $t=1,2,\dots$ (until some stopping criterion is met): $$w^{(t)} \;=\; w^{(t-1)} \;-\; \alpha\,\left.\frac{dJ(w)}{dw}\right|_{w=w^{(t-1)}}$$
- Return $w^{(t)}$.
Every symbol. The superscript $(t)$ is the iteration index, not a power. $w^{(0)}$ is wherever you start, and for a parabola "any point" genuinely means any point. The vertical bar means "evaluate that derivative function at the current iterate". And $\alpha$ is a positive number we choose.
GradientDescent(J, alpha, w0):
w <- w0
for t = 1, 2, 3, ...:
g <- dJ/dw evaluated at w # one number
w <- w - alpha * g # the whole algorithm
if stopping_criterion(): break
return w
Stopping criteria
The loop says "for $t=1,2,\dots$" with no upper limit, so something has to stop it. The notes list four, and they are genuinely different tests:
The objective isn't improving much
Stop when $|J(w^{(t)}) - J(w^{(t-1)})|$ falls below a tolerance. You are measuring the thing you actually care about — but it can trigger early on a long flat plateau you would eventually have escaped.
The derivative isn't changing much
Watch the slope itself. Related and more common: stop when the slope is small, $|dJ/dw| < \varepsilon$ — that is the first-order condition for a minimum, tested numerically.
The iterate isn't moving much
Stop when $|w^{(t)} - w^{(t-1)}|$ is tiny. Careful: since the step is $\alpha\cdot$gradient, a tiny step can also mean a tiny $\alpha$ rather than a tiny gradient. This criterion is fooled by an over-decayed learning rate.
You ran out of compute
The honest one, and in deep learning the usual one. A fixed number of iterations, or a wall-clock deadline. Not a failure mode — a legitimate criterion the notes list alongside the others.
In practice you combine them: run for at most $T$ iterations, stopping early if the objective has improved by less than $10^{-6}$ for ten iterations in a row.
$\alpha$: the learning rate
$\alpha$ is the learning rate or step size, and the notes give three families of choice:
- Constant. Pick a number and keep it, e.g. $\alpha=0.01$. The default starting point.
- Decaying with the iteration number, for example $\alpha_t = \frac{1}{\sqrt{t}}$: confident strides early, cautious nudges later. The standard choice when gradients are noisy (see SGD), because a shrinking step averages the noise out instead of bouncing forever.
- Adaptive methods that tune the rate per parameter from the gradient history. beyond syllabus AdaGrad, RMSProp, Adam — what people actually run, and out of scope here.
The four learning rates, computed in full
The notes' exercise, left for the poll: let $J(w)=w^2$ and $w^{(0)}=1$. Run three iterations. What is $w^{(3)}$ for (i) $\alpha=0.25$, (ii) $\alpha=0.5$, (iii) $\alpha=1$, (iv) $\alpha=2$?
Set up once. Since $\frac{dJ}{dw} = 2w$, the update $w^{(t)} = w^{(t-1)} - \alpha\cdot 2w^{(t-1)}$ factors:
$$\boxed{\ w^{(t)} = w^{(t-1)}\,(1-2\alpha).\ }$$Each iteration multiplies the iterate by the same contraction factor $1-2\alpha$, so $w^{(t)} = (1-2\alpha)^t w^{(0)}$ and $w^{(3)} = (1-2\alpha)^3$. Everything about the behaviour is in that one number — but grind through the arithmetic anyway, because the shape of the numbers is the lesson.
| $\alpha$ | factor $1-2\alpha$ | $w^{(0)}$ | step 1 | $w^{(1)}$ | step 2 | $w^{(2)}$ | step 3 | $w^{(3)}$ | $J(w^{(3)})$ | verdict |
|---|---|---|---|---|---|---|---|---|---|---|
| $0.25$ | $0.5$ | $1$ | $1-0.25(2)$ | $0.5$ | $0.5-0.25(1)$ | $0.25$ | $0.25-0.25(0.5)$ | $\mathbf{0.125}$ | $0.015625$ | converging |
| $0.5$ | $0$ | $1$ | $1-0.5(2)$ | $0$ | $0-0.5(0)$ | $0$ | $0-0.5(0)$ | $\mathbf{0}$ | $0$ | exact, in one step |
| $1$ | $-1$ | $1$ | $1-1(2)$ | $-1$ | $-1-1(-2)$ | $1$ | $1-1(2)$ | $\mathbf{-1}$ | $1$ | oscillates forever |
| $2$ | $-3$ | $1$ | $1-2(2)$ | $-3$ | $-3-2(-6)$ | $9$ | $9-2(18)$ | $\mathbf{-27}$ | $729$ | diverges |
Read the "step" columns as $w^{(t-1)} - \alpha\cdot 2w^{(t-1)}$, with the derivative $2w^{(t-1)}$ shown in the parentheses. Row four, step 2: the iterate is $-3$, the derivative there is $2(-3)=-6$, so $-3 - 2(-6) = 9$.
What each case is telling you
(i) $\alpha=0.25$ — healthy convergence. Factor $0.5$, so every step halves the distance: $1, \tfrac12, \tfrac14, \tfrac18, \dots$. It never exactly arrives — convergence is geometric — but a stopping criterion fires long before that matters.
(ii) $\alpha=0.5$ — the bullseye. Factor exactly $0$: we land on the minimiser in one step and stay (the gradient at $0$ is $0$, so later steps do nothing). This is possible because for a quadratic the "proportional to the derivative" heuristic is exact: for $J(w)=cw^2$ the derivative at $w$ is $2cw$, so the distance to the minimum is exactly $\frac{1}{2c}$ times the derivative, and $\alpha=\frac{1}{2c}$ makes the step precisely that distance. (Dividing the gradient by the second derivative instead of guessing $\alpha$ is Newton's method beyond syllabus; it hits the same $d^3$ wall as the closed form, because the second derivative is a $d\times d$ matrix.)
(iii) $\alpha=1$ — perpetual oscillation. Factor $-1$: every step flips the sign and preserves the magnitude, $1 \to -1 \to 1 \to -1$ forever. The direction is right every time, but we overshoot by exactly twice the distance to the minimum, landing at the mirror point with the mirror gradient. $J$ never decreases, and neither the improvement criterion nor the $|w^{(t)}-w^{(t-1)}|$ criterion will ever fire.
(iv) $\alpha=2$ — divergence. Factor $-3$: each step flips the sign and triples the magnitude, $1\to-3\to9\to-27\to81$, with $J$ going $1\to 9\to 81\to 729$. In floating point this becomes inf and then NaN within a few dozen iterations; a training loss printing nan is almost always this, in a thousand dimensions.
Reading case (iv) as "$\alpha$ was too big, so we overshot a little". The failure is not one sloppy step; the process is unstable. Each overshoot lands somewhere with a larger gradient, which produces a larger next step: the error is multiplied by $3$ every iteration. Halving $\alpha$ from $2$ to $1$ does not fix it either (that is case iii). Stability needs $\alpha$ below a hard threshold, derived next.
The convergence condition, derived
We have the exact solution of the recursion: $w^{(t)} = (1-2\alpha)^t\,w^{(0)}$.
For $w^{(t)}\to 0$ as $t\to\infty$, from an arbitrary starting point $w^{(0)}\neq 0$, we need the geometric factor to shrink:
$$|1-2\alpha| < 1.$$Unwrap the absolute value: $-1 < 1-2\alpha < 1$. Subtract $1$ throughout: $-2 < -2\alpha < 0$. Divide by $-2$, which reverses both inequalities: $1 > \alpha > 0$. So
$$\boxed{\,0 < \alpha < 1\,}$$and the four cases check out: $0.25$ and $0.5$ are inside, $\alpha=1$ sits exactly on the boundary where $|1-2\alpha|=1$ (no decay, no growth — the oscillation), and $\alpha=2$ gives $|1-2\alpha|=3>1$, divergence. $\blacksquare$
Generalise to $J(w)=cw^2$ with $c>0$. Now $\frac{dJ}{dw}=2cw$, the update is $w^{(t)}=w^{(t-1)}(1-2\alpha c)$, and the same argument gives $|1-2\alpha c| < 1$, i.e.
$$0 < \alpha < \frac{1}{c},$$with the midpoint $\alpha=\frac{1}{2c}$ converging in one step. Sharper curvature forces smaller steps — a narrow steep valley must be walked carefully.
Writing the curvature as the second derivative $L = J'' = 2c$, the condition $\alpha < 1/c$ reads
$$\alpha < \frac{2}{L},$$and this is the form that generalises: for any $L$-smooth function (one whose gradient satisfies $\|\nabla J(u)-\nabla J(v)\|\le L\|u-v\|$), gradient descent with $\alpha < 2/L$ is stable and $\alpha = 1/L$ is the standard safe choice. $L$ is the largest curvature anywhere in the landscape — in $d$ dimensions the largest eigenvalue of the Hessian, which for linear regression is the largest eigenvalue of $\frac{2}{N}X^\top X$.
$J(w)=w^2$, $w^{(0)}=1$, three iterations of gradient descent. Find $w^{(3)}$ for $\alpha\in\{0.25,\ 0.5,\ 1,\ 2\}$, classify each behaviour, and state the exact set of $\alpha$ for which this run converges. Try it on paper before opening anything.
Step 1 — Write the update concretely before plugging in any number
Do the calculus once, not four times. $J(w)=w^2 \Rightarrow \frac{dJ}{dw}=2w$. Substituting into $w^{(t)}=w^{(t-1)}-\alpha\frac{dJ}{dw}\big|_{w^{(t-1)}}$:
$$w^{(t)} = w^{(t-1)} - 2\alpha w^{(t-1)} = (1-2\alpha)\,w^{(t-1)}.$$This is the single most useful line in the problem. It says the iteration is just repeated multiplication by the constant $r=1-2\alpha$, so $w^{(3)} = r^3 w^{(0)} = r^3$.
Step 2 — $\alpha=0.25$ and $\alpha=0.5$
$\alpha=0.25$: $r = 1-0.5 = 0.5$.
$w^{(1)} = 1 - 0.25\cdot 2(1) = 1-0.5 = 0.5$. $w^{(2)} = 0.5 - 0.25\cdot 2(0.5) = 0.5-0.25 = 0.25$. $w^{(3)} = 0.25 - 0.25\cdot 2(0.25) = 0.25-0.125 = \mathbf{0.125}$.
Check against the shortcut: $0.5^3 = 0.125$. ✓ Halving each time — converging.
$\alpha=0.5$: $r = 1-1 = 0$.
$w^{(1)} = 1 - 0.5\cdot2(1) = 1-1 = 0$. The gradient at $w=0$ is $2(0)=0$, so $w^{(2)} = 0 - 0.5(0) = 0$ and $w^{(3)}=\mathbf{0}$. Exact minimiser after one step, and it stays there — a zero gradient is a fixed point of the update, which is the algorithmic meaning of "we're done".
Step 3 — $\alpha=1$ and $\alpha=2$ (do the signs slowly)
$\alpha=1$: $r = 1-2 = -1$.
$w^{(1)} = 1 - 1\cdot 2(1) = 1-2 = -1$. Now the derivative at $-1$ is $2(-1)=-2$, so $w^{(2)} = -1 - 1(-2) = -1+2 = 1$. And $w^{(3)} = 1-2 = \mathbf{-1}$.
Cycle of period two: $1,-1,1,-1$. $J$ equals $1$ at every single iterate — zero progress, forever.
$\alpha=2$: $r = 1-4 = -3$.
$w^{(1)} = 1 - 2\cdot2(1) = 1-4 = -3$. Derivative at $-3$ is $-6$: $w^{(2)} = -3 - 2(-6) = -3+12 = 9$. Derivative at $9$ is $18$: $w^{(3)} = 9 - 2(18) = 9-36 = \mathbf{-27}$.
Check: $(-3)^3 = -27$ ✓. The objective went $1 \to 9 \to 81 \to 729$. Diverging.
Step 4 — the general condition
$w^{(t)} = (1-2\alpha)^t$ tends to $0$ exactly when $|1-2\alpha|<1$. Solving: $-1 < 1-2\alpha < 1 \Rightarrow -2 < -2\alpha < 0 \Rightarrow 0 < \alpha < 1$ (dividing by $-2$ flips the inequalities).
Within that window, smaller $|1-2\alpha|$ means faster convergence, so $\alpha=0.5$ is optimal and convergence degrades symmetrically as you move toward either $0$ or $1$. Note that $\alpha=0.1$ and $\alpha=0.9$ converge at exactly the same rate ($|r|=0.8$) — but $\alpha=0.9$ does it by oscillating across the minimum while $\alpha=0.1$ creeps in from one side.
Answer & the takeaway
$w^{(3)} = 0.125,\ 0,\ -1,\ -27$ respectively. Converging / exact / oscillating / diverging. Convergence iff $0<\alpha<1$.
Takeaway: the learning rate is not a tuning detail, it is the difference between an algorithm that works, an algorithm that spins in place, and an algorithm that destroys itself — on a function with one minimum and no pathologies. The threshold is set by the curvature: $\alpha < 2/L$ with $L=J''$. Everything else in this chapter is a variation on this one computation.
Why this already works for all $N$
Everything so far was derived on a single sample. With $N$ samples (still $\X=\R$, still $b=0$) the objective is the mean squared error
$$J(w) \;=\; \frac{1}{N}\sum_{i=1}^{N}\left(y^{(i)} - x^{(i)}w\right)^2.$$Expand the square inside the sum and collect powers of $w$:
$$J(w) \;=\; \underbrace{\frac{1}{N}\sum_i \left(x^{(i)}\right)^2}_{\textstyle c}\; w^2 \;-\; 2\underbrace{\frac{1}{N}\sum_i x^{(i)}y^{(i)}}_{\textstyle m}\; w \;+\; \underbrace{\frac{1}{N}\sum_i \left(y^{(i)}\right)^2}_{\textstyle k}.$$That is $J(w) = cw^2 - 2mw + k$: a parabola again, opening upward because $c$ is a sum of squares. So the single-sample analysis transfers verbatim — same update, same sign argument, same threshold $\alpha < 1/c$ — only now $c$ is the mean squared input.
Two flags. $c$ depends on the scale of your features: multiply every $x^{(i)}$ by $1000$ and $c$ grows by $10^6$, so the largest safe $\alpha$ shrinks by $10^6$ — which is why people standardise features before running gradient descent (see feature engineering). And the previous chapter's corner case reappears: if $\sum_i (x^{(i)})^2 = 0$ then $c=0$, $J$ is flat, the gradient is $0$ everywhere, and gradient descent returns whatever $w^{(0)}$ you typed. The closed form reported that by dividing by zero; both are saying "the data does not determine $w$".
We developed gradient descent on a parabola because that is where it is easiest to see why it works. But nothing in the algorithm ever used the parabola — it used a derivative. "Evaluate the slope where you stand, step against it" is meaningful for any differentiable $J$, which is why this algorithm scales to networks with billions of parameters whose loss surfaces have, as the notes put it, crazy shapes.
Three training points, $b=0$, so $h(x)=xw$: $(x,y) = (1,2),\ (2,3),\ (3,5)$.
(a) Write $J(w)=\frac13\sum_i (y^{(i)}-x^{(i)}w)^2$ as a parabola $cw^2 - 2mw + k$. (b) What is the largest stable learning rate? (c) Starting from $w^{(0)}=0$ with $\alpha=0.1$, compute $w^{(1)}$ and $w^{(2)}$. (d) Where is it heading, and does that agree with the closed form from the previous chapter?
Step 1 — Build the parabola
$\sum_i (x^{(i)})^2 = 1 + 4 + 9 = 14$, so $c = 14/3$. $\sum_i x^{(i)}y^{(i)} = 1(2)+2(3)+3(5) = 2+6+15 = 23$, so $m = 23/3$. $\sum_i (y^{(i)})^2 = 4+9+25 = 38$, so $k = 38/3$.
$$J(w) = \tfrac{14}{3}w^2 - \tfrac{46}{3}w + \tfrac{38}{3}, \qquad \frac{dJ}{dw} = \tfrac{28}{3}w - \tfrac{46}{3}.$$(The $-2m$ coefficient is $-2\cdot\frac{23}{3} = -\frac{46}{3}$ — don't drop that factor of 2.)
Step 2 — The stability threshold
Curvature $L = J'' = \frac{28}{3} \approx 9.33$. The condition $\alpha < 2/L$ gives
$$\alpha < \frac{2}{28/3} = \frac{6}{28} = \frac{3}{14} \approx 0.214.$$Equivalently $\alpha < 1/c = 3/14$. Same number, as it must be. So $\alpha = 0.1$ is safely inside; $\alpha=0.25$ would diverge, and $\alpha = 3/28 \approx 0.107$ would hit the minimum in a single step.
Step 3 — Two iterations, arithmetic shown
Iteration 1. At $w^{(0)}=0$: $\frac{dJ}{dw} = \frac{28}{3}(0) - \frac{46}{3} = -\frac{46}{3} \approx -15.33$. Negative slope, so we should move right — and indeed
$$w^{(1)} = 0 - 0.1\left(-\tfrac{46}{3}\right) = \tfrac{46}{30} = \tfrac{23}{15} \approx 1.5333.$$Iteration 2. At $w^{(1)}=\frac{23}{15}$: $\frac{dJ}{dw} = \frac{28}{3}\cdot\frac{23}{15} - \frac{46}{3} = \frac{644}{45} - \frac{690}{45} = -\frac{46}{45} \approx -1.022$. Still negative but fifteen times smaller — we are much closer now, exactly as the magnitude argument predicted.
$$w^{(2)} = \tfrac{23}{15} - 0.1\left(-\tfrac{46}{45}\right) = \tfrac{23}{15} + \tfrac{46}{450} = \tfrac{368}{225} \approx 1.6356.$$Answer & the takeaway
Continuing: $w^{(3)} \approx 1.64237$, $w^{(4)} \approx 1.642825$, $w^{(5)} \approx 1.6428550$. The closed form from the previous chapter is
$$w^\star = \frac{\sum_i x^{(i)}y^{(i)}}{\sum_i (x^{(i)})^2} = \frac{23}{14} = 1.642857\ldots$$Gradient descent is converging to the closed-form answer, gaining roughly one decimal digit per iteration (each step multiplies the remaining error by $|1-2\alpha c| = |1 - 0.1\cdot\frac{28}{3}| \approx 0.0667$).
Takeaway: on a problem this small, gradient descent is strictly worse than the closed form — it gives an approximation after five steps where division gave the exact answer immediately. That is the honest comparison, and it is why the closed form is still what you use for small linear regression. Gradient descent earns its keep when $d$ is large enough that the $d^3$ matrix inverse is impossible, or when $\H$ is anything other than linear so no closed form exists at all.
Multivariate calculus: what a gradient is
Real problems have many parameters. Extend to $\X=\R^d$ and a general objective $J:\R^d\to\R$ consuming a parameter vector $\theta$ and returning one number. Before running the algorithm we need to know what replaces $dJ/dw$.
In the scalar case $\frac{\partial J(\theta)}{\partial\theta} \in \R$: one input, one derivative. When $J:\R^d\to\R$ there are $d$ inputs, so $d$ partial derivatives, stacked into a column:
$$\frac{\partial J(\theta)}{\partial \theta} \;=\; \begin{bmatrix} \dfrac{\partial J(\theta)}{\partial \theta_1} \\[6pt] \dfrac{\partial J(\theta)}{\partial \theta_2} \\[2pt] \vdots \\[2pt] \dfrac{\partial J(\theta)}{\partial \theta_d} \end{bmatrix} \;\in\; \R^d.$$This vector is the gradient of $J$, written $\nabla_\theta J(\theta)$ or $\nabla J$. Its $j$-th entry answers one narrow question: if I nudge parameter $j$ alone and freeze the others, how fast does $J$ change? The gradient is all $d$ of those answers collected in one place.
What the gradient means geometrically
Picture $J$ as a landscape, with $\theta=(\theta_1,\theta_2)$ a map coordinate and $J(\theta)$ the altitude, and draw its level sets (contours of constant altitude) as on a topographic map.
- $\nabla J(\theta)$ points in the direction of steepest ascent: of all directions you could step, that one increases $J$ fastest, and its length $\|\nabla J\|$ is how fast.
- Therefore $-\nabla J(\theta)$ is the direction of steepest descent. That is the direction gradient descent walks.
- The gradient is perpendicular to the level set through that point. Walking along a contour does not change altitude, so the rate of change in that direction is zero, so the gradient has no component along it.
A ball dropped on the landscape rolls along $-\nabla J$ — honest about steepest descent being a purely local choice. It breaks in two places: a real ball has momentum and can roll up out of a shallow dip, while plain gradient descent has no memory (adding momentum is a standard fix beyond syllabus); and a ball moves continuously, while gradient descent teleports in jumps of length $\alpha\|\nabla J\|$, which is how too large an $\alpha$ can jump clean across a valley.
The two identities you need — both proved
These two are the only gradient formulas linear regression needs, and both are proved the same way: write out a single coordinate as an ordinary scalar partial derivative, differentiate with high-school rules, then recognise the resulting vector. That technique works for every matrix-calculus identity you will meet.
(i) If $J(\theta) = \theta^\top v$ for some fixed $v\in\R^d$, then $\nabla_\theta J(\theta) = v$.
Written out with explicit sums, the inner product is
$$J(\theta) = \theta^\top v = \sum_{k=1}^{d} \theta_k v_k = \theta_1v_1 + \theta_2v_2 + \dots + \theta_dv_d.$$Take the partial derivative with respect to one particular coordinate $\theta_j$. Every term $\theta_kv_k$ with $k\neq j$ contains no $\theta_j$, so it is a constant and dies. The one surviving term is $\theta_jv_j$, whose derivative is $v_j$:
$$\frac{\partial J}{\partial \theta_j} = \frac{\partial}{\partial\theta_j}\sum_{k=1}^d \theta_kv_k = v_j.$$Now stack over $j=1,\dots,d$: the vector whose $j$-th entry is $v_j$ is $v$ itself. Hence $\nabla_\theta J = v$. $\blacksquare$
Sanity check in one dimension: $J(\theta)=\theta v$ is a line of slope $v$, and its derivative is $v$. The identity is the exact analogue — $\theta^\top v$ is the multidimensional straight line, and its gradient is the constant vector of slopes.
(ii) If $J(\theta) = \theta^\top A\theta$ for some fixed $A\in\R^{d\times d}$, then $\nabla_\theta J(\theta) = (A + A^\top)\theta$.
The quadratic form written as a double sum:
$$J(\theta) = \theta^\top A\theta = \sum_{k=1}^{d}\sum_{l=1}^{d} A_{kl}\,\theta_k\theta_l.$$Differentiate with respect to $\theta_j$. A term $A_{kl}\theta_k\theta_l$ survives only if it contains $\theta_j$, which happens in three situations:
- $k=j$ and $l\neq j$: the term is $A_{jl}\theta_j\theta_l$, and $\frac{\partial}{\partial\theta_j} = A_{jl}\theta_l$.
- $l=j$ and $k\neq j$: the term is $A_{kj}\theta_k\theta_j$, and $\frac{\partial}{\partial\theta_j} = A_{kj}\theta_k$.
- $k=l=j$: the term is $A_{jj}\theta_j^2$, and $\frac{\partial}{\partial\theta_j} = 2A_{jj}\theta_j$ by the power rule.
The third case is exactly what you get by letting $l=j$ in the first sum and $k=j$ in the second (giving $A_{jj}\theta_j + A_{jj}\theta_j$), so we can fold all three cases into two unrestricted sums:
$$\frac{\partial J}{\partial\theta_j} = \sum_{l=1}^{d} A_{jl}\theta_l \;+\; \sum_{k=1}^{d} A_{kj}\theta_k.$$Read each piece. $\sum_l A_{jl}\theta_l$ is row $j$ of $A$ dotted with $\theta$ — the $j$-th entry of $A\theta$. And $\sum_k A_{kj}\theta_k$ is column $j$ of $A$ dotted with $\theta$ — which is row $j$ of $A^\top$ dotted with $\theta$, the $j$-th entry of $A^\top\theta$. So
$$\frac{\partial J}{\partial\theta_j} = (A\theta)_j + (A^\top\theta)_j = \left((A+A^\top)\theta\right)_j,$$and stacking over all $j$ gives $\nabla_\theta J(\theta) = (A+A^\top)\theta$. $\blacksquare$
The symmetric special case. If $A$ is symmetric, meaning $A^\top = A$, then $(A+A^\top)\theta = 2A\theta$ and the identity collapses to
$$\nabla_\theta\,\theta^\top A\theta = 2A\theta,$$which is the perfect analogue of the scalar $\frac{d}{dw}(cw^2) = 2cw$. And this is not a rare case for us: $X^\top X$ is always symmetric, for any matrix $X$ whatsoever, because $(X^\top X)^\top = X^\top (X^\top)^\top = X^\top X$. The matrix sitting in the middle of the linear-regression objective is guaranteed to be of exactly the form that makes this identity simple.
Shapes, and which layout a formula is written in
More generally you may need $\frac{\partial J(\theta)}{\partial\theta}$ where $\theta$ and the output of $J$ are each a scalar, a vector or a matrix. Do not memorise a table of cases; remember what the notes say:
$\frac{\partial J(\theta)}{\partial \theta}$ is simply a collection of scalar-by-scalar partial derivatives: the partial derivative of each coordinate of the output with respect to each coordinate of the input, then arranged in some shape — a vector for $\nabla_\theta J(\theta)$, a matrix when both sides are vectors, and so on.
The content is never in doubt, only the arrangement, and there are two conventions:
- Denominator layout (this course, and the more popular convention in ML): the result is shaped like the denominator, i.e. like $\theta$ — a $d\times1$ column for $J:\R^d\to\R$.
- Numerator layout: shaped like the numerator, i.e. like $J$ — the same object as a $1\times d$ row.
With $d=3$, $J(\theta)=\theta^\top v$ and $v=(4,5,6)^\top$, the three scalar partials are $4,5,6$ in both conventions; only the stacking differs:
Shaped like $\theta$ ($3\times1$):
$$\frac{\partial J}{\partial\theta} = \begin{bmatrix}4\\5\\6\end{bmatrix}$$Update reads $\theta \leftarrow \theta - \alpha\nabla_\theta J$ — a column minus a column. Shapes just work.
Shaped like $J$ ($1\times3$):
$$\frac{\partial J}{\partial\theta} = \begin{bmatrix}4&5&6\end{bmatrix}$$Update needs a transpose: $\theta \leftarrow \theta - \alpha\left(\frac{\partial J}{\partial\theta}\right)^\top$.
How to tell at a glance: check a known identity — a source writing $\nabla_\theta(\theta^\top A\theta) = \theta^\top(A+A^\top)$ (a row) is in numerator layout; our $(A+A^\top)\theta$ (a column) is denominator layout. They differ by a transpose and nothing else, so nobody is wrong — but mixing them mid-derivation produces maddening shape errors.
Back to optimization: linear regression in matrix form
Take $\X=\R^d$, $\Y=\R$, and ERM for linear regression as the previous chapter left it, with samples as rows of $X\in\R^{N\times d}$ and labels in $y\in\R^N$:
$$\argmin_\theta \|y - X\theta\|_2^2 \;=\; \argmin_\theta\, (y-X\theta)^\top(y-X\theta) \;=\; \argmin_\theta\, \underbrace{y^\top y - 2\theta^\top X^\top y + \theta^\top X^\top X\theta}_{J(\theta)}.$$The middle step is the definition $\|v\|_2^2 = v^\top v$; the last multiplies out, with the two cross terms $-y^\top X\theta$ and $-\theta^\top X^\top y$ each $1\times1$ — scalars equal to their own transposes, hence the same number — combining into $-2\theta^\top X^\top y$.
$J$ is a bowl, and we want $\nabla_\theta J(\theta)=0$. Differentiate term by term:
- $y^\top y$ contains no $\theta$. Gradient: $\mathbf{0}$.
- $-2\theta^\top X^\top y$ has the form $\theta^\top v$ with $v = -2X^\top y$. By identity (i), gradient: $-2X^\top y$.
- $\theta^\top X^\top X\theta$ has the form $\theta^\top A\theta$ with $A = X^\top X$, symmetric. By identity (ii), gradient: $2X^\top X\theta$.
Setting it to zero:
$$-2X^\top y + 2X^\top X\theta = 0 \;\Longrightarrow\; X^\top X\theta = X^\top y \;\Longrightarrow\; \theta^\star = (X^\top X)^{-1}X^\top y,$$assuming $X^\top X$ is invertible, which requires $X$ to have full column rank.
Two routes, one answer. The previous chapter got this same $\theta^\star$ by completing the square, with no calculus, and that route proves the point is a global minimum. The calculus route is shorter but proves less: setting a gradient to zero finds a stationary point, which could be a maximum or a saddle. They agree because $X^\top X$ is positive semi-definite, so the only stationary points of this bowl are minima.
Why this is a lucky accident, not the general situation
Setting the gradient to zero produced an equation we could solve exactly because the gradient was linear in $\theta$ — and it was linear because $J$ was quadratic. Most problems are not like this: set the gradient of a neural network's loss to zero and you get millions of coupled nonlinear equations with no solution formula. Gradient descent works there because it never needs to solve $\nabla J = 0$; it only needs to evaluate $\nabla J$ where it stands, and evaluation is always possible.
Gradient descent for a general $J:\R^d\to\R$.
- Initialise $\theta^{(0)}\in\R^d$.
- For $t=1,2,\dots$ (until some stopping criterion is met): $$\theta^{(t)} = \theta^{(t-1)} - \alpha\,\nabla_\theta J(\theta)\big|_{\theta=\theta^{(t-1)}}$$
- Return $\theta^{(t)}$.
Line for line the same algorithm as the scalar version. The only change is that $w$ became a vector $\theta$ and the derivative became a gradient — so the update now moves all $d$ coordinates at once, each by its own partial derivative times the same $\alpha$.
Local minima, global minima, and getting stuck
Gradient descent may not find the optimal solution unless the function takes some special form (like our bowl). It may get stuck in a local minimum. The notes' definitions, exactly:
Local minimum. A value of $\theta\in\R^d$ which is the lowest in its neighbourhood — but there could be points $\theta'$ farther away which are lower.
Global minimum. A value of $\theta$ that minimises the function: $J(\theta) \le J(\theta')$ for every $\theta'\in\R^d$.
Note the asymmetry: "local" quantifies over a neighbourhood, "global" over all of $\R^d$. Every global minimum is local; the converse fails. And the gradient cannot tell the difference — at a local minimum $\nabla J = 0$ and the surface curves upward in every direction, exactly what a global minimum looks like from up close. In the fog, a small dip and the deepest valley feel identical.
So where you start determines where you end. Two starting points on opposite sides of a ridge slide into different basins with different final losses. That is not randomness — plain gradient descent is deterministic — it is sensitivity to the initialisation. Try it In Figure 2, press Function for the multi-minimum landscape and move the start slider: $w^{(0)}=-2.5$ ends in the deep left valley, $w^{(0)}=2.0$ in the shallower right one.
Saddle points and convexity, briefly
Saddle points. beyond syllabus The gradient vanishes, but the point is a minimum along some directions and a maximum along others. Gradient descent crawls near one without being trapped, and eventually escapes downhill. In high dimensions saddles vastly outnumber local minima — a local minimum needs all $d$ curvature directions pointing up, a demanding coincidence when $d$ is a million — so the practical enemy in deep learning is saddles and flat plateaus, not bad local minima.
Convex problems. beyond syllabus A function is convex if the chord between any two points on its graph lies on or above the graph; bowls, parabolas and $\|y-X\theta\|_2^2$ all qualify. A convex function has no bad local minima: every local minimum is global. That is why gradient descent on linear regression converges to the same answer from every start. Logistic regression is also convex; neural networks emphatically are not.
Gradient descent may get stuck at a local minimum that is not global, and is still very popular, because it finds a good solution efficiently. That is the pragmatic bargain at the heart of modern ML: an approximate answer you can compute beats an exact one you cannot. Nobody training a large model believes they found the global optimum; the model works anyway.
NaN, not $0.047$. This is also why serious papers report a mean and a standard deviation over several seeds rather than a single number.Three points with an intercept, so $x^{(i)} = (1,\ \text{feature})^\top$ and $\theta=(b,w)^\top$:
$$X = \begin{bmatrix}1&1\\1&2\\1&3\end{bmatrix},\qquad y=\begin{bmatrix}2\\3\\5\end{bmatrix}.$$(a) Compute $X^\top X$ and $X^\top y$. (b) Write $\nabla_\theta J(\theta)$ for $J(\theta)=\|y-X\theta\|_2^2$. (c) Take two gradient-descent steps from $\theta^{(0)}=(0,0)^\top$ with $\alpha=0.02$. (d) Compare to the closed form.
Step 1 — The two matrix products
$X^\top X$ is $2\times2$. Entry $(1,1)$ is column 1 dotted with itself: $1+1+1=3$. Entry $(1,2)=(2,1)$ is column 1 dotted with column 2: $1+2+3=6$. Entry $(2,2)$ is column 2 with itself: $1+4+9=14$.
$$X^\top X = \begin{bmatrix}3&6\\6&14\end{bmatrix} \quad\text{(symmetric, as promised)},\qquad X^\top y = \begin{bmatrix}2+3+5\\ 1(2)+2(3)+3(5)\end{bmatrix} = \begin{bmatrix}10\\23\end{bmatrix}.$$Step 2 — The gradient, instantiated
Plug into $\nabla_\theta J(\theta) = -2X^\top y + 2X^\top X\theta$:
$$\nabla_\theta J(\theta) = -2\begin{bmatrix}10\\23\end{bmatrix} + 2\begin{bmatrix}3&6\\6&14\end{bmatrix}\begin{bmatrix}b\\w\end{bmatrix} = \begin{bmatrix}-20 + 6b + 12w\\ -46 + 12b + 28w\end{bmatrix}.$$Both entries are linear in $\theta$ — that linearity is the whole reason a closed form exists here.
Step 3 — Two steps of arithmetic
Step 1. At $\theta^{(0)}=(0,0)$ the gradient is $(-20,-46)^\top$. Both components negative, so both parameters increase:
$$\theta^{(1)} = \begin{bmatrix}0\\0\end{bmatrix} - 0.02\begin{bmatrix}-20\\-46\end{bmatrix} = \begin{bmatrix}0.4\\0.92\end{bmatrix}.$$Step 2. At $\theta^{(1)}$: first component $-20 + 6(0.4) + 12(0.92) = -20 + 2.4 + 11.04 = -6.56$; second $-46 + 12(0.4) + 28(0.92) = -46 + 4.8 + 25.76 = -15.44$.
$$\theta^{(2)} = \begin{bmatrix}0.4\\0.92\end{bmatrix} - 0.02\begin{bmatrix}-6.56\\-15.44\end{bmatrix} = \begin{bmatrix}0.4+0.1312\\0.92+0.3088\end{bmatrix} = \begin{bmatrix}0.5312\\1.2288\end{bmatrix}.$$Both gradient components shrank by about two thirds. We are heading in.
Answer & the takeaway
Closed form: $\det(X^\top X) = 3(14)-6(6) = 6$, so $(X^\top X)^{-1} = \frac16\begin{bmatrix}14&-6\\-6&3\end{bmatrix}$ and
$$\theta^\star = \frac16\begin{bmatrix}14&-6\\-6&3\end{bmatrix}\begin{bmatrix}10\\23\end{bmatrix} = \frac16\begin{bmatrix}140-138\\-60+69\end{bmatrix} = \frac16\begin{bmatrix}2\\9\end{bmatrix} = \begin{bmatrix}1/3\\3/2\end{bmatrix}.$$After two steps we are at $(0.53, 1.23)$ against a target of $(0.33, 1.50)$ — the right neighbourhood, not the right answer. Continuing takes a while, and here is why: the Hessian is $2X^\top X$ with eigenvalues $\approx 33.3$ and $\approx 0.72$. Stability demands $\alpha < 2/33.3 \approx 0.060$, but progress along the flat direction happens at rate $\alpha \cdot 0.72 \approx 0.014$ per step. A condition number of $33.3/0.72\approx 46$ means roughly 46 times more iterations than a round bowl would need.
Takeaway: this is the zig-zag figure in numbers. The intercept column of all-ones and the feature column of $1,2,3$ are strongly correlated, which stretches the bowl. Centering the feature (subtracting its mean) would decorrelate the columns and shrink the condition number dramatically — a cheap fix, and a preview of feature engineering.
Batch gradient descent, and the problem with it
ERM once more, with the average and a general hypothesis:
$$\argmin_\theta\ \frac{1}{N}\sum_{i=1}^{N} \ell\!\left(h_\theta(x^{(i)}),\, y^{(i)}\right)$$where $h_\theta(x) = \theta^\top x$ for linear regression, but $h_\theta$ could be a neural network — all we need is that $\ell$ is differentiable in $\theta$. Because the objective is a sum and differentiation is linear, the gradient is a sum too:
$$\nabla_\theta J(\theta) = \frac{1}{N}\sum_{i=1}^{N} \nabla_\theta\,\ell\!\left(h_\theta(x^{(i)}), y^{(i)}\right).$$So to take one step the algorithm must compute a gradient for every single training example and average them. Gradient descent applied to ERM is therefore also called batch gradient descent: all $N$ samples per update.
Problem. Suppose $N$ is large. Then gradient descent has to compute $\nabla_\theta \ell(h_\theta(x^{(i)}),y^{(i)})$ for every $i\in\{1,\dots,N\}$ in order to make any update to the iterate $\theta^{(t-1)}$. This makes it slow.
Put numbers on it: at ImageNet scale, $N = 1{,}280{,}000$ images at about $0.5$ ms per forward-and-backward pass, one full gradient costs $1{,}280{,}000 \times 0.5\,\text{ms} \approx 640$ s $\approx 10.7$ minutes — and that buys one update. Ten thousand steps would take 74 days. It is also wasteful: the first thousand images already said roughly which way is downhill, and the remaining 1.279 million only refine that into the exact average, which you then multiply by $\alpha=0.001$ and immediately invalidate by moving. We compute a very precise number and barely use it.
Idea: take gradients of just one sample at a time for each update. You get a much worse estimate of the descent direction — but you get it $N$ times faster, so you can take $N$ steps in the time the batch version takes one. Trading accuracy per step for number of steps turns out to be an overwhelmingly good trade.
Stochastic gradient descent
Stochastic gradient descent (SGD).
- Initialise $\theta^{(0)}\in\R^d$.
- For $t=1,2,\dots$ (until some stopping criterion is met):
- Choose $j \in \text{Uniform-Random}\{1,2,\dots,N\}$.
- $\theta^{(t)} = \theta^{(t-1)} - \alpha\,\nabla_\theta\,\ell\!\left(h_\theta(x^{(j)}), y^{(j)}\right)$.
- Return $\theta^{(t)}$.
"Stochastic" is the whole difference: the index $j$ is drawn at random, fresh, every iteration. The update uses the gradient of the loss on that one sample, as if it were the entire training set.
The cost per update drops by a factor of $N$. On the ImageNet numbers, an SGD update costs $0.5$ ms instead of $10.7$ minutes, so in the time batch GD makes one step SGD makes $1{,}280{,}000$. As the notes put it: a very noisy version of the full gradient, but fast to compute.
Why does this work at all?
A single random training point is a terrible summary of a dataset, so why doesn't following it just wander? Because the single-sample gradient is an unbiased estimate of the full gradient: wrong on any given step, but right on average, with no systematic lean.
Write $g_j = \nabla_\theta\,\ell(h_\theta(x^{(j)}), y^{(j)})$ and let $j$ be drawn uniformly from $\{1,\dots,N\}$, so $\Pr[j=i] = \frac1N$. Then by the definition of expectation,
$$\E_j\!\left[g_j\right] \;=\; \sum_{i=1}^{N}\Pr[j=i]\; g_i \;=\; \sum_{i=1}^{N}\frac{1}{N}\,g_i \;=\; \frac{1}{N}\sum_{i=1}^{N}\nabla_\theta\,\ell\!\left(h_\theta(x^{(i)}),y^{(i)}\right) \;=\; \nabla_\theta J(\theta). \qquad\blacksquare$$The uniform draw is exactly what makes the middle equality hold: each sample's gradient gets weight $\frac1N$, precisely how the ERM average weights it. Sampling non-uniformly (always preferring hard examples, say) breaks unbiasedness unless you reweight to compensate.
Write the stochastic gradient as truth plus noise, $g_j = \nabla J(\theta) + \varepsilon_j$ with $\E[\varepsilon_j]=0$. An SGD step is then a true gradient step plus a random kick. Over many steps the kicks partially cancel while the true-gradient parts accumulate, so the drift is downhill even though individual steps may go uphill. But the kicks do not vanish near the minimum — a single sample's gradient is generally nonzero even at $\theta^\star$ — so SGD with constant $\alpha$ does not converge to a point; it bounces inside a ball of radius roughly proportional to $\alpha$. That is exactly why $\alpha_t = 1/\sqrt{t}$ schedules exist: shrink the kicks and the ball shrinks to a point.
The training-error curves
A note on these two figures. The lecture notes contain two plots — "Figure 1: Training error of gradient descent" and "Figure 2: Training error of (batch) GD and SGD" — whose images did not survive extraction from the PDF. The curves below are reconstructions: real simulations run live in your browser, fitting a linear model to 200 synthetic points with both algorithms, so the shapes are genuine rather than drawn by hand. Press Re-run to draw a fresh random dataset and watch the qualitative story stay the same.
Comparing optimizers by iteration count. Per iteration, batch GD is strictly better — it uses strictly more information. The only comparison that means anything is error against compute spent (gradient evaluations, FLOPs, or seconds). Under that accounting SGD wins decisively on large $N$, which is why it, and not batch GD, trains essentially every large model in existence.
Mini-batch gradient descent
Batch GD uses all $N$ samples per update; SGD uses exactly $1$. The intermediate version is the obvious one, and it is what everyone actually runs.
Mini-batch gradient descent. Choose $K$ samples at random per iteration, with $1 < K < N$. Call the chosen index set $B_t$ (the mini-batch). The update is
$$\theta^{(t)} = \theta^{(t-1)} - \alpha\,\frac{1}{K}\sum_{j\in B_t}\nabla_\theta\,\ell\!\left(h_\theta(x^{(j)}), y^{(j)}\right).$$$K=1$ recovers SGD; $K=N$ recovers batch GD. Everything in between is a dial.
The tradeoff, quantified
Averaging $K$ independent unbiased estimates gives an estimate that is still unbiased (the average of things each averaging to $\nabla J$ averages to $\nabla J$) but less noisy. Specifically, for independent draws the variance of the mean is
$$\mathrm{Var}\!\left[\frac{1}{K}\sum_{j\in B_t} g_j\right] = \frac{\sigma^2}{K},$$where $\sigma^2$ is the per-sample gradient variance. So:
- Noise falls like $1/K$. The standard deviation — the actual scale of the wobble — falls like $1/\sqrt{K}$.
- Cost rises like $K$. Each iteration does $K$ times the work.
Multiply those together: noise reduction per unit of compute is roughly constant. Going from $K=1$ to $K=100$ makes each step $100\times$ more expensive to make the noise $10\times$ smaller, so in pure flop-counting terms small $K$ wins. Everyone still uses $K=32$ or $K=256$, because the flop count is not the wall clock:
- Hardware parallelism. A GPU computing $256$ sample gradients at once takes barely longer than computing one — the arithmetic units are idle otherwise, so mini-batching is nearly free in real time up to saturation.
- Fixed per-step overhead. Kernel launches, memory transfers and the optimizer update are paid per iteration, not per sample, and dominate at $K=1$.
- Stability. A less noisy gradient tolerates a larger $\alpha$, recovering some of the lost steps.
beyond syllabus $K$ is conventionally a power of two for hardware reasons (warp size, memory coalescing, tensor-core dimensions), not statistical ones. Also, implementations rarely sample with replacement as the definition says: they shuffle once and cut the data into consecutive blocks of $K$, so every sample is used once per pass — one such pass is an epoch.
$N = 100{,}000$ training samples. One per-sample gradient costs $1$ microsecond, and per-iteration overhead is negligible except where stated. Your compute budget is 10 seconds, i.e. $10^7$ per-sample gradient computations.
(a) How many parameter updates does batch GD get? (b) How many does SGD get? (c) How many does mini-batch with $K=100$ get? (d) If the hardware computes a batch of 100 gradients in $20\,\mu$s wall-clock rather than $100\,\mu$s, redo (c). (e) Which would you run?
Step 1 — Updates per unit compute
Each update costs (gradients per update) $\times$ (cost per gradient). Budget $= 10^7$ gradient computations.
(a) Batch GD: $N = 10^5$ gradients per update $\Rightarrow 10^7/10^5 = \mathbf{100}$ updates.
(b) SGD: $1$ gradient per update $\Rightarrow \mathbf{10^7}$ updates — ten million.
(c) Mini-batch $K=100$: $10^7/100 = \mathbf{10^5}$ updates.
In epochs: the budget is $10^7/10^5 = 100$ passes over the data, for all three. They differ entirely in how finely they slice those passes into updates.
Step 2 — Is 100 updates ever enough?
For linear regression on a well-conditioned problem, quite possibly — we saw geometric convergence, gaining a digit every few iterations. For a neural network, no: $100$ updates from a random initialisation leaves you essentially at the initialisation. This is the crux. Batch GD does not fail because its direction is bad; its direction is the best available. It fails because the number of updates is the resource that matters, and batch GD spends its entire budget on a hundred extremely well-informed steps.
Step 3 — Wall-clock changes the answer (d)
With parallel hardware, $100$ gradients cost $20\,\mu$s, so the effective cost per gradient is $0.2\,\mu$s. In $10$ seconds: $10\,\text{s}/20\,\mu\text{s} = \mathbf{500{,}000}$ updates — five times more than the naive count in (c), and each update uses a gradient with $\frac{1}{\sqrt{100}} = \frac{1}{10}$ the noise of a single sample's.
Compare to SGD, which on the same hardware still gets $10^7$ updates only if a single gradient really costs $1\,\mu$s — but it leaves 99% of the GPU idle doing so. This is the entire practical argument for mini-batching.
Answer & the takeaway
(a) $100$ (b) $10^7$ (c) $10^5$ (d) $5\times10^5$ (e) mini-batch, with $K$ set to the largest value your hardware absorbs for free — typically $32$ to $256$.
Takeaway: all three algorithms consume identical compute and differ only in the granularity of the updates. The right question is never "which gradient is most accurate?" but "how much progress can I buy per second?" — and the answer to that depends on your hardware, not only your mathematics.
Recap
Where the rule came from: derivative positive $\Rightarrow$ step left, negative $\Rightarrow$ step right, magnitude large when far away $\Rightarrow$ step proportionally — all three at once in $\theta \leftarrow \theta - \alpha\nabla_\theta J$. And the dial: on $J(w)=cw^2$ it converges iff $0<\alpha<1/c$, is exact in one step at $\alpha = 1/(2c)$, oscillates on the boundary and diverges beyond; in general $\alpha < 2/L$ with $L$ the largest curvature.
- Everything was derived on a parabola, because a one-sample squared loss is a parabola and so is the $N$-sample average — but the algorithm only ever uses a derivative, which is why it transfers to landscapes of any shape.
- Two identities do all the work: $\nabla_\theta(\theta^\top v) = v$ and $\nabla_\theta(\theta^\top A\theta) = (A+A^\top)\theta$, which is $2A\theta$ for symmetric $A$ — and $X^\top X$ is always symmetric. Together they give $\nabla_\theta\|y-X\theta\|_2^2 = -2X^\top y + 2X^\top X\theta$ and hence the normal equations, agreeing with the completing-the-square derivation in the previous chapter.
- Linear regression is the lucky case. Almost nothing else has a closed form; gradient descent is what you use when $\nabla J = 0$ cannot be solved.
- Local minima are real, and gradient descent can get stuck in one depending on where it starts. It remains overwhelmingly popular anyway, because a good solution found efficiently beats a perfect one found never.
- Judge optimizers by error versus compute, never versus iterations.
Next: feature engineering, where the shape of the bowl you are descending turns out to be something you get to choose.