What is gradient descent?
Gradient descent finds the lowest point of a function by taking small steps downhill. Training a machine learning model uses it to make errors smaller.
In this lesson you will take the steps by hand and then by loop. You will also see why the size of each step, the learning rate, decides whether it works.
By the end of this lesson
Note
I can minimise a function by stepping downhill.
Key words
| Word | What it means |
|---|---|
| Minimum | the lowest value a function reaches |
| Gradient descent | repeated small steps downhill to find a minimum |
| Learning rate | the size of each step, as a share of the slope |
| Convergence | the steps settling on one answer |
| Divergence | the steps growing bigger instead of settling |
The cells students fill in are left blank in this preview.
Each step subtracts a share of the slope
Stand at a point. If the slope is positive the function rises to the right, so move left. If it is negative, move right. Both are the same move: subtract the slope.
The update is new x = x - rate * slope. The learning rate is a small number such as 0.1 that stops the step from being too big.
Worked example: five steps towards 3
| Step | x | Slope 2 times (x - 3) | Change: minus 0.1 times slope | New x |
|---|---|---|---|---|
| 1 | 0 | -6 | +0.6 | 0.6 |
| 2 | 0.6 | -4.8 | +0.48 | 1.08 |
| 3 | 1.08 | -3.84 | +0.384 | 1.464 |
| 4 | 1.464 | -3.072 | +0.3072 | 1.771 |
| 5 | 1.771 | -2.458 | +0.2458 | 2.017 |
The cells students fill in are left blank in this preview.
Run the five steps in the lab
docker exec jupyter python3 -c "exec('x = 0.0\nfor n in range(1, 6):\n x = x - 0.1 * 2 * (x - 3)\n print(n, round(x, 3))')"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
You stop when the ground is nearly flat
The steps never reach the minimum exactly. They get closer each time, so you need a rule for when to stop.
Stop when the slope is smaller than a tolerance, such as 0.01. Also stop after a fixed number of steps, in case the slope never gets that small. Both checks go in the loop condition.
A loop that stops on its own
# Walk downhill on (x - 3) squared until the ground is nearly flat.
def slope(x):
return 2 * (x - 3)
x = 0.0
rate = 0.1
steps = 0
while abs(slope(x)) > 0.01 and steps < 1000:
x = x - rate * slope(x)
steps = steps + 1
print(steps, round(x, 3))
# Change rate to 0.5, then to 0.01. How do the steps change?
A learning rate that is too big diverges
A tiny rate crawls: many steps for a short walk. A good rate settles in a few dozen steps. A rate that is too big jumps over the bottom and lands higher up on the other side.
For x squared the slope is 2x. With a rate of 1.1 each step multiplies x by -1.2. The point flips sides and every jump is bigger than the last. This is divergence.
Worked example: three rates from x = 5
| Learning rate | x after 1 step | x after 2 steps | x after 3 steps | What happens |
|---|---|---|---|---|
| 0.1 | 4 | 3.2 | 2.56 | Settles slowly towards 0 |
| 1.0 | -5 | 5 | -5 | Bounces and never settles |
| 1.1 | -6 | 7.2 | -8.64 | Diverges |
The cells students fill in are left blank in this preview.
Watch a rate of 1.1 diverge
docker exec jupyter python3 -c "exec('x = 5.0\nfor n in range(1, 6):\n x = x - 1.1 * 2 * x\n print(n, round(x, 3))')"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think a bigger learning rate always gets there faster. Up to a point it does. Past that point the steps overshoot and the answer gets worse each time. Start small, then raise the rate while it still settles.
Going further
In your own notebook, change the code block so the bowl is (x - 3) ** 2 + 10.
Predict first whether the steps and the final x change. The slope is the same, so only the height of the bowl moved.