AI / ML Theory
Chapter 3 · 18 min

3.1 — Batch, stochastic, and mini-batch gradient descent

Goal: Understand the gradient estimator at each batch size, its bias and variance, and why mini-batches are the universal compromise.

1. Why this session exists

In Chapter 1 we wrote the update θ←θ−α∇L(θ)\theta \leftarrow \theta - \alpha \nabla L(\theta) as if ∇L\nabla L were a single, computable thing. For modern training that is a fiction. The loss is an average over NN examples — 10410^4 for MNIST, 101210^{12} tokens for a frontier LM — and computing the true gradient once per step is prohibitive.

So we estimate it. The estimator's choice — full batch, single example, or a mini-batch of size BB — controls bias, variance, memory, and how often we get to update. This session sets up the bias/variance picture and locks in the vocabulary for the rest of Chapter 3.


2. The empirical risk and its true gradient

The training objective is the empirical risk

L(θ)=1N∑i=1Nℓ(fθ(xi), yi),L(\theta) = \frac{1}{N} \sum_{i=1}^N \ell\bigl(f_\theta(x_i),\, y_i\bigr),

with per-example loss ℓi(θ):=ℓ(fθ(xi),yi)\ell_i(\theta) := \ell(f_\theta(x_i), y_i). Its gradient is the average

∇L(θ)=1N∑i=1N∇ℓi(θ)=:1N∑i=1Ngi.\nabla L(\theta) = \frac{1}{N} \sum_{i=1}^N \nabla \ell_i(\theta) =: \frac{1}{N} \sum_{i=1}^N g_i.

Call gi:=∇ℓi(θ)g_i := \nabla \ell_i(\theta) the per-example gradient. Then ∇L=gˉ\nabla L = \bar g, the population mean of the gig_i's. Every estimator we write next is some attempt at gˉ\bar g.[3]


3. The three regimes

Full-batch GD (BGD). Use all NN examples per step:

g^BGD=1N∑i=1Ngi=∇L(θ).\hat g^{\text{BGD}} = \frac{1}{N} \sum_{i=1}^N g_i = \nabla L(\theta).

This is the exact gradient. No noise, but each step costs O(N)O(N) forward+backward passes. For N=109N = 10^9 that is one step per several minutes; impossible.

Stochastic GD (SGD). Pick one example ii uniformly at random and use only that gradient:

g^SGD=gi,i∼Uniform⁡{1,…,N}.\hat g^{\text{SGD}} = g_i, \qquad i \sim \operatorname{Uniform}\{1, \dots, N\}.

One forward+backward per step; we update parameters NN times per pass through the dataset. Maximum noise, maximum step count.

Mini-batch SGD. Pick a random subset B⊂{1,…,N}\mathcal{B} \subset \{1, \dots, N\} with ∣B∣=B|\mathcal{B}| = B:

g^mb=1B∑i∈Bgi.\hat g^{\text{mb}} = \frac{1}{B} \sum_{i \in \mathcal{B}} g_i.

