Md. Asif Uddin
    Problem I.6.B02

    Deriving the layer recurrence from the graph

    symbolic▲▲△

    Symbolic throughout; no numbers.

    STATEMENT

    Derive the two equations every implementation of backpropagation contains — the recurrence that carries an adjoint from one layer to the previous one, and the outer product that turns an adjoint into a weight gradient — from the graph rule (I.6.2) alone. Nothing else may be assumed.

    GIVEN

    One layer of an MLP, written as three nodes so that each has a Jacobian that can be stated:

    z(ℓ)=a(ℓ−1)W(ℓ)+b(ℓ),a(ℓ)=φ(z(ℓ))\vec{z}^{(\ell)} = \vec{a}^{(\ell-1)}\mat{W}^{(\ell)} + \vec{b}^{(\ell)}, \qquad \vec{a}^{(\ell)} = \varphi(\vec{z}^{(\ell)})

    with a(ℓ−1)∈R1×dℓ−1\vec{a}^{(\ell-1)} \in \R^{1 \times d_{\ell-1}}, W(ℓ)∈Rdℓ−1×dℓ\mat{W}^{(\ell)} \in \R^{d_{\ell-1} \times d_\ell} and φ\varphi applied elementwise. A scalar loss LL sits at the sink. Write δ(ℓ)=∂L/∂z(ℓ)\delta^{(\ell)} = \partial L / \partial \vec{z}^{(\ell)}.

    FIND

    Expressions for ∂L/∂W(ℓ)\partial L/\partial \mat{W}^{(\ell)}, ∂L/∂b(ℓ)\partial L/\partial \vec{b}^{(\ell)} and δ(ℓ−1)\delta^{(\ell-1)} in terms of δ(ℓ)\delta^{(\ell)} and quantities the forward pass already stored.

    STRATEGY

    Work one node at a time and never write down a full Jacobian. Each step asks the same question: given the adjoint of this node’s output, what is the adjoint of its input? That is the vector–Jacobian product of Definition 7, and for these three operations it has a closed form in each case.

    SOLUTION

    Step 1 — through the nonlinearity. φ\varphi acts elementwise, so ∂aj(ℓ)/∂zi(ℓ)\partial a^{(\ell)}_j / \partial z^{(\ell)}_i is zero unless i=ji = j. The Jacobian is diagonal, and multiplying by a diagonal matrix is multiplying elementwise:

    δ(ℓ)=∂L∂z(ℓ)=∂L∂a(ℓ)⊙φ′(z(ℓ))\delta^{(\ell)} = \frac{\partial L}{\partial \vec{z}^{(\ell)}} = \frac{\partial L}{\partial \vec{a}^{(\ell)}} \odot \varphi'(\vec{z}^{(\ell)})

    This is the first place the forward pass is consumed: φ′\varphi' is evaluated at the stored z(ℓ)\vec{z}^{(\ell)}, and without it there is nothing to multiply.

    Step 2 — the bias. In z=aW+b\vec{z} = \vec{a}\mat{W} + \vec{b} the bias enters with coefficient one, so ∂zj/∂bi=δij\partial z_j / \partial b_i = \delta_{ij} and the local Jacobian is the identity. By (I.6.2) the adjoint passes through unchanged:

    ∂L∂b(ℓ)=δ(ℓ)\frac{\partial L}{\partial \vec{b}^{(\ell)}} = \delta^{(\ell)}

    Step 3 — the weights. Take one entry. Only the jj-th output involves WijW_{ij}, and it involves it linearly with coefficient ai(ℓ−1)a^{(\ell-1)}_i:

    ∂zk(ℓ)∂Wij(ℓ)={ai(ℓ−1)k=j0k≠j\frac{\partial z^{(\ell)}_k}{\partial W^{(\ell)}_{ij}} = \begin{cases} a^{(\ell-1)}_i & k = j \\ 0 & k \neq j \end{cases}

    So the sum over consumers in (I.6.2) collapses to a single term:

    ∂L∂Wij(ℓ)=∑kδk(ℓ)∂zk(ℓ)∂Wij(ℓ)=ai(ℓ−1)δj(ℓ)\frac{\partial L}{\partial W^{(\ell)}_{ij}} = \sum_k \delta^{(\ell)}_k \frac{\partial z^{(\ell)}_k}{\partial W^{(\ell)}_{ij}} = a^{(\ell-1)}_i \delta^{(\ell)}_j

    Every entry is a product of one input coordinate and one output adjoint, which is exactly an outer product:

    ∂L∂W(ℓ)=(a(ℓ−1))Tδ(ℓ)\frac{\partial L}{\partial \mat{W}^{(\ell)}} = (\vec{a}^{(\ell-1)})^{\mathsf{T}} \delta^{(\ell)}

    The shapes confirm it: (dℓ−1×1)(1×dℓ)(d_{\ell-1} \times 1)(1 \times d_\ell) gives dℓ−1×dℓd_{\ell-1} \times d_\ell, the shape of W(ℓ)\mat{W}^{(\ell)}. A gradient always has the shape of the thing it differentiates.

    Step 4 — back to the previous layer. Now differentiate with respect to the input rather than the parameters. Coordinate ai(ℓ−1)a^{(\ell-1)}_i feeds every output zj(ℓ)z^{(\ell)}_j, so this time the sum does not collapse:

    ∂L∂ai(ℓ−1)=∑jδj(ℓ)∂zj(ℓ)∂ai(ℓ−1)=∑jδj(ℓ)Wij(ℓ)\frac{\partial L}{\partial a^{(\ell-1)}_i} = \sum_j \delta^{(\ell)}_j \frac{\partial z^{(\ell)}_j}{\partial a^{(\ell-1)}_i} = \sum_j \delta^{(\ell)}_j W^{(\ell)}_{ij}

    which is the ii-th entry of δ(ℓ)(W(ℓ))T\delta^{(\ell)}(\mat{W}^{(\ell)})^{\mathsf{T}}:

    ∂L∂a(ℓ−1)=δ(ℓ)(W(ℓ))T\frac{\partial L}{\partial \vec{a}^{(\ell-1)}} = \delta^{(\ell)}(\mat{W}^{(\ell)})^{\mathsf{T}}

    The transpose is not a convention. Forwards, W\mat{W} maps dℓ−1d_{\ell-1} coordinates to dℓd_\ell; backwards, the adjoint must travel from dℓd_\ell back to dℓ−1d_{\ell-1}, and the only way to do that with the same matrix is to use it the other way round.

    Step 5 — combine. Applying Step 1 at layer ℓ−1\ell - 1 to the result of Step 4 gives the recurrence:

    δ(ℓ−1)=(δ(ℓ)(W(ℓ))T)⊙φ′(z(ℓ−1))\delta^{(\ell-1)} = \left(\delta^{(\ell)}(\mat{W}^{(\ell)})^{\mathsf{T}}\right) \odot \varphi'(\vec{z}^{(\ell-1)})

    which is (I.6.3), and Steps 2 and 3 are (I.6.4). Both came from (I.6.2) and three local Jacobians, and no Jacobian was ever written out in full.

    Answer

    ∂L∂W(ℓ)=(a(ℓ−1))Tδ(ℓ),∂L∂b(ℓ)=δ(ℓ)\frac{\partial L}{\partial \mat{W}^{(\ell)}} = (\vec{a}^{(\ell-1)})^{\mathsf{T}} \delta^{(\ell)}, \qquad \frac{\partial L}{\partial \vec{b}^{(\ell)}} = \delta^{(\ell)}δ(ℓ−1)=(δ(ℓ)(W(ℓ))T)⊙φ′(z(ℓ−1))\delta^{(\ell-1)} = \left(\delta^{(\ell)}(\mat{W}^{(\ell)})^{\mathsf{T}}\right) \odot \varphi'(\vec{z}^{(\ell-1)})

    Check — sanity

    Every gradient has the shape of its parameter. (dℓ−1×1)(1×dℓ)=dℓ−1×dℓ(d_{\ell-1} \times 1)(1 \times d_\ell) = d_{\ell-1} \times d_\ell for the weights, and δ(ℓ)\delta^{(\ell)} is 1×dℓ1 \times d_\ell for the bias. This is the cheapest check there is and it catches a transposed derivation immediately.

    The recurrence terminates. δ(L)\delta^{(L)} comes from the loss, and each application of the recurrence produces δ\delta one layer earlier, so LL steps reach the input. Nothing in the derivation refers to a layer that has not been reached, which is what makes reverse topological order the right traversal.

    Only stored quantities appear. a(ℓ−1)\vec{a}^{(\ell-1)}, z(ℓ−1)\vec{z}^{(\ell-1)} and W(ℓ)\mat{W}^{(\ell)} — all present after the forward pass. No re-evaluation of φ\varphi or of any matrix product is required, which is why the backward pass costs about what the forward pass cost rather than twice it.

    Where this breaks

    The derivation assumes φ\varphi is elementwise, which is what makes its Jacobian diagonal and its VJP a Hadamard product. Softmax is not elementwise: its Jacobian is diag(p)−pTp\mathrm{diag}(\vec{p}) - \vec{p}^{\mathsf{T}}\vec{p}, dense and of size d×dd \times d, and Step 1 does not apply to it. Every layer that mixes coordinates — softmax, normalisation over a feature dimension, attention — needs its own VJP derived separately, and treating one of them as elementwise produces a gradient that is wrong in a way no shape check detects, because the shapes are unchanged.

    It also assumes each of a(ℓ−1)\vec{a}^{(\ell-1)}, W(ℓ)\mat{W}^{(\ell)} and b(ℓ)\vec{b}^{(\ell)} has exactly one consumer. Tie a weight across two layers and Step 3 acquires a second term, by (I.6.2); I.6.X04 is that case, and the failure of forgetting it is not subtle.

    Variation

    Redo Steps 3 and 4 for a batch of BB examples, where A(ℓ−1)∈RB×dℓ−1\mat{A}^{(\ell-1)} \in \R^{B \times d_{\ell-1}} and Δ(ℓ)∈RB×dℓ\Delta^{(\ell)} \in \R^{B \times d_\ell}. One of the two results acquires a sum over the batch and the other does not. Which, and why?

    Draws on