Basis Lab

Answers · The mathematics underneath

Why does computing the gradient cost about the same no matter how many parameters the network has?

In shortBecause one backward sweep shares intermediate derivatives across all parameters, so the whole gradient costs a few forward passes in total rather than one per parameter.

The gradient costs about the same because backpropagation does not compute a separate derivative for each parameter. It makes one forward pass to keep the intermediate values and one backward sweep that carries a single row vector of derivatives from the loss back through every operation; the parameter derivatives fall out along the way. The cost is proportional to the number of operations and the size of the activations, not to the number of parameters.

∂L∂θ=JkJk−1⋯J2J1\frac{\partial L}{\partial \theta} = J_k J_{k-1} \cdots J_2 J_1

The product is bracketed from the loss end

The chain rule fixes the factors in that product but not the order in which they are multiplied. Matrix multiplication is associative, so the answer is the same either way, but the cost is not. Multiplying from the right, starting with J2J1J_2 J_1, means multiplying a matrix by a matrix, and the partial product stays wide because it has one column per parameter. Multiplying from the left, starting with JkJk−1J_k J_{k-1}, starts with a single row, because the loss is one number. A row vector times a matrix is a row vector, so every later product is again a single row. The chain never builds a matrix with one column per parameter. This is reverse mode, and it gives the derivative of one output with respect to all inputs in one sweep. Forward mode gives the derivative of all outputs with respect to one input per sweep, which is the wrong way round when there is one loss and billions of parameters.

(⋯((JkJk−1)Jk−2)⋯ )versus(⋯J3(J2J1)⋯ )\left(\cdots((J_k J_{k-1})J_{k-2})\cdots\right) \quad\text{versus}\quad \left(\cdots J_3(J_2 J_1)\cdots\right)
FIG 1
MethodPasses neededCost relative to one forward pass
Finite differencesone per parameter plus oneabout
Forward modeone per parameterabout
Reverse modeone forward, one backwarda small constant

A hand check

Take x=1x = 1, w1=0.5w_1 = 0.5, w2=2w_2 = 2 and target y=1y = 1, with the chain a=w1xa = w_1 x, h=tanh⁡ah = \tanh a, p=w2hp = w_2 h, L=(p−y)2L = (p - y)^2. Forward: a=0.5a = 0.5, h=tanh⁡(0.5)=0.462117h = \tanh(0.5) = 0.462117, p=2h=0.924234p = 2h = 0.924234, and L=(0.924234−1)2=0.005740L = (0.924234 - 1)^2 = 0.005740. Those four numbers are all the forward pass has to produce, and all four are kept.

The backward sweep starts at LL with dL/dL=1dL/dL = 1. At pp, dL/dp=2(p−y)=2(−0.075766)=−0.151532dL/dp = 2(p - y) = 2(-0.075766) = -0.151532. At hh, dL/dh=(dL/dp)w2=−0.151532×2=−0.303064dL/dh = (dL/dp) w_2 = -0.151532 \times 2 = -0.303064. At aa, 1−h2=1−0.4621172=0.7864481 - h^2 = 1 - 0.462117^2 = 0.786448, so dL/da=−0.303064×0.786448=−0.238320dL/da = -0.303064 \times 0.786448 = -0.238320. The parameter derivatives then fall out: dL/dw2=(dL/dp)h=−0.151532×0.462117=−0.070003dL/dw_2 = (dL/dp)h = -0.151532 \times 0.462117 = -0.070003, and dL/dw1=(dL/da)x=−0.238320×1=−0.238320dL/dw_1 = (dL/da)x = -0.238320 \times 1 = -0.238320. Each step is one multiplication by a value already computed on the forward pass. No extra pass is made for w1w_1 or w2w_2.

What the guess misses

The natural guess is that nn parameters need nn derivatives, so the cost should grow with nn. Computing each derivative independently would indeed cost about nn forward passes by finite differences, or about nn sweeps by forward mode. The mistake is to treat the derivatives as separate objects. The derivative at hh is reused on the way to both w2w_2 and w1w_1, and the derivative at pp is reused before that. The chain rule lets the same backward sweep supply every partial derivative, because all of them are entries of one row vector travelling back through the same operations. The row vector grows longer as the parameter count grows, but it is still one vector, and it is still produced by one sweep.

The price of that saving is memory rather than arithmetic. The local derivative of an operation depends on the values that went into it: the slope of tanh⁡\tanh at aa needs hh, and the derivative with respect to w2w_2 needs hh again. So the forward pass cannot discard its activations. Every intermediate value for every layer, and for every example in the batch, stays resident until the backward sweep has passed it. That is usually the binding constraint: the arithmetic of a backward pass is about twice the forward pass, while the memory is roughly the size of every intermediate value the model produced. Checkpointing trades some of that memory back for extra compute by throwing activations away and recomputing them during the sweep. The argument also depends on the loss being a single number. If there were many outputs and few inputs, reverse mode would no longer be the cheap direction, and forward mode would win instead.

The number of parameters changes the length of the row vector, not the number of sweeps. The cost is set by the number of operations and the size of the activations.

Worth keeping

  • The gradient is a product of Jacobians, and the order of multiplication decides whether the cost grows with the parameter count.
  • Multiplying from the loss end keeps every intermediate a row vector, so one backward sweep produces every partial derivative.
  • The saving is paid for in memory, because each operation's local derivative needs the forward values that went into it.

Where this goes next

This question is one step of The Mathematics of Gradient Descent, a course that works through its subject from the beginning. The page that teaches this part of it is Where the Gradient Comes From, and it reads the whole way through whether or not you have an account.

What an account changes is the practice: problems standing under every idea, marked with a reason rather than a tick, in a copy of the course that is yours.

Read that pageThe whole course

Other questions people ask about this

  1. Why is the negative gradient the direction of steepest descent?A unit step goes downhill fastest when it points directly opposite the gradient, because the dot product with the gradient is then as negative as it can be.
  2. How does momentum stop the steps from cancelling each other out?Momentum keeps a running total of past gradients, so directions that keep agreeing build up while directions that keep flipping sign cancel out.
  3. Why does Adam need bias correction at the start of training?Adam needs bias correction because its two running averages start at zero, and without correction the early steps are several times larger than the learning rate asks for.
  4. Why does gradient descent still work when each step uses only one minibatch's gradient?A minibatch gradient is wrong at every step but correct on average, so the errors cancel over many steps while the true downhill pull keeps adding up.
  5. What is the difference between variance and standard deviation?They measure the same spread: variance is the average squared distance from the mean, standard deviation is its square root, so you report the standard deviation and calculate with the variance.
  6. How do you make a vague claim precise enough to tell whether it's true?Fix what is being talked about, what is asserted, which cases are covered and the cut-off, then name an observation that would prove it false.

Read alongside