我正在使用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."
答案 0 :(得分:1)
尝试使用此代码段作为骰子系数。 重要注意事项:如果您的蒙版已进行一次热编码,则此代码也应适用于多类分割。
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)
答案 1 :(得分:0)
此post似乎表明,由于argmax
在keras中没有渐变,因此您将无法在自定义损失函数中使用它。