ML Atlas

Machine learning from zero · Lesson 1.6 · 7 of 33 lessons ready · 10 min

Gradient descent: learning by small steps

In short

Gradient descent finds good parameters by repeatedly stepping downhill on the error. The learning rate decides between progress and explosion.

Warm-up Two questions from earlier lessons. A minute, and it never blocks the lesson.
From lesson 1.5: Linear regression: fitting a line With the slope fixed at zero, which intercept gives the lowest MSE?

Show the answer

Correct answer: The mean of the target variable in the training data

For a flat line the squared error is smallest at the average, which is why the mean is the natural baseline in regression.

From lesson 1.4: Nearest neighbours: the simplest model Why are measurements usually standardized before kNN?

Show the answer

Correct answer: Because a measurement in big units, like grams, drowns out the rest

The distance adds up the differences in the measurements. Mass in thousands of grams covers the bill in millimetres: on four measurements 76.7% without scaling and 96.1% after standardizing.

In the last lesson a formula handed us the best line in one go. But a neural network with millions of weights has no such formula. How can a computer find good values for millions of knobs when nobody can tell it where the best setting is? The answer is almost embarrassingly simple: it feels which way is downhill and takes a small step. Then it does it again.

Predict, then check Four learning rates (step lengths) to choose from: 0.01, 0.1, 0.8 and 1.1. Which one gives the lowest loss (the number that says how wrong the model is) after 5 steps?
How sure are you?

Interactive lab

This interactive lab runs in a browser with JavaScript enabled. The text around it describes what the lab shows.

Show the answer

Correct answer: 0.8

After 5 steps the loss is 24468 (η = 0.01), 6595 (0.1), 4043 (0.8) and 159823 (1.1); the minimum is 3890. At 0.8 the step is large but does not yet overshoot the valley. At 1.1 every step overshoots it so far that the loss grows.

Try this

  • Choose a small learning rate and press Step a few times. Watch the line move a little at each step and the loss curve slowly go down.
  • Press Run and let it go. Does the line end up close to the least squares line from the previous lesson?
  • Start over with the largest learning rate and press Step again. Watch the loss curve: instead of falling, it climbs, and the line swings wildly. That is divergence.
  • Try the learning rates in between and find the largest one that still makes the loss fall steadily.

Now that you've tried it, let's see what was actually going on.

The idea in plain words

Imagine standing on a hillside in thick fog. You want to reach the valley, but you can see only a metre around you. A sensible strategy: feel the ground with your feet, find the direction in which it slopes down most steeply, take a step that way, and repeat. You never see the whole landscape, yet step by step you get lower.

In machine learning the "landscape" is the error of the model. Every possible pair of slope and intercept is a position on the map, and the height at that position is the mean squared error from lesson 3. The valley floor is the best line. Gradient descent is the foggy walk: start somewhere, measure which way the error decreases, move the parameters a little in that direction, and repeat until the error stops falling.

Why it works

The direction of steepest ascent of a function is given by its gradient — a list of derivatives, one for each parameter, saying how much the error would grow if that parameter were nudged up. Go the opposite way and the error goes down. For each parameter w one step is:

w ← w − η · ∂L/∂w

Here L is the loss (the error we minimise), ∂L/∂w is how strongly the loss reacts to w, and η (the Greek letter eta) is the learning rate, which sets the size of the step. Where the slope is steep, steps are big; near the bottom the slope flattens and the steps shrink by themselves.

Everything depends on the learning rate. If it is too small, each step is tiny and the walk takes forever. If it is just right, the error drops quickly and settles near the minimum. If it is too large, each step overshoots the valley and lands higher on the opposite slope; the next step overshoots even more, and the error grows without limit. This is called divergence, and it is the most common reason why a training run "explodes".

The beauty of the method is that it needs only one thing: the ability to compute the gradient at the current position. It does not need a formula for the answer, and it works the same for two parameters as for two billion. That is why it is the engine behind almost every neural network, including the language models of lesson 12. In practice the gradient is usually estimated on a small random batch of examples rather than on all of them, which makes each step cheaper and noisier but works remarkably well.

Common mistake

When the loss suddenly shoots up or turns into "NaN" (not a number), beginners often suspect a bug in their code. Much more often the learning rate is simply too large. The cure is to lower it, not to rewrite the model. The opposite mistake is less visible: a learning rate so small that the loss is still falling when training stops, so the model looks worse than it could be. A related trap is features on very different scales — say, age in years next to income in euros — which turns the valley into a long, narrow canyon where no single learning rate suits every direction. Scaling the features first makes the walk much easier.

