在 Keras 中实现的卷积神经网络的训练过程中,如何修复我的骰子损失计算?

How can I fix my dice loss calculation during the training process of a convolutional neural network implemented in Keras?

我正在使用 keras 实现自己的代码来进行语义分割。我的测试图像具有 (10, 512, 512, 5) 的形状,其中 10 是图像的数量,512 是它们的大小,5 是我要分割的 类 的数量。作为最后一个激活函数,我使用 softmax 作为损失,我想提取骰子损失 (https://arxiv.org/abs/1606.04797) 以改善分割结果。我的代码是:

eps = 1e-3

def dice(y_true, y_pred):
    y_pred = K.one_hot(K.argmax(y_pred,axis=-1), Nclasses) 
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    num = 2*K.sum(y_true_f*y_pred_f)
    den = K.sum(K.square(y_true_f))+K.sum(K.square(y_pred_f))+eps
    return num/den

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

我使用 K.one_hot(K.argmax(...)) 因为这样我的 y_pred 是二元的而不是由概率决定的(对吧?)。 无论如何,当训练过程开始时,我收到这个错误:

"ValueError: An operation has None for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval."

这个post好像说明由于argmax在keras中没有梯度,你将不能在你的自定义损失函数中使用它

尝试将此代码片段用于您的骰子系数。 重要观察:如果您对蒙版进行了单热编码,则此代码也应该适用于多 class 分割。

smooth = 1.

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


def dice_coef_loss(y_true, y_pred):
    return -dice_coef(y_true, y_pred)