The chain rule
Derivatives of functions inside functions: the heart of backprop.
Create a free account Try part of it here
Why it matters
A neural network is a long chain of small steps. Each layer feeds the next one. At the end sits the loss: a score of how wrong the model was. Training means adjusting the model's inner numbers, its weights, to shrink that loss. So you need to know how each weight affects the loss, however far back in the chain it sits. The chain rule tells you: multiply the rates of change along the path from the weight to the loss. Backpropagation, the method that trains every modern model, is the chain rule organized so that each step is worked out only once.
What you'll be able to do
- Differentiate a function inside a function by multiplying rates
- Follow a computation graph forward (values) and backward (derivatives)
- Compute the gradient of a single neuron's loss by hand
- Explain backpropagation as the chain rule applied from the loss backwards
What it covers
- Rates multiply along a chain
- The chain rule
- Models are chains too
- Worked example: a one-weight model
- Forward, then backward: one neuron
- Reading the result
- Why go backward?
Rates multiply along a chain
Picture an ad campaign as a chain with three links. Spending money buys clicks. Some clicks turn into conversions (a sale or a sign-up). Each conversion brings in revenue.
Say each extra dollar buys 2 clicks. Each click yields 0.05 conversions, which is one conversion in every 20 clicks. Each conversion is worth $60. How much revenue does one extra dollar bring in?
Follow the dollar down the chain. It buys 2 clicks. Those make 2 × 0.05 = 0.1 conversions. Those are worth 0.1 × 60 = $6. So each extra dollar of spend is worth of revenue.
Rates along a chain multiply. That one idea is the chain rule.
Show the answer
0.3
Rates along a chain multiply: 3 × 0.1 = 0.3. Adding them (3.1) is a common mistake.
The chain rule
In code, a function inside a function looks like f(g(x)). First g runs on . Then f runs on whatever g gave back.
Give that middle value a name: . The final answer is then . Now there are three rates, each written like a fraction:
- is how fast the middle value changes as changes;
- is how fast the answer changes as changes;
- is the one you want: how fast changes as changes.
Each one is a slope, the same idea as from the last two lessons. The chain rule says:
In plain words: the overall rate is the outside rate times the inside rate. It's the ad chain again: dollars to clicks, then clicks to revenue.
Here's a worked example: , at .
- The inside step is . Each extra 1 in adds 3 to , so . At , .
- The outside step is . The power rule gives . At , that's 14.
- Multiply the two rates: .
The same steps work for every at once:
At , that's again. Python checks it with the nudge method. Here rule is the chain-rule answer. numeric moves a millionth up and down and measures the change.
f = lambda x: (3 * x + 1) ** 2 rule = lambda x: 6 * (3 * x + 1) x = 2.0 numeric = (f(x + 1e-6) - f(x - 1e-6)) / 2e-6 print(rule(x), round(numeric, 4))
Both print 42.0.
Watch out: work out the outside slope at the inside value. Here means , not .
Go deeper Why the rates multiply
Nudge by a tiny amount . The middle value moves by about . That move in is itself a nudge, so moves by about times it:
Here (delta y) means "the change in y". Divide by to get the slope. As shrinks toward 0, the "about" becomes exact, and the chain rule is what's left.
inside_rate = 4 # u = 4x - 1 u = 4 * 1 - 1 # the inside value at x = 1 outside_rate = 2 * u # slope of u squared print(outside_rate * inside_rate)
Show the answer
24
At x = 1, u = 3. The outside rate is 2 × 3 = 6, the inside rate is 4, and the chain rule multiplies them: 24.
Models are chains too
A machine-learning model is a chain like the ad campaign. It turns an input into a prediction. Then a loss scores how wrong that prediction was: 0 is perfect, and bigger is worse. Training adjusts the model's weights, the numbers it can tune, to make the loss smaller.
The smallest possible model has one weight, . It multiplies the input by to make a prediction. The right answer is called the target, . The loss is the miss, squared: . Squaring stops the loss from going negative and punishes big misses more.
You walk this chain in two directions:
- The forward pass goes from input to loss. It computes the values: prediction, then loss.
- The backward pass goes from loss to weight. It computes the rates: first how the loss responds to the prediction, then how the prediction responds to .
Worked example: a one-weight model
Input x = 2, target y = 3, weight w = 1. The model predicts 1 × 2 = 2. It misses by −1, so the loss is (−1)² = 1. Find how the loss changes as w changes, using the chain rule. Then check it with nudges.
x, y = 2.0, 3.0 # input and target w = 1.0 # the weight we can adjust pred = w * x # forward: the prediction loss = (pred - y) ** 2 # forward: the loss dloss_dpred = 2 * (pred - y) # backward: outside rate dpred_dw = x # backward: inside rate dloss_dw = dloss_dpred * dpred_dw h = 1e-6 nudge = (((w + h) * x - y) ** 2 - ((w - h) * x - y) ** 2) / (2 * h) print(pred, loss) print(dloss_dpred, dpred_dw, dloss_dw, round(nudge, 4))
The outside rate is the slope of "miss squared", which is 2 × miss: 2 × (−1) = −2. The inside rate is how the prediction moves with w. Raising w by 1 raises w × x by x, which is 2. Multiply: −2 × 2 = −4, and the nudge agrees. The minus sign is the useful part: raising w lowers the loss. Sure enough, w = 1.5 predicts exactly 3, and the loss drops to 0.
Forward, then backward: one neuron
A neuron, the building block of a neural network, makes this chain one step longer. After multiplying by , it adds a second adjustable number, the bias . Then it passes the result through the sigmoid from earlier lessons, which is the S-shaped curve that squashes any number into the range 0 to 1.
In machine learning (the subject of Phase 3), chains like this are drawn as a computation graph: a row of small steps, each taking inputs and producing an output. With input and target , the neuron's graph has three steps:
In plain words: is the input times the weight, plus the bias. , the activation, is squashed by the sigmoid. is the loss: the miss between and the target, squared.
Try it with small numbers: input , target , weight , bias . The forward pass fills in the values from left to right:
print(round((0.6225 - 1) ** 2, 3))
Show the answer
0.143
The miss is about −0.38, and squaring it gives about 0.143. That's the forward pass finished.
The backward pass goes right to left. This chain has two numbers you can adjust, and , so you want a rate for each. These rates are written with a curly d, , said "partial". means how fast changes as changes, with everything else held still. Partial derivatives get their own lesson next. For now, read each one as a slope.
Each backward step reuses the one before it:
- Loss to activation. As in the one-weight model, the slope is 2 × miss: .
- Activation to z. The last lesson gave the sigmoid's slope as . Since , that's : . Multiply: .
- z to w. In , raising by 1 raises by . So multiply by : about .
- z to b. Raising by 1 raises by 1. So multiply by 1: about .
Here are the same four steps in symbols:
In plain words: start at the loss. At each step back, multiply by that step's own slope. When you reach a weight, you have its rate.
The stepper below runs the same numbers in Python.
Step through: the forward lines fill in z, a and L; the backward lines multiply local slopes from the loss back to w and b.
Reading the result
The code prints 0.1425 -0.3549: the loss, then .
That slope is negative. So increasing would lower the loss. Training therefore nudges up a little. The next lessons turn that habit into a method called gradient descent.
Every weight in a network gets its slope the same way. Start at the loss, walk backward, and multiply the local slopes.
Show the answer
Down: a positive slope means raising w raises the loss
A positive slope means the loss rises as w rises. So lowering w lowers the loss.
Why go backward?
A deep network has many weights feeding into the same later steps. Think of streams that join a river, which then flows to the sea. Once you know how the river reaches the sea, every stream that joins it can reuse that answer. Nobody has to trace the whole way again.
Going backward from the loss, each in-between rate (like ) is worked out once. Then every weight that feeds into it reuses it. So one backward pass costs about the same as one forward pass, no matter how many weights there are. This is backpropagation, often shortened to backprop.
It also explains the vanishing-gradient problem from the last lesson. In a deep stack of sigmoids, the backward pass multiplies many slopes of at most 0.25. Five of them multiply to about 0.001. So the slopes for the early layers shrink toward zero, and those layers barely learn.
For later: frameworks like PyTorch, which is the library Phase 4 uses, build the computation graph as your code runs and call
loss.backward()to run the backward pass for you. You'll write one by hand in Phase 4 (and Baby AI already uses one).
slope = 1.0 for layer in range(5): slope = slope * 0.25 print(round(slope, 4))
Show the answer
0.001
The backward pass multiplies the slopes: 0.25 five times is about 0.001. Even at its best, the signal shrinks fast. That's the vanishing gradient.
Practice what you just read
- 2 code examples you can edit and run
- a practice exercise that checks your code
- a 5-question quiz
- 4 review cards for spaced repetition
Try a quiz question
What is the derivative of (2x + 5)³?