I am sorry if my question might seem silly, but I would like to learn. I am quite new to programming and segmentation tasks. In effect, I am having a dataset with labels that are not in the form of [0,1] as It should be for a binary segmentation task. The readme of the data says that the probability of the label ranges from 0 to 1 and that I should use a threshold value of 0.5 to adjust the data before feeding into the network. Please, I would like to get a better understanding of this concept as well as how I can modify the label before feeding the data into the network. When I input the data and labels to the network without thresholding the labels, the network cannot detect anything.
Any suggestions and/or comments would be highly appreciated
Could you explain a bit how you are feeding the target to the network?
Usually you would feed the data into the model and use its output and target to calculate the loss.
You don’t need to apply a threshold on the target to calculate the loss.
However you might want to apply a threshold on the model outputs to get the class predictions (for a binary use case).
Yes, you are right. I am not applying a threshold on the target to calculate the loss.
I am feeding the target directly without considering any threshold.
Am I supposed to apply a threshold to the target before feeding into the network? I have noticed that the loss could decrease normally without anything strange. However, The testing results were very bad ( dice = 0.002).
Please, I would like to know when and how should the threshold be applied
Usually not, but I might misunderstand your use case.
Do you want to apply a threshold to the target or your model outputs?
The latter case would make sense, while I’m not sure about the former one.
From your explanation, I think that the threshold should be applied to the model outputs instead.
Please, how should it be done?
In the mean time I had tried to apply a threshold to the target before feeding into the network (this could be seen as a data preprocessing step). I did it with the following lines of code
If your target is a probability between 0 and 1, you could directly use it in nn.BCEWithlogitsLoss.
You don’t need to apply a threshold on the model output to calculate the loss, but could use it to get the predictions and calculate the accuracy.
If your model outputs are logits, you could use a threshold of 0.0.
Could you post the custom loss and explain what your model outputs?
Since you are using nn.CrossEntropyLoss, I assume your model returns an output in the shape [batch_size, 2, height, width]? If that’s the case, you should not apply any threshold, but get the predicted classes via preds = torch.argmax(output, 1).
If your model returns logits of the shape [batch_size, 1, height, width], you could get the predictions via: preds = output > 0.0. However, see the comment before, as I’m skeptical what your model returns.
The output shape won’t work for a binary classification using F.cross_entropy and you should get an error, if label_batch contains zeros and ones (for both classes).
nn.CrossEntropyLoss expects an output in the shape [batch_size, nb_classes=2, depth, height, width] in your use case, and a target in the shape [batch_size, depth, height, width] containing values in the range [0, 1].
Also, based on your given shape, outputs_soft[:,1,:,:,:] should give you an IndexError.
Your dice_loss implementation might be wrong or the inputs are not what I would expect.
Could you post the code for the dice_loss implementation, please?
As I explained earlier, the problem is about the targets. The targets are not in the form of 0 (background) and 1(foreground) as it should be in the case of binary segmentation. Instead, the values of the foreground are float values ranging from 0.1 to 1. After reading online, I found that it could also be seen as a regression problem rather than classification. I am yet to get a clear picture of everything given that I am a beginner. Please, any explanation and suggestions would be highly appreciated.
Thanks for mentioning it again.
The dice loss is used for discrete data, so I doubt it can work for a regression task.
Since your labels are in the range [0, 1], I would again recommend to use nn.BCEWithLogitsLoss.
Alternatively, since you are already rounding the targets to 0 and 1 to be able to use F.cross_entropy, you could also apply the same for the dice loss calculation.