我尝试写一个自定义的二进制交叉熵损失函数。 这是我的脚本:
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 *日志(P)+(1-γ)*日志(1-p)的
我有双曲线函数作为激活我的最后一层。 这样的“p”的值应该为0和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 <0,以避免在EXP溢出(-x),我们重新配制上述
x - x * z + log(1 + exp(-x))
= log(exp(x)) - x * z + log(1 + exp(-x))
= - x * z + log(1 + exp(x))
而执行使用equivalient形式:
max(x, 0) - x * z + log(1 + exp(-abs(x)))
文章来源: Keras Custom Binary Cross Entropy Loss Function. Get NaN as output for loss