Visualize how networks process dummy data, compare exact vs predicted values, calculate batch cost, and backpropagate to minimize Loss.
A loss collapses a whole batch of predictions into one scalar, and it has to do so in a way that is differentiable — otherwise there is nothing to descend. Which function you pick depends on what you are predicting.
The loss is the single number that training is allowed to care about. Every gradient in the network is a derivative of this one value.
MSE. Predictions [2.5, 0.0, 2.0] against targets [3.0, −0.5, 2.0]. The errors are 0.5, 0.5 and 0. Squared: 0.25, 0.25, 0. Mean: 0.167. Squaring means one error of 2.0 costs more than four errors of 0.5.Cross-entropy. If the model gives the correct class a probability of 0.7, the loss is −ln(0.7) = 0.357. If it gives that class only 0.05, the loss is −ln(0.05) = 3.00 — roughly eight times worse. Being confidently wrong is punished far harder than being uncertain.
Training needs a single scalar to minimise. The loss function is what produces it: compare each prediction with its target, score the discrepancy, and average over the batch.
Everything downstream depends on that one number. The gradient is its derivative, the optimiser follows the gradient, and the model becomes whatever minimises it. Choosing the loss is therefore choosing what the model will optimise for — a modelling decision, not a technical detail.
The standard choices:
| Task | Loss | Formula |
|---|---|---|
| Regression | Mean squared error | mean((ŷ − y)²) |
| Regression, outliers present | Mean absolute error | mean(|ŷ − y|) |
| Regression, compromise | Huber / smooth L1 | Squared near zero, linear beyond |
| Binary classification | Binary cross-entropy | −[y log p + (1−y) log(1−p)] |
| Multi-class | Categorical cross-entropy | −log(p of the true class) |
| Multi-label | Binary cross-entropy per label | Sum over labels |
| Ranking, embeddings | Triplet, contrastive | Distance-based |
Regression. Predictions [2.5, 0.0, 2.1] against targets [3.0, −0.5, 2.0]:
Classification. Three samples, true classes 0, 1, 2, and the model gives the correct class probabilities 0.7, 0.2, 0.9:
The second sample contributes most of the total, and that is deliberate. Cross-entropy punishes confident mistakes without limit, so the model's attention goes where it is most wrong.
A useful check: at initialisation, cross-entropy over C balanced classes should be about ln(C) — 2.30 for 10 classes. Seeing that in the first steps means the setup is sane.
Both measure regression error and they encode different opinions about outliers.
Squaring makes a single large miss dominate: an error of 10 contributes 100, while twenty errors of 1 contribute 20 in total. The fitted model will distort itself to reduce that one point.
Absolute error treats every unit of error equally, so it is robust — and it has a corner at zero, which makes its gradient constant in magnitude regardless of how close you are.
Huber loss is the standard compromise: squared within a threshold δ of zero, linear beyond it. Smooth gradients near the optimum, bounded influence from outliers. It is the default regression loss in several detection frameworks for exactly this reason.
There is a deeper reading. Minimising squared error estimates the conditional mean; minimising absolute error estimates the conditional median. So the choice of loss is a choice about which summary of the target distribution you want predicted.
Comparing loss values that are not comparable. A loss summed over a batch and a loss averaged over a batch differ by a factor of the batch size. Two runs with different batch sizes or different reduction settings are not measuring the same thing, and neither is a run that changed loss function mid-experiment.MSE on a classifier. It technically works and trains badly. When the model is confidently wrong, cross-entropy produces a large gradient and MSE produces a small one, so the model is slowest to fix exactly the errors that matter most.Unscaled regression targets. Squared error on values around 300,000 produces enormous gradients. Scale the target, or the first update will destroy the weights.
The loss is the only thing the network is optimising — if it does not measure what you care about, nothing downstream can fix that.
Three details of how a batch's losses are combined matter in practice.
Reduction. mean averages over the batch and is the default; sum totals them, which makes the effective learning rate depend on batch size; none returns per-example losses, which is what you need for custom weighting or for finding the hardest examples.
Class weighting. On imbalanced data, weighting each class's contribution by the inverse of its frequency stops the majority class dominating the average:
weights = torch.tensor([1.0, 12.0]) # positive class is 12x rarer
criterion = nn.CrossEntropyLoss(weight=weights)Masking. Padded positions in a sequence, and pixels marked "unlabelled" in a segmentation mask, must be excluded. ignore_index does this:
criterion = nn.CrossEntropyLoss(ignore_index=-100) # skip these positionsForgetting to mask is a real and quiet bug: the model spends a large share of its capacity learning to predict padding tokens, and the reported loss is not comparable to anyone else's.
These are different things and should be allowed to differ.
The loss must be differentiable so gradients exist. Accuracy, F1, IoU and mAP are not differentiable — they are step functions of the predictions, with zero gradient almost everywhere. You cannot optimise them directly.
So the standard arrangement is: train on a smooth surrogate, evaluate on the metric you care about. Train on cross-entropy, report F1. Train on Dice-plus-cross-entropy, report IoU.
The two can disagree, and that is informative rather than alarming. Validation loss rising while accuracy stays flat usually means the model is becoming overconfident on the examples it already gets right — a calibration problem rather than a classification one. Early stopping on the metric you care about, rather than on the loss, is often the better choice.
Some metrics have differentiable relaxations — soft-Dice, soft-IoU, and the CIoU family for bounding boxes — and using them closes part of the gap between what you optimise and what you measure.
MSE, MAE, Huber, binary and categorical cross-entropy on the same predictions -- so you can see what each one punishes and how hard.
Why is my loss NaN? A log(0), a division by zero, or a learning rate high enough to send the weights to infinity. Use the framework's fused losses, which guard the logarithm.
Can I add several losses together? Yes, and it is common in multi-task models. Weight them, and be aware the weights matter: a term ten times larger dominates training regardless of importance.
Should the loss go to zero? Not on real data. Irreducible noise means there is a floor, and reaching zero on training data usually means memorisation.
Why does my validation loss rise while accuracy holds? Growing overconfidence. Consider label smoothing, and stop on the metric rather than the loss.
How do I handle imbalanced classes? Class weights, or focal loss, which down-weights the easy examples the majority class provides.
Do I apply softmax before the loss? No — pass logits. The fused loss applies it internally and stably. Applying it twice is a common silent bug.
Answer without scrolling back up.
What is a loss function for?
Optimisation needs a single scalar to push downhill. The loss is that scalar, and its choice defines what the model treats as an error in the first place.
Why use cross-entropy rather than squared error for classification?
Cross-entropy goes to infinity as a confident prediction turns out wrong. Squared error caps out, so a badly wrong classifier gets only a weak nudge to fix itself.
Training loss is falling but validation loss has started to rise. This means:
The model is still improving on data it has seen while getting worse on data it has not. That gap opening up is the definition of overfitting, and the point early stopping watches for.
A loss collapses a whole batch of predictions into one scalar, and it has to do so in a way that is differentiable — otherwise there is nothing to descend. Which function you pick depends on what you are predicting.