Backpropagation › Jacobian Matrices and Gradient Flow

Michael BrenndoerferMay 6, 20254 min read
Language AI HandbookAll chapters
Part 10 of 67Neural Network Foundations
Chapter 65Backpropagation › Jacobian Matrices and Gradient Flow
Reading section 5 of 20 · Jacobian Matrices and Gradient Flow · 4 minSection 5 of 20 · 4 min

Book contents

Section 5 of 20 · 4 min read

Backpropagation › Jacobian Matrices and Gradient FlowOne section · Sections in this chapter5 / 20 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Before diving into the full backward pass, it's worth understanding Jacobian matrices carefully, because they formalize how gradients flow through vector-valued operations.

Jacobian Matrix

For a function f:Rn→Rm\mathbf{f}: \mathbb{R}^n \to \mathbb{R}^m, the Jacobian is the m×nm \times n matrix of all partial derivatives:

J=(∂f1∂x1⋯∂f1∂xn⋮⋱⋮∂fm∂x1⋯∂fm∂xn)\mathbf{J} = \begin{pmatrix} \frac{\partial f_1}{\partial x_1} & \cdots & \frac{\partial f_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac{\partial f_m}{\partial x_1} & \cdots & \frac{\partial f_m}{\partial x_n} \end{pmatrix}

Entry JijJ_{ij} tells us how much the ii-th output changes when we perturb the jj-th input.

In neural network backpropagation, the loss L\mathcal{L} is a scalar, and each operation in the network transforms a vector to another vector. At each node, we don't technically need the full Jacobian. We only need the vector-Jacobian product (VJP), which maps the upstream gradient vector to a downstream gradient vector.

To see why the full Jacobian is unnecessary, consider a layer that maps R512→R512\mathbb{R}^{512} \to \mathbb{R}^{512}. The full Jacobian would be a 512×512512 \times 512 matrix of 262,144 entries. But we only need to propagate a gradient vector of length 512 backward. The VJP computes this directly in O(5122)O(512^2) time, the same cost as forming the Jacobian, but without ever explicitly materializing it. For larger layers, the savings are more dramatic, and specialized operations like batch normalization have structured Jacobians that admit even faster VJP computations.

Vector-Jacobian Products (VJPs)

In practice, backpropagation never explicitly forms full Jacobian matrices. Instead, it computes vector-Jacobian products. If the upstream gradient is a row vector vT\mathbf{v}^T (with the same shape as the output), the downstream gradient is:

vT⋅J\mathbf{v}^T \cdot \mathbf{J}

This produces a row vector with the same shape as the input. The key insight is that computing this product is much cheaper than computing J\mathbf{J} explicitly, then multiplying. PyTorch's autograd system is built entirely around this VJP abstraction.

This VJP perspective also clarifies what backpropagation is computing at each step. The upstream gradient v\mathbf{v} represents "how the loss changes when the output of this node changes." The Jacobian J\mathbf{J} represents "how the output of this node changes when the input changes." Their product gives "how the loss changes when the input changes," which is exactly the downstream gradient we need to propagate.

Local Gradients for Common Operations

The power of computational graphs is that each operation only needs to define its own local Jacobian (or VJP). The full gradient is then assembled by chaining these local gradients via the multivariate chain rule.

Here are the local gradients for the key operations in a neural network:

Addition: z=x+y\mathbf{z} = \mathbf{x} + \mathbf{y}. The Jacobian with respect to each input is the identity matrix I\mathbf{I}. Gradients pass through unchanged: ∂L∂x=∂L∂z\frac{\partial \mathcal{L}}{\partial \mathbf{x}} = \frac{\partial \mathcal{L}}{\partial \mathbf{z}} and ∂L∂y=∂L∂z\frac{\partial \mathcal{L}}{\partial \mathbf{y}} = \frac{\partial \mathcal{L}}{\partial \mathbf{z}}. This is why residual connections are so effective: the skip path provides a direct gradient highway back to earlier layers. The gradient flows through without any attenuation from the addition node itself.

Multiplication by scalar ww: z=w⋅x\mathbf{z} = w \cdot \mathbf{x}. The gradient with respect to x\mathbf{x} is w⋅∂L∂zw \cdot \frac{\partial \mathcal{L}}{\partial \mathbf{z}} (scale up or down), and the gradient with respect to ww is xT∂L∂z\mathbf{x}^T \frac{\partial \mathcal{L}}{\partial \mathbf{z}}.

Matrix multiplication: z=Wx\mathbf{z} = \mathbf{W}\mathbf{x}. The Jacobian with respect to x\mathbf{x} is WT\mathbf{W}^T, giving ∂L∂x=WT∂L∂z\frac{\partial \mathcal{L}}{\partial \mathbf{x}} = \mathbf{W}^T \frac{\partial \mathcal{L}}{\partial \mathbf{z}}. The gradient with respect to W\mathbf{W} is the outer product ∂L∂zxT\frac{\partial \mathcal{L}}{\partial \mathbf{z}} \mathbf{x}^T. Notice the transpose: gradients flow backward through the weight matrix transposed, which is why the backward pass through a linear layer involves WT\mathbf{W}^T while the forward pass involves W\mathbf{W}.

Elementwise nonlinearity: a=σ(z)\mathbf{a} = \sigma(\mathbf{z}). The Jacobian is a diagonal matrix with σ′(zi)\sigma'(z_i) on the diagonal, so ∂L∂z=∂L∂a⊙σ′(z)\frac{\partial \mathcal{L}}{\partial \mathbf{z}} = \frac{\partial \mathcal{L}}{\partial \mathbf{a}} \odot \sigma'(\mathbf{z}), where ⊙\odot denotes elementwise multiplication. Because the Jacobian is diagonal, we never form a full matrix; we just do an elementwise multiply.