Matrix Calculus
Every time a language model finishes a sentence, a self-driving car steadies its lane, or a
recommender guesses your next film, a machine somewhere has already taken billions of
derivatives to get there. Not derivatives of one variable with respect to another — derivatives
of a single number (a "loss", how wrong the model is) with respect to a whole vector
of millions of tunable weights, all at once. The bookkeeping that makes this possible, and keeps
it sane, is matrix calculus: differentiating with respect to vectors and
matrices instead of scalars.
The good news is that there is almost no new calculus here. You already know how to take a
gradient and how a
Jacobian
packages many partial derivatives into a matrix. Matrix calculus is mostly a change of
language: instead of writing out n partial-derivative
equations, you write one tidy line with vectors and matrices in it — and then you learn the
handful of identities that let you differentiate those lines by sight. Master the cheat sheet
below and you can differentiate a neural network's loss on the back of a napkin.
Three objects: gradient, Jacobian, Hessian
Everything in matrix calculus is built from three arrangements of partial derivatives. Which one
you get depends only on what goes in and what comes out.
1. The gradient — scalar out, vector in. For a scalar function
f(\mathbf{x}) of a vector
\mathbf{x} = (x_1, \dots, x_n), the derivative
\partial f / \partial \mathbf{x} is the vector that collects one
partial per input:
\frac{\partial f}{\partial \mathbf{x}} \;=\; \nabla f \;=\; \left( \frac{\partial f}{\partial x_1},\; \frac{\partial f}{\partial x_2},\; \dots,\; \frac{\partial f}{\partial x_n} \right).
Same object you already met — just written as "the derivative of a scalar with respect to a
vector". It has one number for every input direction.
2. The Jacobian — vector out, vector in. For a vector-valued function
\mathbf{f} : \mathbb{R}^n \to \mathbb{R}^m (so
m outputs, n inputs), the derivative is the
m \times n matrix whose row i is the
gradient of the i-th output:
J \;=\; \frac{\partial \mathbf{f}}{\partial \mathbf{x}} \;=\; \begin{bmatrix} \dfrac{\partial f_1}{\partial x_1} & \cdots & \dfrac{\partial f_1}{\partial x_n} \\[1.2em] \vdots & \ddots & \vdots \\[0.6em] \dfrac{\partial f_m}{\partial x_1} & \cdots & \dfrac{\partial f_m}{\partial x_n} \end{bmatrix}, \qquad J_{ij} = \frac{\partial f_i}{\partial x_j}.
Stack m gradients as rows and you have the Jacobian. A gradient is
just the special case m = 1: a Jacobian with a single row.
3. The Hessian — scalar out, differentiated twice. Take a scalar
f(\mathbf{x}) and differentiate again: the matrix of all
second partials is the Hessian, the Jacobian of the gradient,
H \;=\; \frac{\partial^2 f}{\partial \mathbf{x}\, \partial \mathbf{x}^{\!\top}}, \qquad H_{ij} = \frac{\partial^2 f}{\partial x_i\, \partial x_j}.
It measures curvature — how the gradient itself bends — and (for nice
functions) it is symmetric, because mixed partials commute:
\partial^2 f / \partial x_i \partial x_j = \partial^2 f / \partial x_j \partial x_i.
The cheat sheet every ML practitioner memorises
Once functions are written with vectors and matrices, a small set of identities lets you
differentiate them without ever peeking at individual components. Treat these like the power rule
of matrix calculus — worth knowing cold. Throughout, \mathbf{a} is a
constant vector, A a constant matrix, and
\mathbf{x} the variable vector.
-
Linear form.
\nabla_{\mathbf{x}}\,(\mathbf{a}^{\top}\mathbf{x}) = \mathbf{a}.
(The vector analogue of \tfrac{d}{dx}(ax) = a.)
-
Squared length.
\nabla_{\mathbf{x}}\,(\mathbf{x}^{\top}\mathbf{x}) = 2\mathbf{x}.
(The analogue of \tfrac{d}{dx}(x^2) = 2x.)
-
Quadratic form.
\nabla_{\mathbf{x}}\,(\mathbf{x}^{\top}\! A\,\mathbf{x}) = (A + A^{\top})\,\mathbf{x},
which is 2A\mathbf{x} only when
A is symmetric (A^{\top} = A).
-
Linear map (Jacobian). The Jacobian of
\mathbf{f}(\mathbf{x}) = A\mathbf{x} is just
A itself:
\dfrac{\partial (A\mathbf{x})}{\partial \mathbf{x}} = A.
(The analogue of \tfrac{d}{dx}(ax) = a for whole vectors.)
-
Vector chain rule. If
\mathbf{y} = \mathbf{g}(\mathbf{x}) and
\mathbf{z} = \mathbf{f}(\mathbf{y}), then the Jacobians
multiply:
\dfrac{\partial \mathbf{z}}{\partial \mathbf{x}} = \dfrac{\partial \mathbf{z}}{\partial \mathbf{y}}\,\dfrac{\partial \mathbf{y}}{\partial \mathbf{x}} = J_{\mathbf{f}}\, J_{\mathbf{g}}
— outer Jacobian times inner Jacobian, in that order.
A quick sanity check on the linear form. Write
\mathbf{a}^{\top}\mathbf{x} = a_1 x_1 + a_2 x_2 + \dots + a_n x_n.
Differentiating with respect to x_k kills every term except
a_k x_k, leaving a_k. Collect those and the
gradient is (a_1, \dots, a_n) = \mathbf{a}. Every identity above can be
checked the same way — write out one component, differentiate, and read the pattern.
The squared-length rule is worth doing by hand once, because it explains the factor of 2 and
previews the quadratic-form rule. Write
\mathbf{x}^{\top}\mathbf{x} = x_1^2 + x_2^2 + \dots + x_n^2.
Differentiating with respect to x_k gives
2 x_k (only the x_k^2 term survives).
Collecting components, \nabla(\mathbf{x}^{\top}\mathbf{x}) = 2\mathbf{x}.
And \mathbf{x}^{\top}\mathbf{x} is exactly the quadratic form
\mathbf{x}^{\top}\! A\,\mathbf{x} with
A = I (the identity, which is symmetric), so the general rule gives
(I + I^{\top})\mathbf{x} = 2I\mathbf{x} = 2\mathbf{x} — perfectly
consistent. The two identities are the same fact at two levels of generality.
Worked example 1 — the least-squares loss (where the identities pay off)
This is the calculation of classical machine learning, and it uses three of the
identities at once. We fit a linear model to data by minimising the squared error. With data
matrix A, unknown weights \mathbf{x}, and
targets \mathbf{b}, the loss is the squared length of the residual:
f(\mathbf{x}) \;=\; \lVert A\mathbf{x} - \mathbf{b} \rVert^2 \;=\; (A\mathbf{x} - \mathbf{b})^{\top}(A\mathbf{x} - \mathbf{b}).
Step 1 — expand the product. Multiply it out, remembering that transposing a
product reverses order, (A\mathbf{x})^{\top} = \mathbf{x}^{\top} A^{\top}:
f(\mathbf{x}) = \mathbf{x}^{\top} A^{\top} A\,\mathbf{x} \;-\; \mathbf{x}^{\top} A^{\top}\mathbf{b} \;-\; \mathbf{b}^{\top} A\,\mathbf{x} \;+\; \mathbf{b}^{\top}\mathbf{b}.
The two middle terms are each a single number, and a number equals its own transpose, so
\mathbf{b}^{\top} A\,\mathbf{x} = (\mathbf{b}^{\top} A\,\mathbf{x})^{\top} = \mathbf{x}^{\top} A^{\top}\mathbf{b}.
They are the same thing; combine them:
f(\mathbf{x}) = \underbrace{\mathbf{x}^{\top} (A^{\top} A)\,\mathbf{x}}_{\text{quadratic form}} \;-\; 2\underbrace{(A^{\top}\mathbf{b})^{\top}\mathbf{x}}_{\text{linear form}} \;+\; \underbrace{\mathbf{b}^{\top}\mathbf{b}}_{\text{constant}}.
Step 2 — differentiate term by term with the cheat sheet. The matrix
A^{\top} A is symmetric (indeed
(A^{\top}A)^{\top} = A^{\top} A), so the quadratic-form rule gives
2 A^{\top} A\,\mathbf{x}. The linear form
\mathbf{a}^{\top}\mathbf{x} with
\mathbf{a} = A^{\top}\mathbf{b} differentiates to
\mathbf{a}, and the constant vanishes:
\nabla f(\mathbf{x}) \;=\; 2 A^{\top} A\,\mathbf{x} \;-\; 2 A^{\top}\mathbf{b} \;=\; 2 A^{\top}(A\mathbf{x} - \mathbf{b}).
Step 3 — set the gradient to zero. The loss is a bowl (a positive quadratic),
so its one minimum is where \nabla f = \mathbf{0}:
2 A^{\top}(A\mathbf{x} - \mathbf{b}) = \mathbf{0} \quad\Longrightarrow\quad A^{\top} A\,\mathbf{x} = A^{\top}\mathbf{b}.
Those are the famous normal equations of linear regression — the closed-form
best fit — and they dropped out of three lines of matrix calculus. No summation signs, no writing
out components: the identities did the work.
Worked example 2 — a concrete quadratic form
Let us make \nabla(\mathbf{x}^{\top}\! A\,\mathbf{x}) = (A + A^{\top})\mathbf{x}
completely concrete with a small symmetric A. Take
A = \begin{bmatrix} 2 & 1 \\ 1 & 3 \end{bmatrix}, \qquad \mathbf{x} = \begin{bmatrix} x_1 \\ x_2 \end{bmatrix}.
Step 1 — write out the scalar. Multiplying
\mathbf{x}^{\top}\! A\,\mathbf{x} gives a single number:
\mathbf{x}^{\top}\! A\,\mathbf{x} = 2x_1^2 + 2x_1 x_2 + 3x_2^2.
(The cross term is 2x_1 x_2 because the off-diagonal
1 appears twice, once above and once below the diagonal.)
Step 2 — take the two partials directly.
\frac{\partial}{\partial x_1} = 4x_1 + 2x_2, \qquad \frac{\partial}{\partial x_2} = 2x_1 + 6x_2, \qquad\text{so}\quad \nabla = \begin{bmatrix} 4x_1 + 2x_2 \\ 2x_1 + 6x_2 \end{bmatrix}.
Step 3 — check against the identity. Since
A is symmetric, A + A^{\top} = 2A, so the
rule predicts
(A + A^{\top})\mathbf{x} = 2A\mathbf{x} = \begin{bmatrix} 4 & 2 \\ 2 & 6 \end{bmatrix}\begin{bmatrix} x_1 \\ x_2 \end{bmatrix} = \begin{bmatrix} 4x_1 + 2x_2 \\ 2x_1 + 6x_2 \end{bmatrix}.
Identical. And notice the Hessian here is exactly that constant matrix
2A = \begin{bmatrix} 4 & 2 \\ 2 & 6 \end{bmatrix} — for a quadratic,
the curvature is the same everywhere, which is why a quadratic bowl has one clean minimum.
Try A = \begin{bmatrix} 0 & 4 \\ 0 & 0 \end{bmatrix}. Then
\mathbf{x}^{\top}\! A\,\mathbf{x} = 4x_1 x_2, whose gradient is
(4x_2,\, 4x_1). The identity gives
(A + A^{\top})\mathbf{x} = \begin{bmatrix} 0 & 4 \\ 4 & 0 \end{bmatrix}\mathbf{x} = (4x_2,\, 4x_1)
— correct. But 2A\mathbf{x} = (8x_2,\, 0) would be
wrong. That is the whole reason the rule is written
(A + A^{\top}) and not 2A: only symmetry
makes them agree. Reassuringly, only the symmetric part of
A ever affects the quadratic form, so people often symmetrise
A first and then the tidy 2A\mathbf{x}
is safe.
Why any of this matters: gradient descent and backpropagation
Training a model is an optimisation problem: adjust the weights
\mathbf{x} to make a scalar loss
f(\mathbf{x}) as small as possible. Because
-\nabla f points in the direction of steepest descent, the recipe is
the same one line whether \mathbf{x} has two components or two billion:
\mathbf{x}_{n+1} = \mathbf{x}_n - \eta\, \nabla f(\mathbf{x}_n),
with a small step size \eta (the "learning rate"). Every training step
needs \nabla f — the gradient of a loss built from matrix and vector
expressions — so the identities on this page are precisely what makes a training step
computable. The least-squares gradient
2A^{\top}(A\mathbf{x} - \mathbf{b}) we just derived is the simplest
real example of one.
A deep network is a stack of functions, layer after layer, so its loss is a big composition
f = f_L \circ \dots \circ f_2 \circ f_1. Differentiating a composition
is the job of the vector chain rule: the overall Jacobian is the product of each
layer's Jacobian. Backpropagation is nothing more than evaluating that product
efficiently — multiplying the layer Jacobians from the output end back toward the input, reusing
work as it goes. So the entire modern edifice of deep learning rests on two things from this page:
the gradient of a scalar loss, and the chain rule for Jacobians.
The rules are short, but they are unforgiving. Three mistakes catch almost everyone at least
once:
-
Layout conventions differ — pick one and never mix. Some texts write a
gradient as a column vector ("denominator layout"), others as a row
("numerator layout"), and the two put transposes in different places, so a Jacobian in one
convention is the transpose of the Jacobian in the other. Neither is "right"; the sin is
mixing them mid-derivation. Decide up front — most ML code treats gradients as columns
matching \mathbf{x} — and stay consistent, or a stray transpose
will silently break your update.
-
\nabla(\mathbf{x}^{\top}\! A\,\mathbf{x}) = (A + A^{\top})\mathbf{x},
and it is 2A\mathbf{x} ONLY when
A is symmetric. Reaching for
2A\mathbf{x} on a non-symmetric
A is the single most common slip. When in doubt, use
(A + A^{\top}); it is always correct.
-
Chain-rule order — Jacobians multiply, and dimensions must line up. The
outer function's Jacobian goes on the left:
J_{\mathbf{f}}\, J_{\mathbf{g}}, not
J_{\mathbf{g}}\, J_{\mathbf{f}}. Matrix multiplication is not
commutative, so the wrong order isn't just a different answer — the shapes usually won't even
conform (an m \times p times a p \times n
works; reverse it and the inner dimensions clash). Let the dimensions guide you: they fit in
exactly one order.
See the gradient field of a loss
Here is the loss f(x, y) = x^2 + 2y^2 as a
contour map — the rings are its level curves, tighter where the bowl is steep.
The short arrows form the gradient field: at every point,
\nabla f = (2x,\, 4y) points in the direction of steepest
ascent, always crossing the contour at a right angle and growing longer where the walls
are steeper. Training steps the opposite way, along
-\nabla f, straight toward the minimum at the centre.
Drag the sliders to move the marked point P around and watch its
gradient arrow (the bold one) swing to point uphill. That single arrow is exactly what gradient
descent reads off before every step — flip its sign and you have the direction the optimiser
actually moves.
We stopped at gradients (scalar-by-vector) and Jacobians (vector-by-vector), and hinted at the
Hessian (a matrix of second partials). But you can keep going: the derivative of a
vector with respect to a matrix, or a matrix with respect to a matrix, is a
genuine object too — it just has more indices than fit neatly in a rectangle. The full
book-keeping lives in the world of tensors (multi-index arrays), and the
reason modern ML libraries are named "TensorFlow" and built around a "Tensor" type is precisely
this: the derivatives that training needs don't always fit into a 2-D grid.
In practice, engineers dodge most of the index gymnastics with two tools. One is a compact
differential notation (write df, read off the derivative); the other
is automatic differentiation — the computer applies the chain rule for you,
Jacobian by Jacobian, so you write only the forward computation and the gradient comes back for
free. Backpropagation is the most famous special case. The identities on this page are still
what's happening underneath — you've just delegated the arithmetic.