这是我的第一篇文章,所以我会尽量详细说明所有相关信息。如果有什么遗漏,请告诉我!
我目前正在尝试为灰度图像的图像分割创建 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 左右。
谁能解释一下这个损失是如何计算的,为什么它与我预期的不符?
我已经阅读了此处的类似帖子,但找不到任何有用的内容。
如果有任何关于下一步要研究的建议或进一步调查的资源,如果这很明显,请告诉我!提前致谢