Focal loss
Lesson: Loss FunctionsCheat sheetTrack: Deep learning coreTrack: Papers to code
Problem
Focal loss is cross-entropy with a weight that makes easy examples count less. A detector sees many easy background regions and few objects. With plain cross-entropy, the easy examples give most of the loss. Focal loss multiplies each term by (1 - p_t)^\gamma, so the model learns more from the hard examples.
Task
Write three functions.
binary_focal_loss(logits, targets, gamma, alpha)returns the mean binary focal loss.binary_focal_grad(logits, targets, gamma, alpha)returns the gradient of that mean loss with respect to the logits.focal_loss(logits, targets, gamma, alpha)returns the mean multi-class focal loss.
For one example, p_t is the predicted probability of the true class and
In the binary case, the logit is x and the target is y \in \{0, 1\}. Then p_t = \sigma(x) when y = 1 and p_t = 1 - \sigma(x) when y = 0, with \sigma(x) = 1 / (1 + e^{-x}). With a float alpha, \alpha_t = \alpha when y = 1 and \alpha_t = 1 - \alpha when y = 0.
In the multi-class case, p_t is the softmax probability of the target class over the row of logits. With an array alpha of size C, \alpha_t is alpha[target].
When alpha is None, \alpha_t = 1. Each loss is the mean of \mathrm{FL} over the batch. With \gamma = 0 and no alpha, both losses are the ordinary cross-entropy.
Input and output
| Name | Type | Shape | Meaning |
|---|---|---|---|
logits (binary) | float array | (N,) | one logit for each example |
targets (binary) | float array | (N,) | 0 or 1 for each example |
logits (multi-class) | float array | (N, C) | one row of logits for each example |
targets (multi-class) | int array | (N,) | the class index of each example, from 0 to C - 1 |
gamma | float | the focusing exponent, 0 or more | |
alpha | float, float array or None | () or (C,) | the class weight: a float in the binary case, an array of size C in the multi-class case |
binary_focal_lossandfocal_lossreturn a Python float.binary_focal_gradreturns a float array of shape(N,).
Constraints
1 <= N <= 1000,2 <= C <= 100,0 <= gamma <= 5and0 < alpha < 1in the binary case.- Logits can be as large as 1000 in absolute value. The loss and the gradient must stay finite.
- Do not change the input arrays.
- Use numpy only.
Examples
pythonlogits = np.array([2.0, -1.0, 0.5, -3.0])
targets = np.array([1.0, 1.0, 0.0, 0.0])
binary_focal_loss(logits, targets, 0.0)
binary_focal_loss(logits, targets, 2.0)
binary_focal_loss(logits, targets, 2.0, 0.25)
binary_focal_grad(logits, targets, 2.0, 0.25)text0.6157135085787611
0.270298187607633
0.1147646574248966
[-3.04433762e-04 -4.80146702e-02 9.86534666e-02 5.90384712e-05]pythonlogits = np.array([[2.0, 1.0, 0.1], [0.5, 2.5, 0.3]])
targets = np.array([0, 1])
focal_loss(logits, targets, 0.0)
focal_loss(logits, targets, 2.0)
focal_loss(logits, targets, 2.0, np.array([0.5, 1.0, 2.0]))text0.31853976964918573
0.02853873533647399
0.016415649484550623Source paper Focal Loss for Dense Object Detection, Lin et al., 2017.
Hints
4 hintsSolution and notes
LockedPass every check with Submit to open the reference solution and the notes.
Run it on your computer
Clone the repository, install numpy and run the same checks in a terminal:
python3 scripts/practice/run.py focal-loss my_answer.py
python3 scripts/practice/run.py focal-loss my_answer.py --examplesStart my_answer.py from starter.py.
Your code is saved in this browser as you type. On a phone you can read and edit the code, but the checks are easier to use on a desktop.
Keyboard shortcuts
- Ctrl Enter
- Run the examples
- Ctrl Shift Enter
- Submit
- Tab / Shift Tab
- Indent or outdent the lines
- Esc then Tab
- Move the focus out of the editor
- Alt H
- Show the next hint
On a Mac, use Cmd in place of Ctrl.
Select Run to check the examples, or Submit to run every check.