我刚刚在 keras 中实现了广义骰子损失(骰子损失的多类版本),如ref中所述:
(我的目标定义为:(batch_size,image_dim1,image_dim2,image_dim3,nb_of_classes))
def generalized_dice_loss_w(y_true, y_pred):
# Compute weights: "the contribution of each label is corrected by the inverse of its volume"
Ncl = y_pred.shape[-1]
w = np.zeros((Ncl,))
for l in range(0,Ncl): w[l] = np.sum( np.asarray(y_true[:,:,:,:,l]==1,np.int8) )
w = 1/(w**2+0.00001)
# Compute gen dice coef:
numerator = y_true*y_pred
numerator = w*K.sum(numerator,(0,1,2,3))
numerator = K.sum(numerator)
denominator = y_true+y_pred
denominator = w*K.sum(denominator,(0,1,2,3))
denominator = K.sum(denominator)
gen_dice_coef = numerator/denominator
return 1-2*gen_dice_coef
但一定有什么不对劲。我正在处理必须为 4 个类(1 个背景类和 3 个对象类,我有一个不平衡的数据集)分割的 3D 图像。第一件奇怪的事情:虽然我的训练损失和准确性在训练期间有所提高(并且收敛速度非常快),但我的验证损失/准确性是恒定的低谷时期(见图)。其次,在对测试数据进行预测时,只预测背景类:我得到一个恒定的体积。
我使用了完全相同的数据和脚本,但使用了分类交叉熵损失并获得了合理的结果(对象类被分段)。这意味着我的实现有问题。知道它可能是什么吗?
另外,我相信 keras 社区有一个通用的 dice loss 实现会很有用,因为它似乎被用于大多数最近的语义分割任务(至少在医学图像社区)。
PS:对我来说权重是如何定义的似乎很奇怪;我得到大约 10^-10 的值。还有其他人尝试过实现这一点吗?我还测试了没有权重的函数,但遇到了同样的问题。