1. Convention: numerator vs. denominator
Before any derivative, fix the convention. For f:Rn→Rm given by y=f(x), numerator layout declares
∂x∂y∈Rm×n,(∂x∂y)ij=∂xj∂yi.
Denominator layout flips it: ∂y/∂x∈Rn×m. I pick numerator because it makes the chain
rule stack matrices in the natural multiplication order. Every
derivation in this course uses numerator layout. Mix them and you
suffer.[1]
2. Derivative of Wx+b with respect to x
Let f(x)=Wx+b with W∈Rm×n, b∈Rm. Component-wise,
yi=k=1∑nWikxk+bi.
Differentiating yi with respect to xj, every term with k=j
vanishes:
∂xj∂yi=∂xj∂(k∑Wikxk+bi)=k∑Wikδkj=Wij.
Stacking over every (i,j) pair,
∂x∂(Wx+b)=W∈Rm×n.
The intuition is direct: differentiating an affine map with respect to
its input recovers its linear part.
3. Derivative with respect to W
Here W is a matrix, so ∂y/∂W is in principle a
rank-3 tensor: it has indices (i,j,k) with i ranging over y and
(j,k) ranging over W. The cleanest route is to differentiate index by
index; the storage shape will fall out at the end.
∂Wjk∂yi=∂Wjk∂(l∑Wilxl+bi)=l∑δijδlkxl=δijxk.
Note the δij: the derivative of the i-th output with respect
to the element Wjk is non-zero only when j=i. In other words,
the weight Wjk affects only the output yj.
4. Why this shows up as an outer product in backprop
At training time, what we need is not the full tensor but the gradient
of a scalar loss L with respect to W. By the chain rule:
∂Wjk∂L=i∑∂yi∂L∂Wjk∂yi=i∑∂yi∂Lδijxk=∂yj∂Lxk.
Define δ:=∂L/∂y∈Rm. In matrix
form, ∂L/∂W is the m×n matrix whose (j,k)
entry is δjxk — the outer product:
∂W∂L=δx⊤∈Rm×n.
And for the bias, ∂L/∂b=δ (each bi contributes
1 to yi). This completes the local update rule of a linear layer;
chained across all layers, it is PyTorch's backward().
5. Quick check (do it with a pen)
For W=(1324) and x=(5,6)⊤, compute y=Wx, then ∂y/∂x, and finally
— assuming L=21∥y∥2 — obtain δ and the outer
product δx⊤. If W⊤yx⊤ shows up in the slot where δx⊤
should be, the numerator convention from §1 was crossed.