Practice / Backprop by hand

One-hidden-layer backprop, the whole backward pass

Ten problems assembling the full backward pass of a one-hidden-layer classifier: the two deltas, every parameter gradient with its shape, the gradient to the input, the batched version with the 1/N, a ReLU variant and an L2 penalty, with worked solutions and the mistakes that swap shapes or drop factors.

Before you start

The previous two pages computed the pieces of a backward pass: the gradient of softmax with cross-entropy, and the rule for pushing a gradient back through an affine map and an elementwise nonlinearity. These ten problems assemble them into the whole backward pass of a classifier with one hidden layer, first for one example and then for a batch, and then change the activation and the loss to see what moves. The five mistakes are the ones that survive a quick read: an outer product and a batched product transposed, the activation's derivative dropped, a bias gradient left unsummed, and a stray factor of 2 in weight decay.

  • The conventions are those of the previous pages: vectors are columns, Jacobians are in numerator layout, a gradient has the shape of the variable it is taken with respect to, and for a scalar LL of uu with uu a function of xx, ∇xL=(∂u/∂x)⊤∇uL\nabla_x L = (\partial u/\partial x)^\top \nabla_u L.
  • The network: x∈Rdx \in \mathbb{R}^d; z1=W1x+b1∈Rmz_1 = W_1 x + b_1 \in \mathbb{R}^m and h=σ(z1)h = \sigma(z_1), where σ\sigma is the logistic sigmoid applied elementwise, with σ′=σ(1−σ)\sigma' = \sigma(1 - \sigma); z2=W2h+b2∈Rkz_2 = W_2 h + b_2 \in \mathbb{R}^k; y^=softmax⁡(z2)\hat y = \operatorname{softmax}(z_2); and L=−∑iyilog⁡y^iL = -\sum_i y_i \log \hat y_i with yy one-hot.
  • The two deltas are the gradients at the pre-activations: δ2:=∇z2L\delta_2 := \nabla_{z_2} L and δ1:=∇z1L\delta_1 := \nabla_{z_1} L.
  • Entries: W2,ijW_{2,ij} is entry (i,j)(i,j) of W2W_2, and z2,iz_{2,i}, δ2,i\delta_{2,i}, hjh_j are entries of z2z_2, δ2\delta_2, hh; likewise one layer down.
  • ⊙\odot is the elementwise product and 1\mathbf{1} the all-ones vector.
  • Batched: rows are examples. X∈RN×dX \in \mathbb{R}^{N \times d}, Z1=XW1⊤+1b1⊤Z_1 = XW_1^\top + \mathbf{1}b_1^\top, H=σ(Z1)H = \sigma(Z_1), Z2=HW2⊤+1b2⊤Z_2 = HW_2^\top + \mathbf{1}b_2^\top, Y^\hat Y is the row-wise softmax of Z2Z_2, YY holds the one-hot targets as rows, and L=1N∑nLnL = \tfrac1N\sum_n L_n is the mean of the per-example losses. Δ2:=∇Z2L\Delta_2 := \nabla_{Z_2} L and Δ1:=∇Z1L\Delta_1 := \nabla_{Z_1} L.
  • The softmax page gives ∇z2L=y^−y\nabla_{z_2} L = \hat y - y, and the Jacobians page gives the pattern ∇in=W⊤(σ′(z)⊙∇out)\nabla_{\text{in}} = W^\top(\sigma'(z)\odot \nabla_{\text{out}}); this page only assembles them, so every step is a citation plus a shape check.

Builds on: Jacobians and the chain rule, The softmax Jacobian

Problems

  1. ·

    List the shapes of W1,b1,z1,h,W2,b2,z2,y^W_1, b_1, z_1, h, W_2, b_2, z_2, \hat y and of ∇W1L,∇b1L,∇W2L,∇b2L,∇xL\nabla_{W_1} L, \nabla_{b_1} L, \nabla_{W_2} L, \nabla_{b_2} L, \nabla_x L in terms of d,m,kd, m, k.

  2. ·

    Compute δ2=∇z2L\delta_2 = \nabla_{z_2} L.

  3. ··

    Compute ∇W2L\nabla_{W_2} L and ∇b2L\nabla_{b_2} L in terms of δ2\delta_2 and hh, with shapes.

  4. ··

    Compute ∇hL\nabla_h L.

  5. ··

    Compute δ1=∇z1L\delta_1 = \nabla_{z_1} L in terms of δ2\delta_2, W2W_2 and z1z_1, without forming any Jacobian of σ\sigma.

  6. ··

    Compute ∇W1L\nabla_{W_1} L and ∇b1L\nabla_{b_1} L.

  7. ··

    Compute ∇xL\nabla_x L. Why would you want it?

  8. ···

    Batched: with X∈RN×dX \in \mathbb{R}^{N\times d} (rows are examples), Z1=XW1⊤+1b1⊤Z_1 = XW_1^\top + \mathbf{1}b_1^\top, H=σ(Z1)H = \sigma(Z_1), Z2=HW2⊤+1b2⊤Z_2 = HW_2^\top + \mathbf{1}b_2^\top, Y^=softmax⁡(Z2)\hat Y = \operatorname{softmax}(Z_2) row-wise, YY one-hot rows and L=1N∑nLnL = \tfrac1N\sum_n L_n, compute Δ2\Delta_2, ∇W2L\nabla_{W_2} L, ∇b2L\nabla_{b_2} L, Δ1\Delta_1, ∇W1L\nabla_{W_1} L, ∇b1L\nabla_{b_1} L and ∇XL\nabla_X L, with shapes.

  9. ···

    Replace σ\sigma by ReLU⁡(z)=max⁡(z,0)\operatorname{ReLU}(z) = \max(z, 0). What changes in Problems 5–7? Write δ1\delta_1 and ∇xL\nabla_x L.

  10. ···

    Add an L2 penalty: L′=L+λ2∥W2∥F2L' = L + \tfrac{\lambda}{2}\|W_2\|_F^2. Compute ∇W2L′\nabla_{W_2} L'.

Worked solutions

Problem 1

List the shapes of W1,b1,z1,h,W2,b2,z2,y^W_1, b_1, z_1, h, W_2, b_2, z_2, \hat y and of ∇W1L,∇b1L,∇W2L,∇b2L,∇xL\nabla_{W_1} L, \nabla_{b_1} L, \nabla_{W_2} L, \nabla_{b_2} L, \nabla_x L in terms of d,m,kd, m, k.

  1. W1x∈RmW_1 x \in \mathbb{R}^m for x∈Rdx \in \mathbb{R}^d, so W1W_1 is m×dm \times d; b1b_1 is added to W1xW_1 x, so b1b_1 and z1z_1 have mm entries.A matrix takes dd-vectors to mm-vectors only if it has dd columns and mm rows, and vectors can be added only if their shapes agree.
  2. h=σ(z1)h = \sigma(z_1) has mm entries.σ\sigma is elementwise, so it keeps the shape of its input.
  3. W2h∈RkW_2 h \in \mathbb{R}^k, so W2W_2 is k×mk \times m; b2b_2, z2z_2 and y^\hat y have kk entries.Step 1 one layer up, with hh as the input; the softmax gives one probability per class, so it keeps the shape of z2z_2.
  4. Entry (i,j)(i,j) of ∇W1L\nabla_{W_1} L is ∂L/∂W1,ij\partial L/\partial W_{1,ij}, and likewise for every other variable.A gradient has one entry per entry of its variable, which is why W1−η ∇W1LW_1 - \eta\,\nabla_{W_1} L is defined.
  5. W1:m×dW_1: m\times d, b1,z1,h:mb_1, z_1, h: m; W2:k×mW_2: k\times m, b2,z2,y^:kb_2, z_2, \hat y: k; each gradient has the shape of its variable: ∇W1L:m×d\nabla_{W_1}L: m\times d, ∇b1L:m\nabla_{b_1}L: m, ∇W2L:k×m\nabla_{W_2}L: k\times m, ∇b2L:k\nabla_{b_2}L: k, ∇xL:d\nabla_x L: dEvery answer below is checked against this list.

Problem 2

Compute δ2=∇z2L\delta_2 = \nabla_{z_2} L.

  1. As a function of z2z_2, L=−∑iyilog⁡softmax⁡(z2)iL = -\sum_i y_i \log \operatorname{softmax}(z_2)_i.y^=softmax⁡(z2)\hat y = \operatorname{softmax}(z_2), and δ2\delta_2 holds everything below z2z_2 fixed.
  2. Let cc be the index with yc=1y_c = 1. Then L=−z2,c+log⁡∑jez2,jL = -z_{2,c} + \log\sum_j e^{z_{2,j}}.Only the target term of the sum survives, and log⁡y^c=z2,c−log⁡∑jez2,j\log\hat y_c = z_{2,c} - \log\sum_j e^{z_{2,j}}.
  3. ∂L/∂z2,j=−yj+y^j\partial L/\partial z_{2,j} = -y_j + \hat y_j.z2,cz_{2,c} contains z2,jz_{2,j} only when j=cj = c, which is yjy_j; the log-sum-exp term differentiates to ez2,j/∑j′ez2,j′=y^je^{z_{2,j}}/\sum_{j'} e^{z_{2,j'}} = \hat y_j. This is the softmax page's Problem 5 with z=z2z = z_2.
  4. δ2=y^−y\delta_2 = \hat y - yk×1k \times 1, the shape of z2z_2. Its entries sum to 00: the target entry is y^c−1<0\hat y_c - 1 < 0 and the others are positive.

