AnyLearn
All lessons
Mathintermediate

The Chain Rule, and Why Depth Is Hard

A deep network is a composition, so its derivative is a product of Jacobians. This lesson builds the chain rule from one variable up to matrix form, shows that the order you multiply that product in changes the cost tenfold, and explains vanishing gradients as an arithmetic consequence rather than a mystery.

Updated · AI-authored, review-gated · how lessons are made

Not signed in: your progress and quiz score won't be saved.
Progress1 / 10

Every model is a composition

Strip the vocabulary away and a deep network is one function applied after another:

f=fLfL1f2f1f = f_L \circ f_{L-1} \circ \cdots \circ f_2 \circ f_1

Each fif_i is a layer: an affine map, an activation, an attention block, a normalisation. Nothing in that list is difficult to differentiate on its own. The difficulty is entirely in the composition, because you never get to differentiate a layer in isolation. You need the derivative of the whole stack with respect to a weight buried near the bottom.

Key idea: The chain rule is the only tool that converts local knowledge (each layer knows its own derivative) into global knowledge (how the final loss responds to any parameter anywhere). Backpropagation is not a separate algorithm. It is the chain rule with a good evaluation order.

Full lesson text

All 10 steps on one page, for reading, reference, and search.

Show

1. Every model is a composition

Strip the vocabulary away and a deep network is one function applied after another:

f=fLfL1f2f1f = f_L \circ f_{L-1} \circ \cdots \circ f_2 \circ f_1

Each fif_i is a layer: an affine map, an activation, an attention block, a normalisation. Nothing in that list is difficult to differentiate on its own. The difficulty is entirely in the composition, because you never get to differentiate a layer in isolation. You need the derivative of the whole stack with respect to a weight buried near the bottom.

Key idea: The chain rule is the only tool that converts local knowledge (each layer knows its own derivative) into global knowledge (how the final loss responds to any parameter anywhere). Backpropagation is not a separate algorithm. It is the chain rule with a good evaluation order.

2. One variable, and why it is a product

For y=f(g(x))y = f(g(x)) the rule is a product of two local slopes:

dydx=f(g(x))g(x)\frac{dy}{dx} = f'(g(x)) \cdot g'(x)

The reason it multiplies rather than adds is worth holding onto. A nudge of size hh in xx produces a nudge of about g(x)hg'(x)h in the intermediate value, and that nudge is then scaled again by ff' at the point it arrives. Sensitivities compose by multiplication because each stage amplifies whatever reaches it.

Concretely, with f(u)=u3f(u) = u^3 and g(x)=sinxg(x) = \sin x:

ddxsin3x=3sin2xcosx\frac{d}{dx}\sin^3 x = 3\sin^2 x \cdot \cos x

That multiplicative structure is the whole story of this lesson. It is what makes backpropagation efficient, and also what makes deep networks numerically fragile.

3. When a variable influences the answer twice

In a real graph an input rarely reaches the output by one route. A residual block sends the same tensor down two paths; a shared embedding matrix is read at every position in the sequence.

When yy depends on xx through several intermediates u1,,uku_1, \dots, u_k, the contributions add:

dydx=j=1kyujujx\frac{dy}{dx} = \sum_{j=1}^{k} \frac{\partial y}{\partial u_j} \frac{\partial u_j}{\partial x}

Multiply along a path, add across paths. That single sentence is the complete multivariable chain rule, and it is exactly what a framework implements: gradients arriving at a node from different consumers are accumulated with +=, never overwritten.

Gotcha: A hand-written backward pass that assigns instead of accumulating will be silently correct on a plain feed-forward stack and silently wrong the moment anything is reused. The bug looks like a model that trains, just worse.

4. Two paths, one sum

Here xx reaches yy through both uu and vv. The derivative dy/dxdy/dx is the product along the top path plus the product along the bottom one. Every branch in a computation graph is a term in that sum, and every merge is where the terms get added back together.

flowchart LR
  X["x"] --> U["u = g(x)"]
  X --> V["v = h(x)"]
  U --> Y["y = k(u, v)"]
  V --> Y

