光滑骰子损失函数如何可微分?

11

我正在使用Keras训练一个U-Net模型,通过最小化dice_loss函数来解决这个问题。这个函数在这个链接(参考自此)(参考自此)中广泛使用。

def dsc(y_true, y_pred):
     smooth = 1.
     y_true_f = K.flatten(y_true)
     y_pred_f = K.flatten(y_pred)
     intersection = K.sum(y_true_f * y_pred_f)
     score = (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)
     return score

def dice_loss(y_true, y_pred):
    return (1 - dsc(y_true, y_pred))

这个实现与传统的Dice Loss不同,因为它有一个平滑项以使其“可微分”。我只是不理解为什么在分母中添加smooth项而不是像1e-7之类的东西会使它更好,因为它实际上改变了损失值。使用训练有素的Unet模型在测试集上进行正常的Dice Loss实现如下所示,我已经通过了检验:

def dice(im1,im2):
     im1 = np.asarray(im1).astype(np.bool)
     im2 = np.asarray(im2).astype(np.bool)
     intersection = np.logical_and(im1, im2)
     return np.float(2. * intersection.sum()) / (im1.sum() + im2.sum() + 1e-7))

有人可以解释一下为什么光滑的骰子损失通常被使用吗?


你为什么相信这个“平滑”术语会使损失函数可微分呢? - zimmerrol
我很确定我在某个地方读到过这个,但可能混淆了概念。 - zucchinifries
“Smooth dice”和“soft dice”是相同的东西吗? - Monica Heddneck
@MonicaHeddneck 我相信是这样的! - zucchinifries
1个回答

14

smooth添加到损失函数中并不会使其可微分,而使其可微分的是:

  1. 放宽对预测值的阈值:您不将 y_pred 转换为 np.bool,而是将其保留为介于 0 和 1 之间的连续 值。
  2. 您不使用集合运算如np.logical_and,而是使用元素逐个乘积来近似不可微分的交集操作。

只有在y_predy_true都不含前景像素时,才需添加smooth以避免除以零。


谢谢!我把所有的东西都搞混了。跟进一下,如果我在训练中使用平滑项=1,那么推断时是否应该使用相同的平滑项=1?我最初使用了一个非常小的值来避免除以零,但是使用平滑项=1而不是1e-7似乎会更好地提高我的结果。 - zucchinifries
我想在推理过程中,您需要报告确切的dice loss而不是平滑的loss。@nababs - Shai
@Shal,你好,关于“放宽阈值”,你的意思是什么?是什么都不做,还是要削减它? - Alex Luya
@AlexLuya 你根本没有进行阈值处理 - 阈值处理是不可微分的。 - Shai
@Shai,谢谢,我知道,只是好奇想知道哪些'放松阈值'是可区分的。 - Alex Luya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接