Problem 3

Compute ∇W2L\nabla_{W_2} L and ∇b2L\nabla_{b_2} L in terms of δ2\delta_2 and hh, with shapes.

  1. z2,i=∑jW2,ijhj+b2,iz_{2,i} = \sum_j W_{2,ij} h_j + b_{2,i}.Index form shows which entry of z2z_2 each entry of W2W_2 and b2b_2 builds.
  2. W2,ijW_{2,ij} appears only in z2,iz_{2,i}, with coefficient hjh_j.It sits in row ii of W2W_2, and row ii builds only z2,iz_{2,i}; within that sum, only term jj contains it.
  3. ∂L/∂W2,ij=∑i′∂L∂z2,i′ ∂z2,i′∂W2,ij=δ2,i hj\partial L/\partial W_{2,ij} = \sum_{i'} \dfrac{\partial L}{\partial z_{2,i'}}\,\dfrac{\partial z_{2,i'}}{\partial W_{2,ij}} = \delta_{2,i}\, h_j.LL depends on W2W_2 only through z2z_2; by step 2 only the i′=ii' = i term is nonzero.
  4. (δ2h⊤)ij=δ2,ihj(\delta_2 h^\top)_{ij} = \delta_{2,i} h_j, with shapes (k×1)(1×m)=k×m(k \times 1)(1 \times m) = k \times m.An outer product ab⊤ab^\top has entries aibja_i b_j: the row index comes from δ2\delta_2 and the column index from hh, matching step 3.
  5. ∂L/∂b2,i=δ2,i\partial L/\partial b_{2,i} = \delta_{2,i}.b2,ib_{2,i} appears only in z2,iz_{2,i}, with coefficient 11: ∂z2/∂b2=Ik\partial z_2/\partial b_2 = I_k (the Jacobians page, Problem 2).
  6. ∇W2L=δ2h⊤\nabla_{W_2} L = \delta_2 h^\top (k×mk\times m); ∇b2L=δ2\nabla_{b_2} L = \delta_2k×mk \times m and kk, the shapes of W2W_2 and b2b_2 from Problem 1. It is the Jacobians page's (Wx−y) x⊤(Wx - y)\,x^\top with δ2\delta_2 as the incoming gradient: the gradient at the output of the affine map times its input, transposed.

Problem 4

Compute ∇hL\nabla_h L.

  1. ∂z2/∂h=W2\partial z_2/\partial h = W_2, k×mk \times m.z2=W2h+b2z_2 = W_2 h + b_2 is affine in hh (the Jacobians page, Problem 2).
  2. ∇hL=(∂z2/∂h)⊤∇z2L\nabla_h L = (\partial z_2/\partial h)^\top \nabla_{z_2} L.LL depends on hh only through z2z_2, so the chain rule for gradients applies.
  3. ∇hL=W2⊤δ2\nabla_h L = W_2^\top \delta_2Shapes (m×k)(k×1)=m×1(m \times k)(k \times 1) = m \times 1, the shape of hh. Entry jj is ∑iW2,ij δ2,i\sum_i W_{2,ij}\,\delta_{2,i}: hidden unit jj collects the output deltas weighted by its outgoing weights, column jj of W2W_2.

Problem 5

Compute δ1=∇z1L\delta_1 = \nabla_{z_1} L in terms of δ2\delta_2, W2W_2 and z1z_1, without forming any Jacobian of σ\sigma.

  1. ∂h/∂z1=diag⁡(σ′(z1))\partial h/\partial z_1 = \operatorname{diag}(\sigma'(z_1)), m×mm \times m.h=σ(z1)h = \sigma(z_1) is elementwise (the Jacobians page, Problem 1).
  2. δ1=(∂h/∂z1)⊤∇hL=diag⁡(σ′(z1)) W2⊤δ2\delta_1 = (\partial h/\partial z_1)^\top \nabla_h L = \operatorname{diag}(\sigma'(z_1))\,W_2^\top\delta_2.LL depends on z1z_1 only through hh; a diagonal matrix is its own transpose; ∇hL\nabla_h L is Problem 4.
  3. diag⁡(σ′(z1)) v=σ′(z1)⊙v\operatorname{diag}(\sigma'(z_1))\,v = \sigma'(z_1) \odot v for any v∈Rmv \in \mathbb{R}^m.A diagonal matrix acting on a vector scales entry ii by diagonal entry ii: the vector-Jacobian product of the Jacobians page, Problem 6, so the m×mm \times m matrix is never built.
  4. δ1=σ′(z1)⊙(W2⊤δ2)\delta_1 = \sigma'(z_1)\odot(W_2^\top\delta_2)(m×1)⊙(m×1)=m×1(m \times 1) \odot (m \times 1) = m \times 1, the shape of z1z_1. For the sigmoid, σ′(z1)=h⊙(1−h)\sigma'(z_1) = h \odot (1 - h), computed from the hh saved in the forward pass.

Problem 6

Compute ∇W1L\nabla_{W_1} L and ∇b1L\nabla_{b_1} L.

  1. z1=W1x+b1z_1 = W_1 x + b_1 has the form of z2=W2h+b2z_2 = W_2 h + b_2, with xx in place of hh and δ1=∇z1L\delta_1 = \nabla_{z_1} L in place of δ2\delta_2.Problem 3 used only that form and the gradient at its output, so its argument applies unchanged.
  2. ∂L/∂W1,ij=δ1,i xj\partial L/\partial W_{1,ij} = \delta_{1,i}\, x_j and ∂L/∂b1,i=δ1,i\partial L/\partial b_{1,i} = \delta_{1,i}.W1,ijW_{1,ij} appears only in z1,iz_{1,i}, with coefficient xjx_j, and b1,ib_{1,i} only in z1,iz_{1,i}, with coefficient 11 (Problem 3, steps 2 to 5).
  3. ∇W1L=δ1x⊤\nabla_{W_1} L = \delta_1 x^\top (m×dm\times d); ∇b1L=δ1\nabla_{b_1} L = \delta_1(m×1)(1×d)=m×d(m \times 1)(1 \times d) = m \times d and mm, the shapes of W1W_1 and b1b_1 from Problem 1.

Problem 7

Compute ∇xL\nabla_x L. Why would you want it?

  1. ∂z1/∂x=W1\partial z_1/\partial x = W_1, m×dm \times d.z1=W1x+b1z_1 = W_1 x + b_1 is affine in xx.
  2. ∇xL=(∂z1/∂x)⊤δ1=W1⊤δ1\nabla_x L = (\partial z_1/\partial x)^\top \delta_1 = W_1^\top\delta_1, with shapes (d×m)(m×1)=d×1(d \times m)(m \times 1) = d \times 1.LL depends on xx only through z1z_1; the result has the shape of xx.
  3. No parameter update uses it.xx is data, not a parameter, so gradient descent never changes it.
  4. ∇xL=W1⊤δ1\nabla_x L = W_1^\top\delta_1You want it for three things. Adversarial examples: a small step along sign⁡(∇xL)\operatorname{sign}(\nabla_x L) raises the loss the most, to first order, among changes of the same maximum entry size. Saliency: the size of entry jj says how sensitive the loss is to input feature jj. And if xx is itself the output of a layer below, ∇xL\nabla_x L is that layer's incoming gradient, from which it gets its own δ0\delta_0 exactly as Problem 5 got δ1\delta_1 from W2⊤δ2W_2^\top\delta_2.

Problem 8

Batched: with X∈RN×dX \in \mathbb{R}^{N\times d} (rows are examples), Z1=XW1⊤+1b1⊤Z_1 = XW_1^\top + \mathbf{1}b_1^\top, H=σ(Z1)H = \sigma(Z_1), Z2=HW2⊤+1b2⊤Z_2 = HW_2^\top + \mathbf{1}b_2^\top, Y^=softmax⁡(Z2)\hat Y = \operatorname{softmax}(Z_2) row-wise, YY one-hot rows and L=1N∑nLnL = \tfrac1N\sum_n L_n, compute Δ2\Delta_2, ∇W2L\nabla_{W_2} L, ∇b2L\nabla_{b_2} L, Δ1\Delta_1, ∇W1L\nabla_{W_1} L, ∇b1L\nabla_{b_1} L and ∇XL\nabla_X L, with shapes.

Write x(n)x^{(n)} for example nn as a column, so row nn of XX is x(n)⊤x^{(n)\top}, and likewise h(n)h^{(n)}, y^(n)\hat y^{(n)}, y(n)y^{(n)}, and δ2(n)=y^(n)−y(n)\delta_2^{(n)} = \hat y^{(n)} - y^{(n)}, δ1(n)\delta_1^{(n)} for the single-example deltas of Problems 2 and 5.

  1. Row nn of Z1Z_1 is x(n)⊤W1⊤+b1⊤=(W1x(n)+b1)⊤x^{(n)\top} W_1^\top + b_1^\top = (W_1 x^{(n)} + b_1)^\top, and likewise down the network.Row nn of XW1⊤XW_1^\top is row nn of XX times W1⊤W_1^\top, and 1b1⊤\mathbf{1}b_1^\top adds b1⊤b_1^\top to every row. So the batch is NN copies of the single-example network, one per row, sharing the parameters.
  2. LnL_n depends only on row nn of XX, Z1Z_1, HH, Z2Z_2 and Y^\hat Y, so row nn of Δ2\Delta_2 is 1N δ2(n)⊤\tfrac1N\,\delta_2^{(n)\top}.Only the nn-th term of the mean contains row nn of Z2Z_2, and it carries the factor 1N\tfrac1N; the rest is Problem 2 for example nn (the softmax page, Problem 7).
  3. Δ2=1N(Y^−Y)\Delta_2 = \tfrac1N(\hat Y - Y), N×kN \times k.Stack the rows of step 2.
  4. ∇W2L=∑n1N δ2(n)h(n)⊤\nabla_{W_2} L = \sum_n \tfrac1N\,\delta_2^{(n)} h^{(n)\top}.W2W_2 is used by every row, so the loss reaches it through all NN copies and its gradient is the sum of their contributions; each is Problem 3 for example nn, scaled by 1N\tfrac1N.
  5. For matrices AA and BB with rows a(n)⊤a^{(n)\top} and b(n)⊤b^{(n)\top}, ∑na(n)b(n)⊤=A⊤B\sum_n a^{(n)} b^{(n)\top} = A^\top B.(A⊤B)ij=∑nAniBnj=∑nai(n)bj(n)(A^\top B)_{ij} = \sum_n A_{ni} B_{nj} = \sum_n a^{(n)}_i b^{(n)}_j, the (i,j)(i,j) entry of the sum of outer products.
  6. ∇W2L=Δ2⊤H\nabla_{W_2} L = \Delta_2^\top H, with shapes (k×N)(N×m)=k×m(k \times N)(N \times m) = k \times m.Step 5 with A=Δ2A = \Delta_2, whose rows are 1Nδ2(n)⊤\tfrac1N\delta_2^{(n)\top}, and B=HB = H. The shape is that of W2W_2.
  7. ∇b2L=∑n1N δ2(n)=Δ2⊤1\nabla_{b_2} L = \sum_n \tfrac1N\,\delta_2^{(n)} = \Delta_2^\top\mathbf{1}, with shapes (k×N)(N×1)=k×1(k \times N)(N \times 1) = k \times 1.b2b_2 is added to every row, so its gradient is the sum over rows of Problem 3's δ2\delta_2; Δ2⊤1\Delta_2^\top\mathbf{1} sums the rows of Δ2\Delta_2.
  8. ∇HL=Δ2W2\nabla_H L = \Delta_2 W_2, with shapes (N×k)(k×m)=N×m(N \times k)(k \times m) = N \times m.Row nn is Problem 4 for example nn, transposed: (W2⊤ 1Nδ2(n))⊤=1Nδ2(n)⊤W2(W_2^\top\,\tfrac1N\delta_2^{(n)})^\top = \tfrac1N\delta_2^{(n)\top} W_2.
  9. Δ1=σ′(Z1)⊙(Δ2W2)\Delta_1 = \sigma'(Z_1) \odot (\Delta_2 W_2), N×mN \times m, with σ′\sigma' applied to every entry of Z1Z_1.Problem 5 row by row: an elementwise product is taken entry by entry, so it does not care whether the entries are laid out as columns or rows. Row nn is 1Nδ1(n)⊤\tfrac1N\delta_1^{(n)\top}, Problem 5 for example nn.
  10. ∇W1L=Δ1⊤X\nabla_{W_1} L = \Delta_1^\top X, (m×N)(N×d)=m×d(m \times N)(N \times d) = m \times d; ∇b1L=Δ1⊤1\nabla_{b_1} L = \Delta_1^\top\mathbf{1}, (m×N)(N×1)=m×1(m \times N)(N \times 1) = m \times 1.Steps 4 to 7 one layer down, with Δ1\Delta_1 in place of Δ2\Delta_2 and XX in place of HH.
  11. ∇XL=Δ1W1\nabla_X L = \Delta_1 W_1, (N×m)(m×d)=N×d(N \times m)(m \times d) = N \times d.Step 8 one layer down: row nn is 1N(W1⊤δ1(n))⊤\tfrac1N(W_1^\top\delta_1^{(n)})^\top, Problem 7 for example nn scaled by 1N\tfrac1N.
  12. Δ2=1N(Y^−Y)\Delta_2 = \tfrac1N(\hat Y - Y) (N×kN\times k); ∇W2L=Δ2⊤H\nabla_{W_2}L = \Delta_2^\top H (k×mk\times m); ∇b2L=Δ2⊤1\nabla_{b_2}L = \Delta_2^\top\mathbf{1}; Δ1=σ′(Z1)⊙(Δ2W2)\Delta_1 = \sigma'(Z_1)\odot(\Delta_2 W_2) (N×mN\times m); ∇W1L=Δ1⊤X\nabla_{W_1}L = \Delta_1^\top X; ∇b1L=Δ1⊤1\nabla_{b_1}L = \Delta_1^\top\mathbf{1}; ∇XL=Δ1W1\nabla_X L = \Delta_1 W_1 (N×dN\times d)Every gradient has the shape of its variable. The 1N\tfrac1N enters once, in Δ2\Delta_2, and everything after it is linear in Δ2\Delta_2, so it is carried through and never applied again.

Problem 9

Replace σ\sigma by ReLU⁡(z)=max⁡(z,0)\operatorname{ReLU}(z) = \max(z, 0). What changes in Problems 5–7? Write δ1\delta_1 and ∇xL\nabla_x L.

  1. ReLU⁡′(t)=1\operatorname{ReLU}'(t) = 1 for t>0t > 0 and 00 for t<0t < 0; write [z1>0][z_1 > 0] for the vector whose entry ii is 11 if z1,i>0z_{1,i} > 0 and 00 otherwise.ReLU is tt to the right of 00 and 00 to the left. At t=0t = 0 the one-sided slopes are 00 and 11, so the derivative is undefined; it is taken as 00, and a pre-activation exactly at 00 is rare with real-valued data.
  2. δ2\delta_2, ∇W2L\nabla_{W_2} L, ∇b2L\nabla_{b_2} L and ∇hL\nabla_h L keep their formulas, with h=ReLU⁡(z1)h = \operatorname{ReLU}(z_1).Problems 2 to 4 used hh only as a vector feeding z2z_2; none of them differentiated the activation. The values change, the formulas do not.
  3. δ1=ReLU⁡′(z1)⊙(W2⊤δ2)\delta_1 = \operatorname{ReLU}'(z_1) \odot (W_2^\top\delta_2).Problem 5 used only that the activation is elementwise, so its derivative σ′(z1)\sigma'(z_1) is replaced by ReLU⁡′(z1)\operatorname{ReLU}'(z_1), which is [z1>0][z_1 > 0] by step 1.
  4. ∇W1L=δ1x⊤\nabla_{W_1} L = \delta_1 x^\top, ∇b1L=δ1\nabla_{b_1} L = \delta_1, ∇xL=W1⊤δ1\nabla_x L = W_1^\top\delta_1.Problems 6 and 7 start from δ1\delta_1 and never look at the activation; the new δ1\delta_1 flows into them.
  5. δ1=[z1>0]⊙(W2⊤δ2)\delta_1 = [z_1 > 0]\odot(W_2^\top\delta_2); ∇xL=W1⊤δ1\nabla_x L = W_1^\top\delta_1; nothing else changesOnly the elementwise factor in Problem 5 changes. A hidden unit with z1,i≤0z_{1,i} \le 0 passes back nothing: entry ii of δ1\delta_1 is 00, so row ii of ∇W1L\nabla_{W_1} L and entry ii of ∇b1L\nabla_{b_1} L are zero for this example. A unit that is negative on every input never updates, which is a dead ReLU.

Problem 10

Add an L2 penalty: L′=L+λ2∥W2∥F2L' = L + \tfrac{\lambda}{2}\|W_2\|_F^2. Compute ∇W2L′\nabla_{W_2} L'.

  1. λ2∥W2∥F2=λ2∑i,jW2,ij2\tfrac\lambda2\|W_2\|_F^2 = \tfrac\lambda2\sum_{i,j} W_{2,ij}^2.The squared Frobenius norm is the sum of the squares of the entries.
  2. ∂(λ2∥W2∥F2)/∂W2,ij=λW2,ij\partial\big(\tfrac\lambda2\|W_2\|_F^2\big)/\partial W_{2,ij} = \lambda W_{2,ij}, so the penalty's gradient is λW2\lambda W_2, k×mk \times m.Only one term of the sum contains W2,ijW_{2,ij}, and λ2t2\tfrac\lambda2 t^2 has derivative λt\lambda t. This is the matrix-calculus page's ∇X∥X∥F2=2X\nabla_X\|X\|_F^2 = 2X, times λ2\tfrac\lambda2.
  3. ∇W2L=δ2h⊤\nabla_{W_2} L = \delta_2 h^\top, k×mk \times m.Problem 3; the penalty does not involve z2z_2, so δ2\delta_2 is unchanged.
  4. ∇W2L′=δ2h⊤+λW2\nabla_{W_2} L' = \delta_2 h^\top + \lambda W_2The gradient of a sum is the sum of the gradients, and both terms are k×mk \times m. A gradient step becomes W2←(1−ηλ)W2−η δ2h⊤W_2 \leftarrow (1 - \eta\lambda)W_2 - \eta\,\delta_2 h^\top: the update shrinks the weights by 1−ηλ1 - \eta\lambda and adds the data term, which is why this is called weight decay. The other gradients are unchanged, because the penalty contains only W2W_2.

Where this goes wrong

1. Outer product the wrong way round

The weight gradient is built from two column vectors, δ2\delta_2 and hh, and a product of two columns needs one of them transposed.

  1. ∇W2L\nabla_{W_2} L is an outer product of δ2\delta_2 (k×1k \times 1) and hh (m×1m \times 1)Right so far: Problem 3, step 3 gives ∂L/∂W2,ij=δ2,i hj\partial L/\partial W_{2,ij} = \delta_{2,i}\,h_j.
  2. “hh goes into the layer and δ2\delta_2 comes back out of it, so hh comes first.”The analogy that causes the mistake: writing the factors in the order the data flows, input then output, as if the gradient were read along the forward pass.
  3. ∇W2L=h δ2⊤\nabla_{W_2} L = h\,\delta_2^\topIt is m×km \times k, the transpose of W2W_2's shape, so W2−η h δ2⊤W_2 - \eta\, h\,\delta_2^\top is undefined unless m=km = k, and wrong even then. The index form fixes which index is which: in δ2,i hj\delta_{2,i}\,h_j the row index ii is the output unit and belongs to δ2\delta_2, and the column index jj is the input unit and belongs to hh, so the gradient is δ2h⊤\delta_2 h^\top.

2. Passing the delta through the activation unchanged

Backprop is often summarised as “multiply the delta by the transposed weights and pass it down”, and the summary leaves out half of each layer.

  1. ∇hL=W2⊤δ2\nabla_h L = W_2^\top\delta_2Right so far: Problem 4.
  2. “The delta goes back through the transposed weights, so the hidden layer's delta is W2⊤δ2W_2^\top\delta_2.”The analogy that causes the mistake: the rule for a linear layer, applied to a layer that also has a nonlinearity, so that hh and z1z_1 are treated as the same vector.
  3. δ1=W2⊤δ2\delta_1 = W_2^\top\delta_2That is ∇hL\nabla_h L, not ∇z1L\nabla_{z_1} L. The chain rule through h=σ(z1)h = \sigma(z_1) contributes σ′(z1)\sigma'(z_1) elementwise; dropping it is right only for an identity activation. For the sigmoid σ′≤14\sigma' \le \tfrac14, so every nonzero entry comes out at least 4 times too large, and a saturated unit, whose true delta is near 00, keeps receiving a full-sized one.

3. Batched weight gradient with the data matrix on the wrong side

Linear regression's gradient, X⊤(Xw−y)X^\top(Xw - y), puts the transposed data matrix on the left, and the batched backward pass looks like the same kind of product.

  1. ∇W2L=∑n1N δ2(n)h(n)⊤\nabla_{W_2} L = \sum_n \tfrac1N\,\delta_2^{(n)} h^{(n)\top}, summed over the batchRight so far: Problem 8, step 4.
  2. “A sum over examples is a product with the transposed data matrix on the left, as in X⊤(Xw−y)X^\top(Xw - y).”The analogy that causes the mistake: in linear regression the weights are a column vector, so the data matrix goes on the left; here the weights are a k×mk \times m matrix and the order is fixed by W2W_2's shape.
  3. ∇W2L=H⊤Δ2\nabla_{W_2} L = H^\top\Delta_2It is (m×N)(N×k)=m×k(m \times N)(N \times k) = m \times k. With rows as examples the gradient is Δ2⊤H\Delta_2^\top H, k×mk \times m. The entries are the same numbers transposed, (H⊤Δ2)⊤=Δ2⊤H(H^\top\Delta_2)^\top = \Delta_2^\top H, which is why it “looks right” until the update fails to broadcast; when m=km = k the update runs and silently applies the transpose.

4. Bias gradient that is still a matrix

For one example the bias gradient is the delta itself, ∇b2L=δ2\nabla_{b_2} L = \delta_2, and in the batch the delta is a matrix.

  1. Δ2=1N(Y^−Y)\Delta_2 = \tfrac1N(\hat Y - Y), N×kN \times kRight so far: Problem 8, step 3.
  2. “The bias gradient equals the delta, as in Problem 3.”The analogy that causes the mistake: a single-example identity carried to the batch without asking how the bias enters. 1b2⊤\mathbf{1}b_2^\top copies one bias into every row.
  3. ∇b2L=Δ2\nabla_{b_2} L = \Delta_2It is N×kN \times k, and b2b_2 has kk entries. The bias is shared across the batch, so its gradient sums the rows: Δ2⊤1\Delta_2^\top\mathbf{1}. In array code b2−η Δ2b_2 - \eta\,\Delta_2 may broadcast without complaint and turn the bias into an N×kN \times k matrix, one bias per example.

5. Doubling the weight-decay gradient

The matrix-calculus page's ∇X∥X∥F2=2X\nabla_X\|X\|_F^2 = 2X is short enough to memorise, and the 2 in it is easy to carry across without the 12\tfrac12 it is meant to meet.

  1. L′=L+λ2∥W2∥F2L' = L + \tfrac\lambda2\|W_2\|_F^2, and ∇X∥X∥F2=2X\nabla_X\|X\|_F^2 = 2XRight so far: both are true.
  2. “The gradient of a squared Frobenius norm is twice the matrix, so the penalty contributes 2λW22\lambda W_2.”The analogy that causes the mistake: ∇∥X∥F2=2X\nabla\|X\|_F^2 = 2X applied to λ∥W2∥F2\lambda\|W_2\|_F^2 instead of λ2∥W2∥F2\tfrac\lambda2\|W_2\|_F^2, as if the prefactor were λ\lambda.
  3. ∇W2λ2∥W2∥F2=2λW2\nabla_{W_2}\tfrac\lambda2\|W_2\|_F^2 = 2\lambda W_2The 12\tfrac12 is there to cancel the 2: λ2⋅2W2=λW2\tfrac\lambda2 \cdot 2W_2 = \lambda W_2 (Problem 10). The slip survives because training still works: the model is simply regularised as if λ\lambda were twice what was set, so a λ\lambda tuned with this code must be doubled in any correct implementation.

Print this set: one-hidden-layer-backprop.pdf (problems, answers, and worked solutions on separate pages).