Maths for ML / Read an equation
Softmax
Turns a list of scores, one per class, into probabilities that are all positive and add up to 1.
The parts
Point at any part of the equation, or pick it from the list.
probability of class i · output · shape one number between 0 and 1, for each of the K classes
The whole output is a vector of K probabilities that add up to 1.
which class · index · shape 1 to K
The class whose probability this line computes. The same formula is used for every i.
exp of this class's score · operation · shape one positive number
Makes the score positive and stretches the gaps: a score 1 higher becomes about 2.7 times bigger.
the normalizer · operation · shape one number, the same for every i
Adds up the exp of every class's score, so dividing by it makes the K outputs sum to 1.
sum over all classes · index · shape j counts 1, 2, …, K
A different letter from i on purpose: i is the one class on top, j runs over every class underneath, including i itself.
Read it with the seven questions
- What comes out? A vector of K probabilities, one per class, adding up to 1.
- List the parts. Input: the scores z (often called logits), one per class. Indices: i for the class on top, j for the sum. Nothing learned inside softmax itself.
- Check the shapes. z has length K, the output has length K. The denominator is one number shared by every class.
- Say what each function does. exp makes every score positive and magnifies differences; the sum and the division normalize.
- Ask what makes it bigger or smaller. Raising one score raises its own probability and lowers every other one, because the shared denominator grows.
- Push the inputs to extremes. All scores equal: every class gets 1/K. One score far above the rest: it takes almost all the probability. Adding the same number to every score changes nothing, which is why code subtracts the largest score first to keep exp from overflowing.
- Write it as code. e = np.exp(z - z.max()); p = e / e.sum().
Change it and watch
Move the four scores and watch the probabilities share out. Then try the temperature: dividing every score by T before softmax. Small T makes the winner take all; large T spreads probability evenly. Language models use exactly this knob when they sample text.
Now write it in NumPy
import numpy as np
z = np.array([2.0, 1.0, 0.1])
e = np.exp(z - z.max()) # subtracting the max avoids overflow and changes nothing
p = e / e.sum()
print(p.round(3), p.sum()) # [0.659 0.242 0.099] 1.0