Hyoungseo Son
Matrix Calculus & Autodiff
Contents · Matrix Calculus & Autodiff

Part 1 · Automatic Differentiation

Part 2 · Backpropagation

  • Backpropagation, Step by Step

Part 3 · Differentiable Simulation

Part 2 · Backpropagation

Backpropagation, Step by Step

Backpropagation is not a special algorithm for neural nets. It is reverse-mode automatic differentiation applied to one particular composite function: a scalar loss LL stacked on top of a layered network. A forward pass evaluates the network and caches each activation; a backward pass then pushes the loss gradient through those cached values, layer by layer, reusing the same weights the forward pass used. One backward sweep costs about one forward pass and returns L/θ\partial L/\partial\theta for every parameter at once, which is exactly why training deep nets, and the policy and value networks of deep reinforcement learning, is tractable.12

The two passes

Write the network with pre-activations zl\mathbf z^{l} and activations al\mathbf a^{l}. The forward pass is

a0=x,zl=Wlal1+bl,al=σ(zl),\mathbf a^{0} = \mathbf x, \qquad \mathbf z^{l} = W^{l}\mathbf a^{l-1} + \mathbf b^{l}, \qquad \mathbf a^{l} = \sigma(\mathbf z^{l}),

ending in a scalar loss L(aL,y)L(\mathbf a^{L}, \mathbf y). Define the error at layer ll as δl=L/zl\boldsymbol\delta^{l} = \partial L / \partial \mathbf z^{l}. The chain rule gives it a recurrence that runs from the output back to the input,

δL=aLσ(zL),δl=((Wl+1)δl+1)σ(zl),\boldsymbol\delta^{L} = \nabla_{\mathbf a}L \odot \sigma'(\mathbf z^{L}), \qquad \boldsymbol\delta^{l} = \big((W^{l+1})^{\top}\boldsymbol\delta^{l+1}\big)\odot\sigma'(\mathbf z^{l}),

and the parameter gradients fall out of each δl\boldsymbol\delta^{l} directly,

WlL=δl(al1),blL=δl.\nabla_{W^{l}}L = \boldsymbol\delta^{l}\,(\mathbf a^{l-1})^{\top}, \qquad \nabla_{\mathbf b^{l}}L = \boldsymbol\delta^{l}.

The transpose (Wl+1)(W^{l+1})^{\top} sends the error backward along the same edges the forward pass used, σ(zl)\sigma'(\mathbf z^{l}) is the local derivative of the nonlinearity, and the outer product with the cached al1\mathbf a^{l-1} turns a layer's error into its weight gradient. Nothing here is a heuristic; it is the chain rule, evaluated in the order that shares work.

A 2-2-1 network, by hand

Take two inputs, two tanh\tanh hidden units, one linear output, and the single-sample squared-error loss L=12(a2y)2L = \tfrac12(a^{2}-y)^{2} (the 12\tfrac12 makes L/a2=a2y\partial L/\partial a^{2} = a^{2}-y). Fix the weights, input, and target:

W1=[0.100.200.300.40],  b1=[0.100.20],  W2=[0.500.60],  b2=0.20,  x=[0.50.8],  y=1.W^{1}=\begin{bmatrix}0.10 & 0.20\\ 0.30 & 0.40\end{bmatrix},\; \mathbf b^{1}=\begin{bmatrix}0.10\\ 0.20\end{bmatrix},\; W^{2}=\begin{bmatrix}0.50 & 0.60\end{bmatrix},\; b^{2}=0.20,\; \mathbf x=\begin{bmatrix}0.5\\ 0.8\end{bmatrix},\; y=1.

Forward. The hidden pre-activations and activations are

z1=[0.100.200.300.40][0.50.8]+[0.100.20]=[0.310.67],a1=tanhz1=[0.30040.5850].\mathbf z^{1}=\begin{bmatrix}0.10 & 0.20\\ 0.30 & 0.40\end{bmatrix}\begin{bmatrix}0.5\\ 0.8\end{bmatrix}+\begin{bmatrix}0.10\\ 0.20\end{bmatrix}=\begin{bmatrix}0.31\\ 0.67\end{bmatrix}, \qquad \mathbf a^{1}=\tanh\mathbf z^{1}=\begin{bmatrix}0.3004\\ 0.5850\end{bmatrix}.