We now have both halves of the learning recipe: a score and a way to improve it. In the next lesson we use them for a new kind of question — not "how much?" but "which one?".

Quiz

Three questions to check yourself. Pick an answer, or open the answer under a question. Keyboard: arrow keys choose, Enter or Space confirms.

1. What does the gradient tell the algorithm at each step?
Show the answer

Correct answer: In which direction, and how steeply, the loss grows at the current point

The gradient points uphill, so stepping against it lowers the loss, but it only describes the neighbourhood of the current point.

2. The loss climbs higher with every step. What is the most likely cause?
Show the answer

Correct answer: The learning rate is too large, so the steps overshoot the minimum

With too large a step the parameters jump past the valley to a higher point each time, and the error grows.

3. Why is gradient descent used for neural networks instead of an exact formula?
Show the answer

Correct answer: Because there is usually no formula for the best parameters, but a gradient can be computed

Gradient descent needs only the slope of the loss at the current point, which is available even for models with billions of parameters.

Key takeaways

  • Gradient descent improves parameters by repeatedly stepping against the gradient of the loss.
  • The learning rate sets the step size: too small is slow, too large diverges.
  • A loss that explodes usually means the learning rate is too high, not that the code is broken.
  • The method needs only the gradient, so it scales from two parameters to billions.

Going further: formula, code, practice

The math

Take the line ŷ = b + w·z, with the loss L(w, b) = (1/n) · Σ (yᵢ − b − w·zᵢ)². Its gradient is ∂L/∂w = −2 · mean(r · z) and ∂L/∂b = −2 · mean(r), where r = y − ŷ are the residuals. One step is w ← w − η·∂L/∂w and b ← b − η·∂L/∂b.

When the feature is standardised (mean(z) = 0, mean(z²) = 1), the two directions do not interfere. Each step then shrinks the distance to the best w and b by the factor 1 − 2η.

  • 0 < η < 1: the distance shrinks and the loss falls to the minimum. The closer η is to 0.5, the faster.
  • η > 1: the factor 1 − 2η is below −1, so its size is above 1, every step overshoots farther, and the loss grows without limit.
  • Without standardising, the safe range of η depends on the scale of the feature, so one value no longer suits every direction.
In code (Python)

The lab's loss after 5 steps from w = b = 0, for four learning rates, on standardised BMI (diabetes data):

import numpy as np
from sklearn.datasets import load_diabetes

X, y = load_diabetes(return_X_y=True, as_frame=True, scaled=False)
bmi = X["bmi"].to_numpy()
z = (bmi - bmi.mean()) / bmi.std()  # standardised BMI, as in the lab
mse = lambda w, b: np.mean((y - (b + w * z)) ** 2)
for lr in [0.01, 0.1, 0.8, 1.1]:
    w, b = 0.0, 0.0  # start at the origin
    for _ in range(5):  # five full-batch steps
        r = y - (b + w * z)
        w, b = w + lr * 2 * np.mean(r * z), b + lr * 2 * np.mean(r)
    print(f"lr {lr}: loss after 5 steps {mse(w, b):.0f}")
w_best, b_best = np.polyfit(z, y, 1)
print(f"minimum: {mse(w_best, b_best):.0f}")

Output

lr 0.01: loss after 5 steps 24468
lr 0.1: loss after 5 steps 6595
lr 0.8: loss after 5 steps 4043
lr 1.1: loss after 5 steps 159823
minimum: 3890

The minimum, 3890, is the MSE of the least squares line from lesson 3. At lr = 0.8 the factor is |1 − 1.6| = 0.6 per step, which beats 0.9 at lr = 0.1. At lr = 1.1 it is 1.2, so the loss grows.

For practitioners
  • Standardise numeric features before gradient descent. It makes the loss bowl round and lets one learning rate fit all directions.
  • Always plot the loss against the step. A smooth fall is healthy. A rise or NaN almost always means a learning rate that is too large, so cut it by a factor of 10 and try again.
  • Do not stop at a fixed step count only. Also stop when the loss barely changes, and check that it had really flattened and not just crawled.
  • If you write a gradient by hand, compare it with a finite-difference estimate on a few points before trusting a long run.
  • When a closed form exists, as for linear regression, use it. Gradient descent earns its place on models that have no such formula.

Go deeper in the Atlas

Encyclopedia entries on the ideas in this lesson: