Guides / Matrix calculus
The softmax Jacobian: diag(s) − ssᵀ, a backward pass without the matrix, and s − y for cross-entropy
Short answer
Entries: ∂si/∂zj = si(δij − sj), which is si(1 − si) on the diagonal and −sisj off it. Matrix: J = diag(s) − ssT, symmetric, with rows and columns that sum to 0. Backward: for an incoming gradient g, JTg = s ⊙ (g − (sTg)1). With cross-entropy L = −Σ yi log si and labels that sum to 1: ∇zL = s − y. To compute s, subtract maxk zk from every score first; softmax doesn't change.
Why it works
Write Σ = Σk ezk, so si = ezi/Σ. Raising zj raises Σ by ezj, which lowers every si in proportion to sisj; for i = j the numerator also rises, adding si. That is si(δij − sj). The probabilities always add to 1, so a change in z can only move probability between classes, and every column of J sums to 0.
J is symmetric, so JTg = Jg = s ⊙ g − s(sTg): one dot product, then an elementwise step, instead of an n × n matrix. For cross-entropy, L = −log sc = −zc + log Σ for the target class c, and its derivative in zj is sj − δjc. Adding the same constant to every score multiplies the numerator and Σ by the same factor, which is why the shift by the maximum is free.
Example 1: softmax of three scores
Find softmax(z) for z = (2, 1, 0).
- e2, e1, e0The largest score is 2; subtracting it gives (0, −1, −2) and the same answer. These are small enough either way.
- ≈ 7.389, 2.718, 1The three exponentials.
- Σ ≈ 11.107Their sum, the shared denominator.
- s ≈ (0.6652, 0.2447, 0.0900)Each exponential over the sum. They add to 1. A gap of 1 in the scores is a factor of e ≈ 2.718 in the probabilities.
Example 2: the Jacobian, entry by entry
Find ∂s/∂z at the scores of Example 1.
- s1(1 − s1) ≈ 0.2227The diagonal entries, si(1 − si) …
- 0.1848 and 0.0819… for i = 2 and 3.
- −s1s2 ≈ −0.1628The off-diagonal entries, −sisj …
- −0.0599 and −0.0220… for (1, 3) and (2, 3). J is symmetric, so these fill both sides.
- J ≈ .2227−.1628−.0599−.1628.1848−.0220−.0599−.0220.0819Each row and column sums to 0. A finite-difference Jacobian of softmax at z agrees to every digit shown.
Example 3: the cross-entropy gradient and one step
With the scores of Example 1, the target is class 2, so y = (0, 1, 0). Find the loss, ∇zL, and the loss after one gradient step of size 1.
- L = −log s2Only the target's term survives.
- ≈ −log 0.2447 ≈ 1.4076From Example 1.
- ∇zL = s − ySoftmax and cross-entropy together.
- ≈ (0.6652, −0.7553, 0.0900)The target's entry is negative; the others are their probabilities. They sum to 0.
- z − ∇zLOne step downhill.
- ≈ (1.3348, 1.7553, −0.0900)The target's score went up, and the others went down.
- s2 ≈ 0.5511, L ≈ 0.5959Softmax of the new scores. The step moved the target from the second most likely class to the most likely.
Example 4: a backward pass without the matrix
Inside a network, softmax receives the gradient g = (1, 0, −1) from the layer above. With s from Example 1, find JTg without forming J.
- sTg ≈ 0.6652 − 0.0900One dot product.
- ≈ 0.5752The s-weighted average of g.
- g − 0.5752 · 1Subtract it from every entry.
- ≈ (0.4248, −0.5752, −1.5752)g, centered at its s-weighted average.
- s ⊙ (g − (sTg)1)Multiply entry by entry by s.
- ≈ (0.2826, −0.1408, −0.1418)The same as J times g with the matrix of Example 2, in O(n) work instead of O(n2). The entries sum to 0, as every output of J must.
Common mistakes, and the exact line they happen on
1. Keeping only the diagonal
The backward pass of Example 4.
- ∂si/∂zi = si(1 − si)Right so far: that is the diagonal, and it looks just like the sigmoid's derivative.
- s ⊙ (1 − s) ⊙ gThis is the mistake. The sigmoid acts elementwise, so its Jacobian is diagonal. Softmax doesn't: every si depends on every zj through Σ. This gives (0.2227, 0, −0.0819), which doesn't sum to 0. The right answer is (0.2826, −0.1408, −0.1418).
2. Stopping the chain rule at s
The cross-entropy gradient of Example 3.
- ∇sL = −y/sRight so far: the derivative of −log s2 with respect to s.
- ∇zL ≈ (0, −4.086, 0)This is the mistake. That is still the gradient with respect to s. One more step through softmax, JT(−y/s), gives s − y ≈ (0.6652, −0.7553, 0.0900). The wrong version never pushes the other scores down, and its size, 1/s2, blows up as the prediction gets worse.
3. Exponentiating large scores directly
Scores of z = (1000, 999, 998), which differ by the same gaps as Example 1.
- si = ezi/ΣRight so far as math.
- e1000 = ∞This is the mistake. In floating point, ez overflows once z passes about 709 (64-bit) or 88 (32-bit), and ∞/∞ is NaN. Subtract the largest score first: (0, −1, −2) gives the answer of Example 1, (0.6652, 0.2447, 0.0900), because softmax ignores a shift of every score.
Practice
Find softmax(0, 0, 0, 0).
Show answer
(1/4, 1/4, 1/4, 1/4).
Find softmax(ln 3, 0).
Show answer
(3/4, 1/4): the exponentials are 3 and 1.
For s = (0.5, 0.3, 0.2), find ∂s1/∂z2 and ∂s1/∂z1.
Show answer
−s1s2 = −0.15 and s1(1 − s1) = 0.25.
A classifier outputs s = (0.7, 0.2, 0.1) and the target is class 3. Find ∇zL for cross-entropy.
Show answer
s − y = (0.7, 0.2, −0.9).
A batch of 4 examples uses the mean cross-entropy. One row has s = (0.6, 0.4) with target class 1. What is that row of ∇ZL?
Show answer
(s − y)/4 = (−0.1, 0.1): the mean divides every row by the batch size.