The output and loss are

a2=z2=[0.500.60][0.30040.5850]+0.20=0.7012,L=12(0.70121)2=0.0446.a^{2}=z^{2}=\begin{bmatrix}0.50 & 0.60\end{bmatrix}\begin{bmatrix}0.3004\\ 0.5850\end{bmatrix}+0.20=0.7012, \qquad L=\tfrac12(0.7012-1)^{2}=0.0446.

Backward, output layer. The output is linear, so σ(z2)=1\sigma'(z^{2})=1 and

δ2=(a2y)1=0.2988,W2L=δ2(a1)=0.2988[0.30040.5850]=[0.08980.1748].\delta^{2}=(a^{2}-y)\cdot 1 = -0.2988, \qquad \nabla_{W^{2}}L=\delta^{2}(\mathbf a^{1})^{\top}=-0.2988\begin{bmatrix}0.3004 & 0.5850\end{bmatrix}=\begin{bmatrix}-0.0898 & -0.1748\end{bmatrix}.

Backward, hidden layer. For tanh\tanh, σ(z)=1tanh2z=1(a1)2\sigma'(z)=1-\tanh^{2}z=1-(a^{1})^{2}, so

(W2)δ2=[0.500.60](0.2988)=[0.14940.1793],σ(z1)=[0.90970.6578],(W^{2})^{\top}\delta^{2}=\begin{bmatrix}0.50\\ 0.60\end{bmatrix}(-0.2988)=\begin{bmatrix}-0.1494\\ -0.1793\end{bmatrix}, \qquad \sigma'(\mathbf z^{1})=\begin{bmatrix}0.9097\\ 0.6578\end{bmatrix}, δ1=[0.14940.1793][0.90970.6578]=[0.13590.1179],W1L=δ1(a0)=[0.06800.10870.05900.0943].\boldsymbol\delta^{1}=\begin{bmatrix}-0.1494\\ -0.1793\end{bmatrix}\odot\begin{bmatrix}0.9097\\ 0.6578\end{bmatrix}=\begin{bmatrix}-0.1359\\ -0.1179\end{bmatrix}, \qquad \nabla_{W^{1}}L=\boldsymbol\delta^{1}(\mathbf a^{0})^{\top}=\begin{bmatrix}-0.0680 & -0.1087\\ -0.0590 & -0.0943\end{bmatrix}.

One SGD step WWηWLW\leftarrow W-\eta\,\nabla_{W}L with η=0.5\eta=0.5 drives this sample's loss from 0.04460.0446 down to 0.00030.0003 on the next forward pass.

Backpropagation through a 2-2-1 netinteractive
ready0.500.80?tanh?tanh?y = 1.00input a⁰hidden a¹output a²
stateloss = n/aepoch = 0
1 forward · layer 1 ← next
2 forward · layer 2 + loss
3 backward · output
4 backward · hidden
5 apply · SGD update
press Step
Step through the forward and backward passes to see the numbers.
The same 2-2-1 network, computed live. Step forward (blue) to fill z and a at each layer, then backward (red) to compute the output error, the hidden error, and the weight gradients, with the substituted arithmetic in the panel. Apply runs one SGD update at eta = 0.5, and the loss-per-epoch trace shows the loss dropping. Auto loops through forward, backward, and update.

Why it scales

The backward recurrence touches each weight exactly once and reuses activations already cached in the forward pass, so computing the full gradient costs the same order as a single evaluation of the network, independent of how many parameters there are. That is the reverse-mode payoff: differentiate a scalar output with respect to millions of inputs in one sweep. Stack it with SGD and you can fit deep networks, and because a policy or value network is just another composite function ending in a scalar objective, the identical machinery is what makes deep reinforcement learning trainable.

Footnotes

  1. Rumelhart, Hinton & Williams, Learning representations by back-propagating errors (Nature 1986).

  2. Baydin, Pearlmutter, Radul & Siskind, Automatic Differentiation in Machine Learning: a Survey (2018).