Usage
loss_iou(smooth = 1)
loss_dice(smooth = 1)
loss_generalized_dice(smooth = 1)
loss_cce(label_smoothing = 0)
loss_cce_dice(cce_weight = 0.5, smooth = 1)
loss_focal(gamma = 2, alpha = NULL)
loss_tversky(alpha = 0.5, smooth = 1)
loss_focal_tversky(alpha = 0.5, gamma = 1, smooth = 1)
loss_combo(alpha = 0.5, ce_ratio = 0.5)
loss_mse(where = NULL)
loss_l1(where = NULL)
loss_smooth_l1(beta = NULL, where = NULL)
loss_lovasz(per_image = FALSE)
Details
There is one documented separately because it needs a page of its own: loss_boundary() adds the signed distance to the truth’s boundary on top of any of these, which removes the systematic volume bias at some cost in per-case accuracy.
Three of these score numbers rather than classes - loss_mse(), loss_l1() and loss_smooth_l1() - and they are not alternatives to the others. A class target has nothing for them to measure and a continuous one has nothing for an overlap to measure, so they belong in exactly one place: the loss of separation_flows(), where the target is a vector field. Measured against the pinned engine rather than assumed: giving one as any segmentation model’s own loss is refused by name - semantic or instance - and giving a class loss to separation_flows() is refused by name the other way round.
One of these weights the classes rather than treating them alike - loss_generalized_dice(), by the inverse square of how much of the picture each class occupies - and the argument usually made for it is not the argument for it here. It is introduced in the literature as a fix for Dice being dominated by the background, and loss_dice() in this package is a mean over the class channels: a lesion in 1% of the frame already carries the same weight as the 99% around it. Measured on a 1% target, with one prediction that finds the lesion and leaks a false positive of equal size and one that misses it and gets the background perfect:
So what it adds is weight beyond an equal share - on that target the classes come out weighted 1 to 9801 - and the objective that is genuinely dominated is the per-pixel half of loss_cce_dice(): to cross-entropy a false positive and a missed lesion of the same size are the same number of wrong pixels, which is the indifference in that row. Two things follow. With every class the same size this is exactly loss_dice() pooled over the classes, so on a balanced problem it costs nothing and buys nothing. And it is not a third loss_tversky(): Tversky moves the balance between false positives and false negatives by a number you choose, loss_focal_tversky() reweights the hard pixels, and this reweights classes by how much of the image they occupy, computed from each batch rather than set by hand - so a batch holding no lesion at all is scored on flat weights, which is an argument for a larger batch_size on a sparse dataset rather than against the loss.
This page said an instance model’s own until the pin moved to 0.8.0a22, and it was true rather than wrong: the refusal lived on the instance class alone, and a semantic model accepted loss_mse() and trained with it, reporting a validation loss of 0.0014 for a mask that was half missing where loss_cce() reaches a Dice of 1.0000. The default where = “foreground” is what made it look as though it had worked - it evaluates the objective only inside the labelled objects and leaves the background unconstrained. The engine refuses it at either task now (pyplatypus#223).