python - 使用 keras 实现 u-net 时 Jaccard 精度为零

标签 python machine-learning deep-learning keras image-segmentation

我正在尝试将 u-net 与 keras 实现一起使用,我正在使用以下存储库 https://github.com/zhixuhao/unet 它工作得很好,但我的问题是一个二分类分割问题,所以我想将精度指标设置为 jaccard,还有损失函数

我尝试定义函数:

def Jac(y_true, y_pred):
    y_pred_f = K.flatten(K.round(y_pred))
    y_true_f = K.flatten(y_true)
    num = K.sum(y_true_f * y_pred_f)
    den = K.sum(y_true_f) + K.sum(y_pred_f) - num
    return num / den

并在编译中调用它:

model.compile(optimizer = Adam(lr = 1e-4), loss = ['binary_crossentropy'], metrics = [Jac])

当我这样做时,每次迭代中的 jaccard 精度都会降低,直到达到零! 有什么解释为什么会发生吗?
P.S:同样的事情也发生在骰子上。
P.S: 输出层是 conv 1 * 1,带有 sigmoid 激活函数

更新:

附上 keras 中二进制精度的原始实现:

def binary_accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)

我可以看到它还使用舍入来获得输出预测。

最佳答案

您正在对函数进行舍入 (K.round)。

这会导致两个问题:

  • (真正的问题)该函数不可微分,不能作为损失函数(将显示“不支持任何值”错误)
  • 每当您的网络不确定且任何值低于 0.5 时,这些值都将被视为零。

如果 y_true 中黑色(零)像素的数量大于白色(1)像素的数量,则会发生这种情况:

  • 你的网络倾向于首先将所有内容预测为零,这确实会导致更好的二元交叉熵损失!
    • 如果不是四舍五入的话,还有更好的 Jaccard
    • 但是如果四舍五入则为零 Jaccard
  • 只有稍后,当学习率得到更精细的调整时,它才会开始将白色像素带出它们应该在的位置。

出于上述两个原因,您确实应该使用非舍入函数。
有时绘制你的输出来看看发生了什么:)

请注意,如果您将其用作损失函数,请将其乘以 -1(因为您希望它减少,而不是增加)

关于python - 使用 keras 实现 u-net 时 Jaccard 精度为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49296099/

相关文章:

python - TensorFlow:如何合并多个 'collections' ?

tensorflow - 如何使用 tensorflow 执行多标签分类?

python - Python 中的位置倒排索引

python - 对于一个特定列,使用另一个数据帧的数据更新一个数据帧 - Pandas 和 Python

pandas - Numpy np.newaxis

machine-learning - 如何在 Keras 中绘制历元与训练准确性的关系?

Python:过滤列表的最有效方法

python - 返回一个参数绑定(bind)的函数对象?

machine-learning - 何时停止训练 - LOOV MLP

python - 如何在 tf.layers.keras.Conv2D 中初始化常量偏差?