Loss functions (spec layer) #
This file defines a small collection of common losses (and their gradients) in a way that is:
- shape-generic: a loss takes
Tensor α sand reduces it to a scalarα, - explicit about reduction: most losses here are "mean over all elements",
- easy to line up with PyTorch terminology when you read training code.
In PyTorch you'll often see two layers:
- a low-level, elementwise loss (for example, Huber loss),
- plus a reduction (
meanorsum).
TorchLean's spec layer mirrors that idea: most definitions are written as an elementwise formula followed by a global mean over the shape.
Sum all tensor elements into a single scalar.
Instances For
Mean of a scalar that conceptually came from a tensor with shape s.
The denominator is TorchLean.Tensor.meanDenominator, the same totalized element count the tensor
reductions use, so the loss layer and mean agree on what an empty tensor averages to.
Instances For
Number of slices orthogonal to axis in a tensor shape.
Classification losses sum along the selected class dimension and average over every other
dimension. Thus a class vector has one slice, a matrix of shape (batch, classes) with class
dimension 1 has batch slices, and a tensor may instead place its class dimension anywhere in
the shape.
Instances For
Totalized denominator for a mean over slices orthogonal to axis.
Instances For
Divide a classification loss by the number of slices orthogonal to axis.
Instances For
Mean squared error: average of $(\mathtt{predicted}-\mathtt{target})^2$.
Instances For
Derivative of mseSpec with respect to predicted.
Instances For
Mean absolute error: average of |predicted - target|.
Instances For
Derivative of maeSpec w.r.t. predicted (subgradient via sign).
Instances For
Huber loss with transition parameter delta.
Elementwise, for residual $d=\mathtt{pred}-\mathtt{target}$:
- if $\lvert d\rvert<\delta$: $\tfrac12d^2$
- otherwise: $\delta(\lvert d\rvert-\tfrac12\delta)$
Then we take a mean over all elements.
This is PyTorch's HuberLoss convention. It differs from SmoothL1Loss by a factor of delta.
The Huber interpretation requires delta > 0.
Instances For
Derivative of huberSpec w.r.t. predicted.
Instances For
Cross-entropy between distributions (probabilities).
This is closest to PyTorch when you already have probabilities q (e.g. after a softmax) and a
probability target p (e.g. one-hot or label-smoothed), and you want:
$$ \operatorname{CE}(p,q) =-\operatorname{mean}_r\sum_c p_{rc}\log q_{rc}, $$
where c ranges along the selected class dimension and r ranges over all remaining dimensions.
A lone class vector is one distribution and is not divided by its number of classes.
PyTorch's F.cross_entropy typically takes logits and does log_softmax + NLLLoss; that is a
different API surface than this "probabilities in, scalar out" spec.
Instances For
Derivative of crossEntropySpec w.r.t. predicted.
Instances For
Cross-entropy on logits (stable log-softmax form).
This matches the common PyTorch decomposition:
$$ \operatorname{cross\_entropy}(\mathtt{logits},\mathtt{target}) =-\operatorname{mean}_r\sum_c \mathtt{target}_{rc}\operatorname{logsoftmax}(\mathtt{logits})_{rc}, $$
where the dimension selected by axis contains classes and r ranges over the remaining
dimensions. This is PyTorch's reduction="mean" convention for one-hot or soft distribution
targets.
Unlike crossEntropySpec, this takes logits and uses Activation.logSoftmaxSpec for
numerical stability.
Probability targets usually sum to one along axis, as in one-hot or label-smoothed targets.
The same formula also accepts arbitrary target weights. Their sum scales the contribution of
that slice; the reduction still divides by the number of slices, not by the total target weight.
Instances For
Derivative of crossEntropyLogitsSpec with respect to the logits.
For each class slice, differentiating the log-normalizer contributes
softmax(logits) * sum(target). The direct logit term contributes -target. Keeping that
slice sum makes the derivative agree with the loss for weighted, unnormalized, and zero targets.
For a probability target, its sum is one and the familiar softmax(logits) - target follows.
The reduction drops the class axis and then restores that exact axis. Ordinary trailing-axis broadcasting would mix slices when classes occupy an outer or middle dimension. Empty class axes use the same zero-sum convention as the loss.
Instances For
Hinge loss (binary margin loss), elementwise then mean-reduced:
$\operatorname{hinge}(x,y)=\operatorname{mean}_i\max(0,1-y_i x_i)$.
This matches the usual SVM-style hinge loss. (PyTorch exposes similar behavior via margin-style
losses such as HingeEmbeddingLoss / MultiMarginLoss, but the exact signature differs.)
Instances For
Derivative/subgradient of hingeSpec w.r.t. predicted.
Instances For
Poisson negative log-likelihood (log-input form), elementwise then mean-reduced:
If predicted represents log(rate) and target is a nonnegative count,
then (up to an additive constant that does not affect gradients):
$\operatorname{loss}_i=\exp(\mathtt{pred}_i)-\mathtt{target}_i\mathtt{pred}_i$.
This corresponds to PyTorch's PoissonNLLLoss(log_input=true, full=false) at the math level.
Instances For
Derivative of poissonSpec w.r.t. predicted.
Instances For
Cosine similarity loss: 1 - cos(predicted, target) (reduced-to-scalar).
Instances For
Derivative of cosineSimilaritySpec w.r.t. predicted.
If $\cos=(p\mathbin{\cdot}t)/(\lVert p\rVert\lVert t\rVert)$ and $\operatorname{loss}=1-\cos$, then (for nonzero norms):
$$ \frac{\partial\operatorname{loss}}{\partial p} =\frac{p\mathbin{\cdot}t}{\lVert p\rVert^3\lVert t\rVert}p -\frac{1}{\lVert p\rVert\lVert t\rVert}t. $$
We use epsilon to avoid division by zero (similar to common "eps" handling in PyTorch code).
Instances For
Log-cosh loss (reduced-to-scalar): log(cosh(predicted - target)).
Instances For
Derivative of logCoshSpec w.r.t. predicted.
Instances For
Binary cross-entropy on scalars (probabilities), with clipping to avoid log(0).
This matches the core formula behind PyTorch's BCELoss when predicted is already a probability
(not a logit):
$$ \operatorname{BCE}(p,y) =-\left(y\log p+(1-y)\log(1-p)\right). $$
Assumption: target is in [0, 1]. We do not clip the target; we only clip predicted.
Instances For
Selected derivative of binaryCrossEntropySpec w.r.t. predicted.
The clipped forward function is not differentiable at epsilon or 1 - epsilon; this definition
chooses zero at those two kinks and on the clipped exterior branches.
Instances For
Tensor BCE (probabilities), elementwise then mean-reduced.
Instances For
Derivative of binaryCrossEntropyTensorSpec w.r.t. predicted.