Training well: batches, epochs, and optimizers
Which training decisions separate a network that learns from one that does not?
Lesson complete
If you like:
In lesson eight we corrected the weights using a single example. A real model learns from millions. How many examples should it look at before each step?
No voice: the lesson advances on its own with subtitles.
The voice for this lesson is being recorded: for now it advances on its own with subtitles.
Review modeComment on this stepI finished the lesson
What you will achieve
- Explain what a batch is and why we train on random batches instead of using every example, and compute how many steps an epoch has.
- Tell what each optimizer (SGD, momentum, and Adam) does and why each one needs its own learning rate.
- Predict what warmup and decay of the rate do, and recognize which settings are hyperparameters.
Key ideas
- With many examples the slope is not computed from all of them: it is estimated from a random batch (in the lesson, 8 of 256). Its arrow is a little off, but on average it points the right way. That is stochastic gradient descent (SGD).
- An epoch is one full pass over the data: with N examples and batches of B, it has N/B steps (256 / 8 = 32). For the same work, a small batch gives many cheap, noisy steps and a large one gives a few exact steps; the best is usually in between.
- The optimizer turns the slope into a step. SGD uses it as is; momentum adds inertia; Adam also gives each weight its own step size. Each one wants its own rate.
- The rate can change during training: a warmup at the start avoids the jump that throws the model far away, and a decay at the end calms the jitter so it settles at the bottom.
- Batch size, rate, optimizer, and schedule are hyperparameters: a person chooses them, they are not learned with gradients, and trying them costs whole training runs.
What many people believe
Common belief The bigger the batch, the better: the gradient is more exact, so it learns more.
What is true More exact is not more efficient. With the same budget of examples, a big batch takes fewer steps. And very large batches call for rescaling the rate and warming up so quality does not suffer.
Check yourself
Four questions. No grade, no account: they just show whether the idea stuck.
Under the hoodFor those who want the math and the code. You do not need it to follow the course.
The gradient of a batch
With examples and a per-example error , the total error is . A batch of randomly chosen examples gives the approximate gradient
It is an unbiased estimator. Its variance is , where is the variance of one example’s gradient: the error falls as , while the cost of the step grows as . That is why cutting the noise in half takes a batch about four times larger. In the lesson, the arrow’s average error (measured over 24 batches of each size) was 20 %, 10 %, 4 %, and 1.7 % for batches of 2, 8, 32, and 128: it falls a bit faster than because the factor matters when the batch is a large share of the 256 examples. An epoch has steps, and after steps examples have been seen. The idea of updating with noise goes back to Robbins and Monro (1951).
Near a minimum with curvature , gradient noise (variance ) leaves an error floor: when . It is proportional to : lowering the rate or raising the batch lowers it. That is why decaying the rate helps the path settle.
Momentum
With and a constant gradient, : the effective step is ten times larger; for the same effective step, momentum’s rate would be about ten times smaller than SGD’s (in practice the ratio is smaller: in the lesson’s canyon, 0.02 versus 0.07). For a quadratic with curvatures and condition number , the best fixed rate for SGD shrinks the distance to the bottom per step by a factor , and well-tuned momentum by (Polyak, 1964). In the lesson’s canyon, near the bottom, : about per step versus (in theory, without noise).
Adam
Everything is per weight (the square and the root act component by component). The defaults from Kingma and Ba (2015) are , , , and . The bias corrections compensate for and starting at zero. On the first step , so every weight moves by ; in normal operation each weight’s step is at most on the order of . Two consequences: the method is invariant to rescaling each gradient separately (its authors say so), and near an optimum the signal-to-noise ratio drops and the steps shrink on their own, an “automatic annealing” in Kingma and Ba’s words. With noisy batch gradients that is not enough: in the lesson’s simulation, with a constant the path keeps jittering around the bottom, with an amplitude that grows with , and lowering at the end calms it.
Learning-rate schedules
Two real recipes: the original transformer (Vaswani et al., 2017) used Adam with and warmed up for 4000 steps; GPT-3 (Brown et al., 2020) used Adam with , a linear warmup over the first 375 million tokens, and cosine decay down to 10 % of the peak value over 260 billion tokens. Its batch also grew from 32 thousand tokens to the final value (3.2 million for the 175-billion-parameter model) over the first 4 to 12 billion tokens, depending on model size, and it saw only 0.44 epochs of its web-crawl text (Table 2.2). When the batch grows, Goyal et al. (2017) propose multiplying the rate by the same factor and warming up: with that rule they trained ResNet-50 with batches of 8192 images on 256 GPUs, in one hour, with no loss of accuracy.
Hyperparameters
The weights are learned with ; hyperparameters (, , , , the optimizer…) set how learning happens and have no gradient within reach. They are chosen by trying: in spaces of several dimensions, trying random combinations often pays off more per trial than sweeping a grid (Bergstra and Bengio, 2012).
In code
import math
# Eight fixed examples of y ≈ 2x + 1. Batches are taken in order so the
# result is reproducible (in practice you shuffle every epoch).
X = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5]
Y = [1.2, 1.8, 3.1, 4.1, 4.9, 6.2, 6.9, 8.1]
def grad(w, b, idx): # gradient of the batch mean squared error
n = len(idx)
gw = sum(2 * (w * X[i] + b - Y[i]) * X[i] for i in idx) / n
gb = sum(2 * (w * X[i] + b - Y[i]) for i in idx) / n
return [gw, gb]
def train(opt, eta, B, epochs, beta=0.9, b1=0.9, b2=0.999, eps=1e-8):
p = [0.0, 0.0] # weights: w and b
v = [0.0, 0.0]; m = [0.0, 0.0]; s = [0.0, 0.0]; t = 0
for _ in range(epochs): # one epoch = go through all the batches
for start in range(0, len(X), B):
g = grad(p[0], p[1], range(start, min(start + B, len(X))))
t += 1
if opt == "sgd":
step = [eta * gi for gi in g]
elif opt == "momentum":
v = [beta * vi + gi for vi, gi in zip(v, g)]
step = [eta * vi for vi in v]
else: # Adam
m = [b1 * mi + (1 - b1) * gi for mi, gi in zip(m, g)]
s = [b2 * si + (1 - b2) * gi * gi for si, gi in zip(s, g)]
step = [eta * (mi / (1 - b1 ** t)) / (math.sqrt(si / (1 - b2 ** t)) + eps)
for mi, si in zip(m, s)]
p = [pi - di for pi, di in zip(p, step)]
return [round(pi, 3) for pi in p]
# the exact least-squares solution is [1.998, 1.042]
for opt, eta in [("sgd", 0.05), ("momentum", 0.005), ("adam", 0.3)]:
print(opt, train(opt, eta, B=4, epochs=50))
# sgd [1.999, 1.033]
# momentum [2.008, 1.043]
# adam [1.993, 1.028]
On a problem this small and well conditioned, SGD is already enough: the differences show up on landscapes like the canyon, and each optimizer needed its own rate.
What comes next
Lowering the training error is not enough: you have to measure with data the model has not seen. That is lesson 10 (generalizing and evaluating), which adds early stopping and weight decay as ways to regularize.
Decision lens
What this idea means if your job is to decide, not to code.
- “We trained with the default settings” is not a sufficient answer. Ask which rate, batch, optimizer, and schedule were used and how many trials it took to get there: each trial was a full training run.
- Doubling the GPUs does not always halve the time: beyond a certain size, a bigger batch no longer saves steps (the “critical batch size,” McCandlish et al., 2018), and it forces you to rescale the rate and warm up.
- A loss that spikes at the start points to a rate that is too high or a missing warmup; one that oscillates at the end, to a missing decay. These are configuration fixes, not reasons to buy more compute.
- Compare optimizers with each one’s rate tuned, not at the same value: it is easy to mislead that way. Also ask them to record the seed and the configuration, because two identical runs give somewhat different results.
Terms in this lesson
- Batch A small set of examples, picked at random, used to estimate the gradient in one training step.
- Epoch One full pass over all the training examples. With N examples and batches of B, an epoch is N/B steps.
- Stochastic gradient descent (SGD) Gradient descent in which each step uses the gradient of a random batch instead of the gradient from all the examples.
- Optimizer The rule that turns the gradient into a change of the weights. Examples: SGD, SGD with momentum, and Adam.
- Adam An optimizer that combines momentum with a step size of its own for each weight, computed from moving averages of the gradient and its square (Kingma and Ba, 2015).
- Hyperparameter A setting a person fixes for training (rate, batch size, epochs, optimizer, schedule). It is not learned with gradients.
- Gradient The list of the slopes of the error, one for each weight. Seen as an arrow, it points to where the error rises fastest.
- Gradient descent A method that adjusts the weights step by step, always against the slope of the error (the gradient), until it reaches a bottom.
- Learning rate A number (η) that multiplies the slope and sets the size of each step. Too small is slow; too large bounces or diverges.
- Weight (w) In a linear model, the number that multiplies the input: the slope of the line. It tells how much the prediction rises for each unit the input grows.
- Loss function A single number that summarizes how wrong a model is on its data. Training is the search for the parameters that make it as small as possible.
- Backpropagation An algorithm that computes the gradient of the loss with respect to every weight of a network in a single backward sweep, applying the chain rule layer by layer. It computes the blames; it does not move the weights (in the 1986 paper, the name covered the whole learning procedure).
Full transcript
Sources
- Kingma, D. P., Ba, J. (2015). Adam: A Method for Stochastic Optimization
- Goyal, P., Dollár, P., Girshick, R., et al. (2017). Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour
- Brown, T. B., et al. (2020). Language Models are Few-Shot Learners (GPT-3): Tabla 2.1, Tabla 2.2 y Apéndice B
- Robbins, H., Monro, S. (1951). A Stochastic Approximation Method
- Polyak, B. T. (1964). Some methods of speeding up the convergence of iteration methods (USSR Computational Mathematics and Mathematical Physics 4(5): 1–17)
- Loshchilov, I., Hutter, F. (2017). SGDR: Stochastic Gradient Descent with Warm Restarts
- Vaswani, A., et al. (2017). Attention Is All You Need
- Bergstra, J., Bengio, Y. (2012). Random Search for Hyper-Parameter Optimization
- McCandlish, S., Kaplan, J., Amodei, D., OpenAI Dota Team (2018). An Empirical Model of Large-Batch Training
- Bottou, L., Curtis, F. E., Nocedal, J. (2018). Optimization Methods for Large-Scale Machine Learning
CommentsThis lesson’s public conversation: questions, facts to check, ideas.
Comments live in GitHub Discussions, in the course’s public repository; writing one requires a GitHub account. They load from giscus.app when you open this section. The course reviewers read them, and if a change is accepted, it is applied in both languages. Open the thread on GitHub