我正在通过最小化普遍用于此问题的dice_loss
函数在keras中训练U-Net:adapted from here和here
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))
此实现与traditional dice loss有所不同,因为它具有使它“可区分”的平滑术语。我只是不明白在分母中添加
smooth
项而不是类似1e-7
的词如何使它更好,因为它实际上会改变损耗值。我通过在具有常规dice
实现的测试集上使用经过训练的unet模型进行了检查,如下所示: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))
有人可以解释为什么通常使用平滑骰子损失吗?
最佳答案
在损失中加上smooth
并不能区分。使它与众不同的是
1.放宽预测的阈值:您不将y_pred
强制转换为np.bool
,而是将其保留为0到1之间的连续值
2.您不要将set运算用作np.logical_and
,而是使用逐元素乘积来近似不可微分的交集运算。
仅当smooth
和y_pred
不包含任何前景像素时,才添加y_true
以避免被零除。