Softmax and the Log-Sum-Exp Trick
Softmax turns a row of raw scores into probabilities that sum to one, but computed the naive way it overflows on real hardware; the log-sum-exp trick gets the exact same answer without ever computing a number a computer can't hold.
Prerequisites: Cross-Entropy and Log Loss
A classifier's last layer spits out raw scores — logits — one per class, and they can be any real number: negative, huge, tiny. To train the model or report a confidence level you need probabilities: numbers that are all positive and sum to exactly 1. Softmax is the standard way to get there, but the textbook formula, typed literally into code, crashes on real logits. Fixing that crash without changing the answer is the log-sum-exp trick.
The analogy: converting speed ratings into win odds
Imagine three racehorses with speed ratings 2, 1, and 0.1. You want implied win probabilities, and you want a small rating edge to translate into a disproportionately bigger edge in odds — a horse rated one point faster should be noticeably more likely to win, not just slightly. Exponentiating each rating before comparing does exactly that: it stretches gaps between scores into much bigger gaps between probabilities, while keeping everything positive. Divide each exponentiated rating by the total to get shares that sum to 1, and you have softmax.
The formula
Here is the raw score for class , exponentiates it (always positive, and it exaggerates gaps between scores), and dividing by the sum over all classes rescales the exponentiated scores so they add up to 1. In words: exponentiate every score, then divide each one by the total.
Worked example 1: softmax by hand
Logits . Exponentiate: , , . Sum . Divide each by the sum: probabilities . The rating gap of 1.9 between the best and worst horse became a probability gap of 56 percentage points — softmax amplified it.
Worked example 2: the overflow, and the fix
Now suppose the logits are — plausible if a network's outputs are poorly scaled. A computer's floating-point numbers top out around , but — it overflows to inf. The next class gives another inf. Dividing inf by inf produces NaN: the computation has silently broken.
The fix costs nothing mathematically: subtract the maximum logit, , from every score before exponentiating.
This is the same function — multiplying top and bottom by doesn't change a ratio — but now the largest exponent is instead of . Redo the arithmetic: , , , sum , giving — nothing overflows, and it is the exact answer you'd get if infinite-precision arithmetic were available. The same shift-then-sum idea, applied to the log of the softmax denominator, is called log-sum-exp: , and it's what lets cross-entropy loss be computed directly in log-space without ever forming the probabilities at all.
Drag the exponent below and watch how fast leaves any sane numeric range — that runaway growth is exactly what the shift is designed to tame.
Softmax is exponentiate-then-normalize: . Subtracting the maximum logit from every score before exponentiating (the log-sum-exp trick) gives the mathematically identical result while keeping every intermediate number within floating-point range.
What this means in practice
Every deep learning framework's built-in softmax and cross-entropy functions already apply this shift internally — torch.nn.functional.cross_entropy never computes raw softmax probabilities at all, it works in log-space via log-sum-exp for both speed and stability. The practical danger appears when someone reimplements softmax by hand (in a custom loss, in interview code, in a from-scratch project) and skips the shift: it works fine on small toy logits and then silently produces NaN losses the moment the network's outputs drift to large values during training, which is exactly the situation you most need the loss to behave.
The common confusion is thinking the log-sum-exp trick is an approximation — that it trades accuracy for stability. It isn't: subtracting a constant from every logit before exponentiating leaves the softmax output mathematically unchanged, because that constant cancels between numerator and denominator. It is a rearrangement of the same computation, not a different one, and it produces the exact same probabilities a computer with unlimited numeric range would produce directly.
Related concepts
Practice in interviews
Further reading
- Goodfellow, Bengio & Courville, Deep Learning, Ch. 4