5. The matrix form

Once layers map vectors to vectors, each local derivative is a Jacobian and the chain rule becomes matrix multiplication. For y=f3(f2(f1(x)))y = f_3(f_2(f_1(x))):

Jf(x)=Jf3Jf2Jf1J_f(x) = J_{f_3} \cdot J_{f_2} \cdot J_{f_1}

The shapes have to interlock, and checking them catches most errors before you run anything. Take a stack that goes from 1000 inputs to 100, then to 10, then to a single scalar loss:

  • Jf1J_{f_1} is 100×1000100 \times 1000
  • Jf2J_{f_2} is 10×10010 \times 100
  • Jf3J_{f_3} is 1×101 \times 10

The product (1×10)(10×100)(100×1000)(1 \times 10)(10 \times 100)(100 \times 1000) is 1×10001 \times 1000: one row, one entry per input parameter. That row is the gradient. The whole of backpropagation is evaluating this product without ever building the matrices in it.

6. A two-layer network, done by hand

Written out for a small network, the chain rule is unremarkable code. Each line is one Jacobian applied to whatever arrived from above.

import numpy as np

# forward: h = tanh(W1 x),  y = W2 h,  L = 0.5 * ||y - t||^2
z = W1 @ x
h = np.tanh(z)
y = W2 @ h
L = 0.5 * np.sum((y - t) ** 2)

# backward: start at the loss and walk back
dL_dy = y - t                      # dL/dy
dL_dW2 = np.outer(dL_dy, h)        # dL/dy times dy/dW2
dL_dh = W2.T @ dL_dy               # dy/dh is W2, so transpose it
dL_dz = dL_dh * (1 - h ** 2)       # tanh' = 1 - tanh^2, a diagonal Jacobian
dL_dW1 = np.outer(dL_dz, x)

Notice dL_dz: the Jacobian of an elementwise activation is diagonal, so applying it is a vector multiply rather than a matrix one. That single optimisation is why activations are nearly free in the backward pass.

7. The same product, two orders, two prices

Matrix multiplication is associative, so the value of J3J2J1J_3 J_2 J_1 does not depend on where you put the brackets. The cost does, and dramatically.

Predict first

Using the shapes from before, J3 is 1x10, J2 is 10x100, J1 is 100x1000. Multiplying an (a x b) by a (b x c) matrix costs abc multiplications. Which bracketing is cheaper: (J3 J2) J1, or J3 (J2 J1)?

This is not a micro-optimisation. Working right to left is forward-mode differentiation; working left to right, from the loss backwards, is reverse mode, which is to say backpropagation. They compute the identical number.

8. The arithmetic behind that factor of ten

BracketingFirst productSecond productTotal multiplications
J3(J2J1)J_3 (J_2 J_1), forward mode10×100×1000=1,000,00010 \times 100 \times 1000 = 1{,}000{,}0001×10×1000=10,0001 \times 10 \times 1000 = 10{,}0001,010,000
(J3J2)J1(J_3 J_2) J_1, reverse mode1×10×100=1,0001 \times 10 \times 100 = 1{,}0001×100×1000=100,0001 \times 100 \times 1000 = 100{,}000101,000

The gap widens as the network gets wider and deeper, because the forward order pays for intermediates whose height is the input dimension while the reverse order never exceeds the output dimension.

Machine learning sits at the extreme end of that trade: millions of inputs, one scalar output. That asymmetry, and nothing else, is why every training framework differentiates backwards.

9. Why long products die

A product of LL Jacobians behaves like a number raised to the power LL. If each factor typically shrinks the signal, the product collapses; if each amplifies, it explodes. Neither needs anything exotic to happen.

The logistic sigmoid makes the point exactly. Its derivative is σ(x)(1σ(x))\sigma(x)(1 - \sigma(x)), and here is that curve:

Derivative of the logistic sigmoid
derivative00.050.10.150.20.25-6-4-2-101246
Source: Computed: s(x)(1-s(x)) for the logistic sigmoid

