Hi there. Is there a way for me to calculate the BCE loss for different areas of a batch with different weights? Seemed that the * weight (Tensor, optional) – a manual rescaling weight if provided it’s repeated to match input tensor shape for torch.nn.functional.binary_cross_entropy_with_logits — PyTorch 1.9.1 documentation and BCELoss — PyTorch 1.9.1 documentation only work at a batch-level, not pixel-by-pixel? Can I adopt the weight for specific pixels? Thanks.
The documentation is misleadingly unclear, but
(which you should use) and
BCELoss (which you shouldn’t use)
do support what you call “pixel-by-pixel” weights (as do their
Let’s assume that
target have the same shape (which
they will in any reasonable use case). Then what is required is that
weight argument passed into
have a shape that is broadcastable to the shape of
input (and hence
to the shape of
target). After broadcasting,
weight is just used to
weight each element-by-element term in the loss function on an
(Those elements can be pixels in an image, classes in a
multi-label problem, channels, etc., or any combination thereof.
BCEWithLogitsLoss doesn’t care how you choose to interpret
them – they’re just elements of a multi-dimensional tensor.)
weight has the same shape as
input, then no broadcasting is done
(or you could say that the broadcasting is trivial), and
weight will be
applied to “specific pixels” in the way that I think you’re asking for.
Many thanks for your detailed explanation, Frank. Is there a way to mask the cross-entropy loss with PyTorch BCE loss explicitly? I would like to mask out the low possibility pixels with weight=0 and keep others.
If I understand your question correctly, you can just use weights of
1.0 to do this.
Let’s say that the input to your model is a batch of images of shape
[nBatch, height, width], and that the output of your model (which
will be the
BCEWithLogitsLoss) and the
target you pass
BCEWithLogitsLoss also have this shape.
Now let me assume that you somehow construct a
pixel_possibility_tensor, also of the same shape, and that this
tensor tells you the “possibility” of each pixel (whatever that means
in your use case). If a “possibility” of, say, less than
0.35 is considered
“low possibility”, you would:
weight = (pixel_possibility_tensor > 0.35).float() loss = (weight.numel() / weight.sum()) * torch.nn.BCEWithLogitsLoss (weight = weight) (input, target)
loss computation, the
0.0 values in
weight will mask out
the “low possibility” pixels (and the
1.0 values will keep unchanged
the remaining pixels). The
weight.numel() / weight.sum()
pre-factor is so that
loss will be the loss averaged only over the
non-masked pixels, assuming that’s what you want – without it, all
of the masked pixels would also cause a bunch of zeros to get
averaged into the loss.
Got it. Thank you, Frank.