Memory and compute scale linearly with BB; noise scales as 1/B1 / \sqrt{B} (we'll prove this in §4). For B=32B = 32 to 20482048 on a GPU, mini-batch GD is what every modern trainer runs.[1, 2, 4, 5]


4. Bias and variance of the estimator

Sample B\mathcal{B} uniformly at random (with replacement, to make the math clean — without-replacement is the same up to O(B/N)O(B/N) corrections). Define the per-example gradient as a random variable GG taking value gig_i with probability 1/N1/N.

Mean (bias).

E[g^mb]=1B∑i∈BE[gi]=E[G]=1N∑j=1Ngj=∇L(θ).\mathbb{E}[\hat g^{\text{mb}}] = \frac{1}{B} \sum_{i \in \mathcal{B}} \mathbb{E}[g_i] = \mathbb{E}[G] = \frac{1}{N} \sum_{j=1}^N g_j = \nabla L(\theta).

So g^mb\hat g^{\text{mb}} is unbiased for the true gradient. No bias correction needed — the estimator is honest in expectation, at every BB from 11 to NN. SGD (B=1B = 1) is unbiased; full-batch (B=NB = N) is unbiased and noise-free.

Variance. Let Σ:=Cov⁡(G)\Sigma := \operatorname{Cov}(G), the covariance matrix of the per-example gradients. With BB i.i.d. samples,

Cov⁡(g^mb)=1B2∑i∈BCov⁡(gi)=ΣB.\operatorname{Cov}\bigl(\hat g^{\text{mb}}\bigr) = \frac{1}{B^2} \sum_{i \in \mathcal{B}} \operatorname{Cov}(g_i) = \frac{\Sigma}{B}.

The scalar quantity we care about is the squared error of the estimator,

E[∥g^mb−∇L∥2]=tr⁡(Cov⁡(g^mb))=tr⁡(Σ)B.\mathbb{E}\bigl[\lVert \hat g^{\text{mb}} - \nabla L \rVert^2\bigr] = \operatorname{tr}\bigl(\operatorname{Cov}(\hat g^{\text{mb}})\bigr) = \frac{\operatorname{tr}(\Sigma)}{B}.

So

 Var⁡(g^mb)  ∝  1B,noise std  ∝  1B. \boxed{\ \operatorname{Var}\bigl(\hat g^{\text{mb}}\bigr) \;\propto\; \frac{1}{B}, \qquad \text{noise std} \;\propto\; \frac{1}{\sqrt{B}}.\ }

Doubling the batch size halves the variance but doubles the compute per step. To halve the noise std you need four times the batch.


5. Why noise can help

The naive read is "less variance is better, use full-batch". Two reasons that's wrong.

(a) Saddle escape. In a high-dimensional non-convex loss, saddle points vastly outnumber local minima (Dauphin et al., 2014). Full-batch GD on a saddle stays exactly there — ∇L=0\nabla L = 0. The noise of SGD perturbs θ\theta off the saddle into a descent direction. Stochasticity is a feature.

(b) Implicit regularisation. A line of work (Keskar et al., 2017; Smith & Le, 2018) argues that large-batch GD converges to sharp minima — narrow valleys where small parameter perturbations cause large loss changes — and that these generalise worse than the flat minima preferred by small-batch SGD. The noise effectively acts like a low-pass filter on the loss landscape, biasing the optimiser toward wide basins. We will revisit this in 3.9 and 6.12 in the context of LLM training.

So variance is not pure cost; some of it is doing useful work.


6. Step cost vs total compute

Three knobs you can spend compute on: bigger batches, more steps, or a different optimiser. The mini-batch arithmetic gives a clean way to compare.

Let Cstep(B)=c⋅BC_\text{step}(B) = c \cdot B be the per-step cost (linear in BB — one forward+backward per example, GPU-parallelised). After TT steps the total compute is C=cBTC = c B T. To reach a target loss, full-batch needs few but expensive steps; SGD needs many but cheap steps. For convex objectives, an exact bound (Bottou et al., 2018) is

steps to ϵ-optimal  ∼  1ϵ2B⋅tr⁡(Σ)+1ϵ⋅1μ,\text{steps to } \epsilon\text{-optimal} \;\sim\; \frac{1}{\epsilon^2 B} \cdot \operatorname{tr}(\Sigma) + \frac{1}{\epsilon} \cdot \frac{1}{\mu},

with μ\mu the strong-convexity constant. The first term shrinks as 1/B1/B (variance-dominated regime; helps to increase BB); the second is independent of BB (bias-dominated regime; increasing BB is wasted). There is a critical batch size B⋆∼tr⁡(Σ)⋅μ/ϵB^\star \sim \operatorname{tr}(\Sigma) \cdot \mu / \epsilon past which more batch is wasted compute. Practical takeaway: very small or very large batches are both suboptimal; the sweet spot is data-dependent and what every modern trainer empirically tunes.


7. Epoch, step, iteration: vocabulary

  • Step (or iteration). One parameter update: one forward+backward on one mini-batch.
  • Epoch. One full pass through the training set: N/BN / B steps.
  • Sample without replacement per epoch. Practical implementations shuffle the dataset at the start of each epoch and walk through it in order. This is technically biased (within an epoch, samples are dependent) but the bias is negligible for N≫BN \gg B.

The convention we will follow: "training for TT steps with batch BB" is unambiguous; "training for EE epochs" implies E⋅N/BE \cdot N / B steps. Both appear in papers.


8. Takeaways

  • Mini-batch SGD is unbiased for the true gradient: E[g^mb]=∇L\mathbb{E}[\hat g^{\text{mb}}] = \nabla L.
  • Variance scales as Σ/B\Sigma / B; noise std as 1/B1/\sqrt{B}.
  • Pure SGD (B=1B=1) is maximally noisy but cheap; full batch is exact but expensive.
  • Noise is partly useful: it escapes saddles and biases toward flat minima.
  • There is a problem-dependent critical batch size B⋆B^\star; below it, doubling the batch nearly halves time-to-target; above it, the extra batch is wasted.

Self-test

(a) Show by direct calculation that for i.i.d. per-example gradients G1,…,GBG_1, \dots, G_B with covariance Σ\Sigma, Cov⁡(1B∑iGi)=Σ/B\operatorname{Cov}\bigl(\frac{1}{B} \sum_i G_i\bigr) = \Sigma / B.

(b) A trainer reports that doubling batch from B=128B = 128 to B=256B = 256 doubles wall-clock per step but reduces the number of steps to a given loss by only ~30%30\%. What does this say about whether BB is above or below the critical batch size?

(c) Why is full-batch GD a particularly bad optimiser at saddle points? Set up a 2-D example: L(θ1,θ2)=θ12−θ22L(\theta_1, \theta_2) = \theta_1^2 - \theta_2^2 at (0,0)(0,0). What does BGD do? What does SGD do (assume i.i.d. noise ξ\xi added to the gradient)?

(d) Empirically, you sometimes see "linear scaling rule": when you multiply batch BB by kk, also multiply learning rate α\alpha by kk. Argue (informally) that this keeps the per-epoch parameter trajectory roughly invariant: write the expected change in θ\theta after one epoch and show it is approximately the same.


References

  1. [1]

    Barbaresi, A. (2021). "Trafilatura: a web scraping library and command-line tool for text discovery and extraction". ACL System Demonstrations. aclanthology.org/2021.acl-demo.15 — Reference HTML→text extractor (7.1 §3.1).

    ↩
  2. [2]

    Child, R., Gray, S., Radford, A., & Sutskever, I. (2019). "Generating long sequences with sparse transformers". arXiv:1904.10509 — Sparse Transformer's alternating sparse-dense pattern; used in GPT-3 (7.14 §3.1).

    ↩
  3. [3]

    Radford, A., Wu, J., Child, R., et al. (2019). "Language models are unsupervised multitask learners" (GPT-2). OpenAI technical report. — Pre-LN block, modified init, reversible tokenization referenced by GPT-3 §2.1 (7.14 §3.1).

    ↩
  4. [4]

    Fedus, W., Zoph, B., & Shazeer, N. (2021). "Switch Transformer: Scaling to trillion parameter models with simple and efficient sparsity". arXiv:2101.03961 — Top-1 routing; standard auxiliary loss formulation (8.6 §3.1).

    ↩
  5. [5]

    Gu, A., Goel, K., & Ré, C. (2022). "Efficiently modeling long sequences with structured state spaces" (S4). arXiv:2111.00396 — Structured (diagonal-plus-low-rank) AA for efficient long-sequence SSM (8.7 §3.1).

    ↩