The peak is 0.25, at the single point x=0x = 0. Even in the best case every sigmoid layer multiplies the gradient by at most a quarter, so ten stacked layers shrink it by at most 0.25100.25^{10}, roughly 10610^{-6}. Away from zero it is far worse: at x=6x = 6 the factor is 0.0025.

10. What the architecture fixes are, in calculus terms

The standard remedies all read as edits to the Jacobian product rather than to the optimiser.

  • ReLU has derivative exactly 1 wherever it is active, so it contributes a factor of 1 instead of at most 0.25.
  • A residual connection computes y=x+F(x)y = x + F(x), whose Jacobian is I+JFI + J_F. The identity term leaves a route with a factor of 1 through the entire depth, so the product cannot vanish just because it is long.
  • Gradient clipping rescales the product after the fact when it explodes, which treats the symptom and is honest about it.
  • Normalisation layers hold activations in the range where derivatives are largest, keeping factors near 1 rather than out on the flat tails.

Key idea: "Vanishing gradient" is not a pathology of deep learning. It is what happens when you multiply many numbers smaller than one together, and the architectural answer is to keep the factors near one.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. In a computation graph, a tensor is consumed by two different downstream operations. How do the gradients combine?
    • The larger of the two is kept
    • They are multiplied together
    • Only the gradient from the first consumer is used
    • They are summed, because the multivariable chain rule adds across paths
  2. J3 is 1x10, J2 is 10x100, J1 is 100x1000. Why is (J3 J2) J1 cheaper than J3 (J2 J1)?
    • Every intermediate stays one row tall, so no fat matrix-matrix product is ever formed
    • Because matrix multiplication is not associative, so only one order is valid
    • Because it avoids transposing J1
    • Because the second order loses precision and needs extra passes
  3. What is the maximum value of the logistic sigmoid's derivative, and where does it occur?
    • 1, at large positive x
    • 0.25, at x = 0
    • 0.5, at x = 0
    • It is unbounded near x = 0
  4. In calculus terms, why does a residual connection y = x + F(x) help gradients reach early layers?
    • It reduces the number of layers the gradient has to pass through
    • It makes every Jacobian diagonal, which is cheaper to apply
    • Its Jacobian is I + J_F, so an identity route with factor 1 runs through the full depth
    • It replaces the chain rule with a sum rule
  5. A hand-written backward pass assigns gradients with = instead of accumulating with +=. When does this first cause a wrong answer?
    • Immediately, on any network at all
    • Only when the loss is non-convex
    • Never, since assignment and accumulation agree at a single node
    • As soon as any tensor is used by more than one downstream operation

Related lessons

Math
intermediate

Automatic Differentiation: How Gradients Are Actually Computed

Frameworks do not differentiate formulas symbolically or estimate derivatives numerically. They differentiate the program. This lesson builds forward mode from dual numbers and reverse mode from the backward sweep, shows why a full gradient costs about four function evaluations at any size, and where the answer is not what you meant.

10 steps·~15 min
Math
intermediate

Gradients, Jacobians, and Hessians: Calculus in Many Dimensions

One derivative becomes three objects once a function has many inputs and many outputs. This lesson builds the gradient, the Jacobian and the Hessian, shows what each one actually tells you, and explains why curvature decides how many steps an optimiser needs and why nobody ever writes the Hessian down.

10 steps·~15 min
AI
advanced

Evaluating a Book Model Honestly

If your cost per round trip equals the move you are trying to capture, you need 100 percent directional accuracy to break even. This lesson computes that hurdle, replaces accuracy with metrics tied to a tradeable decision, and covers the capacity and latency limits that decide whether a real edge is worth anything.

10 steps·~15 min
AI
advanced

Why Reported Order Book Results Do Not Replicate

At a one-event horizon, 92 percent of mid-price labels are exactly no-change, so a model that always predicts flat scores 92 percent accuracy. This lesson computes that baseline across horizons and works through the four mechanisms that turn a genuine measurement into a number nobody can reproduce.

10 steps·~15 min