【问题标题】:Keras Custom Binary Cross Entropy Loss Function. Get NaN as output for lossKeras 自定义二进制交叉熵损失函数。获取 NaN 作为 loss 的输出
【发布时间】:2018-08-03 16:51:04
【问题描述】:

我尝试编写自定义二元交叉熵损失函数。 这是我的脚本:

def my_custom_loss(y_true,y_pred):
    t_loss = (-1)*(y_true * K.log(y_pred) + (1 - y_true) * K.log(1 - y_pred))
    return K.mean(t_loss)

当我使用这个损失函数运行我的脚本时,经过几次迭代,我得到 NaN 作为损失函数的输出。

然后我查看了TensorFlow文档,将损失函数修改为如下:

 t_loss = K.max(y_pred,0)-y_pred * y_true + K.log(1+K.exp((-1)*K.abs(y_pred)))

代码运行没有任何问题。 我想知道是否有人可以解释为什么我的第一个损失函数会给出 NaN 输出。

二进制交叉熵:y * log(p) + (1-y) * log(1-p)

我有 sigmoid 函数作为我最后一层的激活。 所以'p'的值应该在0到1之间。这个范围应该存在日志。

谢谢。

【问题讨论】:

    标签: python keras loss-function


    【解决方案1】:

    二元交叉熵的简单实现会在输出为 0 或大于输出时遇到数值问题,例如log(0) -> NaN。您发布的公式被重新制定为ensure stability and avoid underflow。以下推论来自tf.nn.sigmoid_cross_entropy_with_logits

    z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))
    = z * -log(1 / (1 + exp(-x))) + (1 - z) * -log(exp(-x) / (1 + exp(-x)))
    = z * log(1 + exp(-x)) + (1 - z) * (-log(exp(-x)) + log(1 + exp(-x)))
    = z * log(1 + exp(-x)) + (1 - z) * (x + log(1 + exp(-x))
    = (1 - z) * x + log(1 + exp(-x))
    = x - x * z + log(1 + exp(-x))
    

    对于 x

    x - x * z + log(1 + exp(-x))
    = log(exp(x)) - x * z + log(1 + exp(-x))
    = - x * z + log(1 + exp(x))
    

    并且实现使用等价形式:

    max(x, 0) - x * z + log(1 + exp(-abs(x)))
    

    【讨论】:

      猜你喜欢
      • 2020-07-08
      • 2019-07-28
      • 2021-01-20
      • 2017-06-26
      • 2019-11-02
      • 2021-02-28
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      相关资源
      最近更新 更多