Softmax: what it does and how to keep it stable
Softmax turns raw scores (logits) into probabilities, but you have to be careful to avoid numerical overflow/underflow.
Softmax definition and properties
For a logits vector (one logit per class), softmax is
Key properties:
- Probabilities: each
- Sum to 1:
- Order-preserving: if then
- Shift-invariance: adding the same constant to all logits doesn’t change probabilities:
Proof of shift-invariance:
Why subtracting max(logits) helps numerical stability
If some logits are large (say 1000), then overflows to infinity in float32.
If some are very negative (say -1000), underflows to 0.
Because of shift-invariance, we can safely do:
Then compute
Mechanism:
- The largest logit becomes 0:
- So the biggest exponent is , which is safe (no overflow)
- Others become , so their exponentials are in , again safe
- Relative differences between logits stay the same, so probabilities are unchanged
Example that would overflow without this trick:
- Logits:
z = [1000, 999, 990]- Directly:
exp(1000)overflows in float32
- Directly:
- Shifted:
max(z) = 1000z' = [0, -1, -10]exp(z') ≈ [1, 0.3679, 0.0000454]— all perfectly fine
Always compute softmax of z - max(z) in practice; same result, much safer numerically.
1 / 5