How to use focalloss in segmentation?

Hello, I’m doing a project about semantic segmentation with 2 class using U-net , but my data was unbalanced, so I think maybe use focalloss is a good idea for my project, and I was use BCEloss, so changed the final layer from 1 channel to 2 channels, and use this code focalloss2d,but the loss was unchanged during trainning, I’m so confused ,I give the label 0 or 1 to the mask, I don’t know where it is wrong. Thanks!

here is part of my Dataset

normalize = T.Normalize(mean=[0.4, 0.4, 0.4], std=[0.4, 0.4, 0.4])
            self.transforms4imgs = T.Compose([
                T.ToTensor(),
                normalize
            ])
            self.transforms4label = T.Compose([
                T.ToTensor(),
            ])

data = cv2.imread(img_path)
label = cv2.imread(label_path, 0)
_, label = cv2.threshold(label, 100, 255, cv2.THRESH_BINARY)
label = label / 255
label = label[:, :, np.newaxis]
data = self.transforms4imgs(data)
label = self.transforms4label(label)

If you just have two exclusive target classes and would like to use nn.BCELoss, you have to add a nn.Sigmoid() layer as your output layer into your model and also use a target between 0 and 1.
Otherwise if your use case is a multi-label classification, i.e. both classes can be true at the same time for the same pixel, you could use two outputs for your model.

The focal loss implementation seems to use F.cross_entropy internally, so you should remove any non-linearities applied on your model output and pass the 2 channel output directly to your criterion.

many thanks! this driving me crazy for two days!! I have modified my code just now, and is my label data right?:smiley:

Where did you modify the code? In your first post or the github repo?
I’m not sure about this line:

label = label[:, :, np.newaxis]

Are you trying to add a batch dimension to your target?
If so, the batch dimension should be at dim0, i.e. the first dimension.
Make sure your label is of type long.

Here is a small code example using F.cross_entropy:

batch_size = 5
nb_classes = 3

output = torch.randn(batch_size, nb_classes)
target = torch.empty(batch_size, dtype=torch.long).random_(nb_classes)

loss = F.cross_entropy(output, target)

Why the ReLU in the output does need to remove when using cross entropy? Thanks

Because when you using cross entropy, it contains log_softmax fuction.

1 Like

Thank you!!! I know!

So we have to add ReLU to remove the negative value. But he said we have to remove the ReLU

oh, sorry, I misunderstood, while, I found a view that use leakyRelu(negative_slope = 0.3) is a good idea for sementation, because it persist the negative value, but I don’t know why and it is right.

Great. So your code will be

self.lrelu = nn.LeakyReLU(negative_slope=0.3, inplace=True)
x = self.conv(x)
x = self.lrelu(self.bn(x))