The problem
This is the loss every language model is trained with. The model has to choose among classes (for a language model, the tokens of the vocabulary), and for each of examples it outputs one raw score per class, its logits. You get:
logits, a table with rows and columns: is the score of class for example ;targets, integers: is the right class of example .
The loss of one example is minus the log of the probability the model gives to its right class, after softmax. The loss of the batch is the average over the examples.
The loss
Computing softmax and then the log is unsafe (a tiny probability can round to 0, and ). The same quantity, written with the LSE (log-sum-exp) function, stays finite:
where:
- is row of the logits;
- is the logit of the right class of example ;
- , computed with the stable trick of the NumPy section.
Example. Two examples, : logits
[[2, 1, 0], [0, 0, 0]], targets[0, 2].
- Row 0: , the right logit is , loss .
- Row 1: , the right logit is , loss . With equal logits every class gets , so this is .
- Mean: .
The gradient
The gradient with respect to the logits is the softmax probabilities minus the one-hot target, divided by because of the mean (the theory page derives it):
where:
- are the probabilities of row ;
- is 1 for the right class and 0 for the others.
Example. Same batch.
- Row 0: ; subtract 1 at class 0: ; divide by : .
- Row 1: ; subtract 1 at class 2: ; divide by 2: .
What to implement
cross_entropy(logits, targets): the mean loss, a single number.cross_entropy_backward(logits, targets): the gradient, shape .
Requirements
- Stable for any logits:
[[1000, 0]]with target1has loss , notinfornan. - No Python loops over the batch. Read the right logits with integer-array indexing, as in the
one-hot-gatherexercise, not with a one-hot matrix.
Hints
- For the loss, compute the log-softmax of every row, , then pick the right entry of each row and average.
- For the gradient, start from the softmax probabilities, subtract 1 at the right class of every row (integer-array indexing again, with
-=), and divide by .