Part II · Chapter 9

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.

Essentials

ERM is a minimisation problem; this chapter is the algorithm that solves it when no closed form exists.

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.

Key idea

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}$.

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.

Figure 1 · The sign of the derivative always points away from the minimum
What to notice: the tangent on the right leans uphill (positive slope) and the correct move is left; the tangent on the left leans downhill (negative slope) and the correct move is right. In both cases you move in the direction opposite to the sign of the derivative. Notice also that the far-left tangent is much steeper than the near-left one — distance from the minimum shows up as steepness.
Intuition

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.

Key idea

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.

Common mistake

"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

Definition

Gradient descent (scalar case).

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:

1 · Performance

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.

2 · Gradient

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.

3 · Iterate

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.

4 · Budget

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:

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.

Common mistake

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

Proof

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$.

Figure 2 · Gradient descent, step by step — drive it yourself
What to notice: set $\alpha=0.25$ and step — each iterate halves its distance to $0$. Set $\alpha=0.5$ — one step and you are done. Set $\alpha=1$ — the trail flips between $+1$ and $-1$ and never gets anywhere. Set $\alpha=2$ — three steps and the iterate is off the top of the plot. Then switch the function to the four-minimum landscape, and drag the start point: from $w^{(0)}=-2.5$ you fall into one valley, from $w^{(0)}=2.0$ into a different, shallower one. Same algorithm, same $\alpha$, different answer.
Guided problemThe notes' exercise: $w^{(3)}$ for four learning rates

$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.

You run gradient descent on $J(w)=10w^2$ from $w^{(0)}=1$ with $\alpha=0.25$ and the loss explodes. What is the smallest change that fixes it?
Why: with $c=10$ the factor is $1-2(0.25)(10) = -4$, so each step multiplies the iterate by $-4$. Convergence requires $|1-2\alpha c|<1$, i.e. $0<\alpha<1/c = 0.1$. Flipping the sign turns descent into ascent (it would climb even faster). And the starting point is irrelevant to stability: $w^{(t)} = (-4)^t w^{(0)}$ diverges from any nonzero start — it just takes a few more iterations to notice from $0.01$. Stability is a property of $\alpha$ and the curvature, never of the initialisation.

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$".

Key idea

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.

Guided problemRun gradient descent on real data, by hand

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.$$
Definition

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.

Figure 3 · Level sets, the gradient, and steepest descent
What to notice: each arrow crosses its contour at a right angle. The long arrow sits where the contours are packed tightly (steep ground, large gradient); the short arrow sits where they are widely spaced (gentle ground, small gradient). The dashed arrow along the contour is the direction of zero change — move that way and the objective is unaffected.
Analogy

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.

Proof

(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.

Proof

(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:

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$

Key idea

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:

Definition

$\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:

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:

Denominator layout · this course

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.

Numerator layout

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.

$J(\theta)=\theta^\top A\theta$ with $A = \begin{bmatrix}1&3\\0&1\end{bmatrix}$ and $\theta=(1,1)^\top$. What is $\nabla_\theta J$?
Why: $A$ here is not symmetric ($A_{12}=3$ but $A_{21}=0$), so the shortcut $2A\theta$ does not apply — you must use the general identity $(A+A^\top)\theta$. Verify directly: $J(\theta) = \theta_1^2 + 3\theta_1\theta_2 + \theta_2^2$, so $\partial J/\partial\theta_1 = 2\theta_1 + 3\theta_2 = 5$ and $\partial J/\partial\theta_2 = 3\theta_1 + 2\theta_2 = 5$. ✓ The happy news is that in linear regression the middle matrix is $X^\top X$, which is symmetric by construction, so there $2A\theta$ is legitimate.

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:

$$\boxed{\ \nabla_\theta J(\theta) = -2X^\top y + 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.

Key idea

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.

Definition

Gradient descent for a general $J:\R^d\to\R$.

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$.

Figure 4 · The zig-zag: gradient descent in a stretched bowl
The bowl is $J(\theta)=\tfrac12(\theta_1^2 + 20\theta_2^2)$ — curvature $1$ along $\theta_1$ but $20$ along $\theta_2$, a condition number of $20$. What to notice: $\alpha$ is forced small by the steep direction ($\alpha<2/20=0.1$), but then progress along the shallow direction is agonisingly slow, so the path bounces across the valley while creeping along it. Push $\alpha$ past $0.1$ and the vertical bounce grows instead of shrinking. This picture is the whole reason feature scaling, momentum and adaptive methods exist.

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:

Definition

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.

Key idea

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.

You train the same neural network twice on the same data with the same hyperparameters, changing only the random initialisation, and get final training losses of $0.031$ and $0.047$. What is the most accurate reading?
Why: gradient descent is deterministic given its starting point, but the loss surface of a network is non-convex, so the starting point selects which local minimum you converge to. Divergence looks completely different — the loss grows without bound or becomes 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.
Guided problemA gradient step in two dimensions, by hand

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.

Common mistake

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.

Key idea

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

Definition

Stochastic gradient descent (SGD).

"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.

Proof

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.

Intuition

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.

Figure 5 · Reconstruction of Figure 1 — training error of gradient descent
What to notice: smooth, monotone, and decelerating. Every step uses the exact gradient, so (with $\alpha$ in the stable range) the objective cannot go up. The curve flattens because the gradient shrinks as you approach the minimum — the same "steps get smaller near the bottom" property we relied on in Figure 1. This is the picture people mean by "a healthy loss curve".
Figure 6 · Reconstruction of Figure 2 — batch GD vs SGD
What to notice — and this is the point of the figure: the horizontal axis is per-sample gradient computations (a proxy for wall-clock time), not iterations. That is the honest comparison, because one GD iteration costs $N$ times one SGD iteration. On this axis SGD is essentially at the floor before batch GD has finished its second step. SGD's curve is visibly noisy and sometimes goes up — a single bad sample can point uphill — and it flattens into a noise floor rather than a point. Tick the box to plot against iterations instead and watch GD appear to win, which is the misleading plot you should refuse to accept from anyone.
Common mistake

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.

Definition

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:

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:

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.

Guided problemBudget three optimizers

$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.

Your SGD training-loss curve is jagged: it goes down overall, but individual steps clearly increase the loss. What should you conclude?
Why: SGD steps exactly downhill on $\ell_j$, not on $J$ — and $\nabla\ell_j = \nabla J + \varepsilon_j$ with a nonzero kick $\varepsilon_j$. Jaggedness is the noise term, not a bug, and it is the price of the $N\times$ speedup. Diagnosing the difference: healthy SGD is jagged with a downward trend and a stable noise floor, while too-large $\alpha$ makes the trend flat or upward and the amplitude grow. A smooth curve is not the goal; a decreasing one is.

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.

Next: feature engineering, where the shape of the bowl you are descending turns out to be something you get to choose.