【发布时间】:2021-06-06 18:08:39
【问题描述】:
我在使用 Unet 进行图像分割时遇到了一个有趣且令人沮丧的问题。
我必须将图像分为两类:背景和感兴趣区域。感兴趣的区域通常是整个图像像素的 4%。图像约为 1600x1600 像素。 我发现 Dice loss 比 Cross Entropy 效果好得多。 但是,如果我使用标准 Dice 损失公式,我的 Unet 不会提供正确的输出,即所有像素都被预测为背景。
我的意思是标准骰子损失:
其中 x_{c,i} 是 Unet 针对像素 i 和通道 c 预测的概率,y_{c,i} 是相应的真实标签。 我使用的修改版本是:
注意分母处的 x 平方。
由于某种原因,后者使网络产生正确的输出,尽管损失收敛到 ~0.5。
我不明白为什么后者有效而前者无效。即使我在分母上使用三的幂,后者也有效。
下面是我的实现:
def make_one_hot(labels, classes):
one_hot = torch.FloatTensor(labels.size()[0], classes, labels.size()[2], labels.size()[3]).zero_().to(labels.device)
target = one_hot.scatter_(1, labels.data, 1)
return target
class DiceLoss(nn.Module):
def __init__(self,):
super(DiceLoss, self).__init__()
def forward(self, output, target):
target = make_one_hot(target.unsqueeze(dim=1), classes=output.size()[1])
output = F.softmax(output, dim=1)
numerator = (output * target).sum(dim=(2, 3))
denominator = output.pow(2).sum(dim=(2, 3)) + target.sum(dim=(2, 3))
iou = numerator / denominator
return 1 - iou.mean()
【问题讨论】:
-
嗨!我没有答案。只是想让你知道我遇到了同样的现象。
标签: deep-learning computer-vision pytorch image-segmentation loss-function