自定义损失函数不等于用于训练模型的损失函数

时间:2021-03-23 03:54:05

标签: python keras tensorflow2.0 loss-function

这是我的第一篇文章,所以我会尽量详细说明所有相关信息。如果有什么遗漏,请告诉我!

我目前正在尝试为灰度图像的图像分割创建 cnn(基于 unet)。

我创建了一个自定义函数来计算骰子损失和二元交叉熵损失,见下文。

def dice_BCE_coef_loss(y_true, y_pred):
    smooth = 1
    bce_weight = 0.5

    #y_true_f = tensorflow.math.reduce_sum(y_true)
    #y_pred_f = tensorflow.math.reduce_sum(y_pred)
    y_true_f = tensorflow.reshape(y_true, [-1])
    y_pred_f = tensorflow.reshape(y_pred, [-1])

    intersection  = tensorflow.math.reduce_sum(y_true_f * y_pred_f)
    union = tensorflow.math.reduce_sum(y_true_f + y_pred_f)
    dice_coef = (2*intersection + smooth) / (union + smooth)
    dice_loss = 1 - dice_coef

    BCE =  tensorflow.keras.losses.BinaryCrossentropy(from_logits=True)(y_true, y_pred)
    dice_BCE = tensorflow.math.reduce_mean(BCE * bce_weight + dice_loss * (1 - bce_weight))
    return dice_BCE

然后我将其作为损失添加到我的模型中。

model.compile(optimizer=tensorflow.keras.optimizers.Adam(lr=1e-3), 
              loss=dice_BCE_coef_loss, 
              metrics=['accuracy']
              )

当我手动计算 dice_BCE 时,问题出现了,损失值与训练期间的输出损失不同。为了确认这是否是整个数据集的正确值(我的手动检查是单个图像),我将数据集缩减为单个图像和掩码,但它们仍然不匹配。

显示损失与我预期的骰子_BCE 损失差异的图像(我希望在这种情况下允许使用图片)1

这个损失在几个 epoch 之后总是保持在 0.48 左右,但是从来没有从那里真正改善过,有时你可以看到输出掩码非常接近(并且很好地预期了 dice_BCE 匹配)但它最终会发散,因为它似乎失去了可以通过其他方式改进训练(但会增加预期的骰子损失)。

骰子损失(通过 epoch 的损失值)也远低于通过函数计算时的损失。即使预测的准确率约为 50% 并且看起来似乎不正确,也能达到 0.001 左右。

谁能解释一下这个损失是如何计算的,为什么它与我预期的不符?

我已经阅读了此处的类似帖子,但找不到任何有用的内容。

如果有任何关于下一步要研究的建议或进一步调查的资源,如果这很明显,请告诉我!提前致谢

0 个答案:

没有答案