图像分割的评价指标Dice Iou的计算方式总结

计算dice和mdice的方法详解

目前找到三种实现方式,且三种方式结果不同

  1. 通过计算tp,fp,fn等根据公式image-20210906200051794计算,但我觉得使用概率计算fp等值是不准确的,保留意见

    def mDiceLoss(inputs, target, beta=1, smooth=1e-6):
        n, c, h, w = inputs.size()
        nt,ct, ht, wt = target.size()
        if h != ht and w != wt:
            inputs = F.interpolate(inputs, size=(ht, wt), mode="bilinear", align_corners=True)
        temp_inputs = torch.softmax(inputs.transpose(1, 2).transpose(2, 3).contiguous().view(n, -1, c), -1)
        temp_target = target.view(n, -1, ct)
        # tp = torch.sum(temp_target[..., :-1] * temp_inputs, axis=[0, 1]) #和下面等效
        tp = torch.sum(temp_target * temp_inputs, axis=[0, 1])
        fp = torch.sum(temp_inputs, axis=[0, 1]) - tp
        fn = torch.sum(temp_target[..., :-1], axis=[0, 1]) - tp
    
        score = ((1 + beta ** 2) * tp + smooth) / ((1 + beta ** 2) * tp + beta ** 2 * fn + fp + smooth)
        dice_loss = 1 - torch.mean(score)
        return dice_loss
    
  2. 通过公示image-20210906202123661 计算得到的,但是这种方法中的sum()方法没有计算每个通道,而是对所有值计算的。
    并且这种方法在网上很通用,各位大佬也是这样计算的暂时采用这种方法。具体实现有两种方式,如下:

def SoftDiceLoss(y_pred,y_true, epsilon=1e-6):
   if len(inputs.shape) == 4:
        y_pred=torch.softmax(y_pred,1)
    if len(inputs.shape) == 3:
        y_pred=torch.softmax(y_pred,0)
    numerator = 2. * torch.sum(y_pred * y_true)
    # denominator = np.sum(np.square(y_pred) + np.square(y_true), axes)
    denominator = torch.sum(y_pred + y_true)
    return 1 - torch.mean((numerator + epsilon) / (denominator + epsilon))
class DiceLoss(nn.Module):
    def __init__(self, weight=None, size_average=True):
        super(DiceLoss, self).__init__()

    def forward(self, inputs, targets, smooth=1e-6):
        # comment out if your model contains a sigmoid or equivalent activation layer
        if len(inputs.shape)==4:
            inputs = F.softmax(inputs,dim=1)
        if len(inputs.shape)==3:
            inputs = F.softmax(inputs,dim=0)
        # flatten label and prediction tensors

        inputs1 = inputs.view(-1)
        targets1 = targets.view(-1)
        intersection1 = (inputs1 * targets1).sum()
        dice = (2. * intersection1 + smooth) / (inputs1.sum() + targets1.sum() + smooth)
        return 1 - torch.mean(dice)
  1. 基于第二种方法,我觉得应该计算每个通道的dice然后求均值,具体实现如下:
def SoftDiceLoss(y_pred,y_true, epsilon=1e-6):
    if len(inputs.shape) == 4:
        y_pred=torch.softmax(y_pred,1)
    if len(inputs.shape) == 3:
        y_pred=torch.softmax(y_pred,0)
    numerator = 2. * torch.sum(y_pred * y_true,axis=[0,2,3])
    # denominator = np.sum(np.square(y_pred) + np.square(y_true), axes)
    denominator = torch.sum(y_pred + y_true,axis=[0,2,3])
    return 1 - torch.mean((numerator + epsilon) / (denominator + epsilon))
class DiceLoss(nn.Module):
    def __init__(self, weight=None, size_average=True):
        super(DiceLoss, self).__init__()

    def forward(self, inputs, targets, smooth=1e-6):
        # comment out if your model contains a sigmoid or equivalent activation layer
        if len(inputs.shape)==4:
            inputs = F.softmax(inputs,dim=1)
        if len(inputs.shape)==3:
            inputs = F.softmax(inputs,dim=0)
        temp_inputs=rearrange(inputs, "n c h w->(n h w ) c")
        temp_target=rearrange(targets, "n c h w->(n h w ) c")
        intersection = (temp_inputs * temp_target).sum(0)
        dice1 = (2. * intersection + smooth) / (temp_inputs.sum(0) + temp_target.sum(0) + smooth)
        print(dice1)
        return 1 - torch.mean(dice)

这种方法分子分母和第二种方法结果一样,只是维度是c结果差在了不同维度做除法然后再求均值

但是这种方法要学会如何使用torch.sum(t,axis=[0,1])维度的使用。sum(0)表示在第0维做加法。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值