我正在训练3D U-Net,并尝试使用Tensorflow实现Dice损失。我创建了以下函数,该函数可以返回骰子得分或相应的损失(1-score)
。
def dice_coefficient(_type="score", empty_score = 1.0):
""" Computes Dice
Args:
_type: "score" or "loss"
empty_score: score if union is empty
Returns:
either Dice score or Dice loss (-score)
"""
def dice_score(y_true, y_pred):
# Flatten
y_true_f = K.cast(K.flatten(y_true), y_pred.dtype)
y_pred_f = K.flatten(y_pred)
im_sum = K.sum(y_true_f) + K.sum(y_pred_f)
if im_sum == 0:
return empty_score
im_sum = K.cast(im_sum, tf.float32)
# Compute Dice coefficient
intersection = K.sum(y_true_f * y_pred_f)
intersection = K.cast(intersection, tf.float32)
return 2. * intersection / im_sum
def dice_loss(y_true, y_pred):
return 1-dice_score(y_true, y_pred)
if _type == "score":
return dice_score
elif _type == "loss":
return dice_loss
训练模型时,我会同时设置损失和得分。
model.compile(optimizer=optimizer,
loss=dice_coefficient(_type="loss"),
metrics=dice_coefficient(_type="score"))
但是我得到nan
的损失和分数的数值:如上所述,损失不应该是1-score
吗?
144/Unknown - 68s 473ms/step - loss: nan - dice_score: 0.0209
答案 0 :(得分:0)
我已经实现了骰子损失函数来优化图像分割。您可以查看此路径 https://github.com/charuu/msc-tooth-segmentation/blob/main/modelIO.py 上的代码 代码片段如下
class Dice(Loss):
def call(self, y_true, y_pred):
y_pred = ops.convert_to_tensor_v2(y_pred)
y_true = gen_math_ops.cast(y_true, y_pred.dtype)
y_true = tf.keras.backend.clip(y_true, tf.keras.backend.epsilon(), 1-tf.keras.backend.epsilon())
y_pred = tf.keras.backend.clip(y_pred, tf.keras.backend.epsilon(), 1-tf.keras.backend.epsilon())
intersection = tf.keras.backend.sum(tf.keras.backend.abs(y_true * y_pred), axis=-1)
numerator = (2. * intersection + 1)
denominator = (tf.keras.backend.sum(tf.keras.backend.square(y_true),-1) + tf.keras.backend.sum(tf.keras.backend.square(y_pred),-1) + 1)
return 1 - (numerator/denominator)