You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

图像分割中Dice系数计算正确性验证及与F1分数差异问题

二值掩码Dice系数函数正确性验证与结果差异问题

我编写了一个用于计算二值掩码Dice系数的函数,但不确定其正确性:

def dice_metrics(inputs, targets, smooth=1e-8):
    # inputs是预测掩码,targets是原始掩码
    # 展平标签和预测张量
    inputs = inputs.view(-1)
    targets = targets.view(-1)

    intersection = (inputs * targets).sum()
    dice = (2.*intersection + smooth)/(inputs.sum() + targets.sum() + smooth)

    return dice

我原本认为Dice系数应与F1分数相等,但该函数计算结果与sklearn.metrics.f1_score()的F1分数存在差异:当前计算出的Dice系数为0.15,而F1分数为0.04。

相关数据信息:

  • TARGETS:数据类型为torch.float32,最小值tensor(0., device='cuda:0'),最大值tensor(0.9804, device='cuda:0')
  • INPUTS:数据类型为torch.float32,最小值tensor(0., device='cuda:0'),最大值tensor(0.9804, device='cuda:0')
  • 使用sklearn.metrics.f1_score()时,会对输入和目标应用二值阈值并转换为np.uint8类型。

函数正确性验证与差异原因解析

  1. 当前Dice函数的性质
    你的函数计算的是Soft Dice系数,它直接使用连续浮点值的预测和目标张量进行计算,不对数据做二值化处理。这种形式常用于语义分割任务的损失函数,能保留预测值的概率信息,避免二值化带来的梯度消失问题。

  2. 与F1分数差异的核心原因
    sklearn的f1_score()计算的是二分类硬标签下的F1分数,它要求输入是0/1的离散标签——你提到的二值阈值化+转np.uint8就是把连续浮点值转换成了硬二值标签。

二分类场景下,硬Dice系数(基于0/1标签)确实和F1分数等价,但你的函数没有做二值化,计算的是Soft Dice,这和F1的计算逻辑完全不同,结果自然会有差异。

  1. 对齐F1分数的修正方案
    如果要让Dice结果与F1分数一致,需要先对输入和目标做二值化处理,与sklearn的逻辑对齐,修正后的函数如下:
def dice_metrics(inputs, targets, smooth=1e-8, threshold=0.5):
    # 对预测和目标做二值化,对齐sklearn的处理逻辑
    inputs = (inputs > threshold).float().view(-1)
    targets = (targets > threshold).float().view(-1)

    intersection = (inputs * targets).sum()
    dice = (2.*intersection + smooth)/(inputs.sum() + targets.sum() + smooth)

    return dice

使用该函数计算的结果将与sklearn.metrics.f1_score()的输出一致,因为两者都基于硬二值标签计算。

内容的提问来源于stack exchange,提问作者KWKIM128

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:46:13