【问题标题】:Why is K.log value giving me nan in keras为什么 K.log 值在 keras 中给了我 nan
【发布时间】:2019-11-06 03:24:13
【问题描述】:

我正在编写一个自定义损失函数,我想取 1 - 计算值的对数。我在 keras 中使用 tensorflow 后端编写如下:

nonlabels = list(np.where(predictions<threshold)[1])
loss_fg_nT = 0
probs_nT = tf.gather(probs_fg,nonlabels,axis=3)
for i in range(len(nonlabels)):
    probs_temp = tf.reshape(probs_nT[:,:,:,i],[-1])
    prob_max = tf.math.reduce_max(probs_temp)
    const = tf.constant(0.000001)
    prob_max = tf.math.add(prob_max,const)
    #prob_max = tf.math.subtract(tf.constant(1.0),prob_max)
    val = K.log(prob_max)
    loss_fg_nT -= val
    loss_fg_nT = loss_fg_nT/(len(nonlabels)+0.000001)

如果我删除 prob_max = tf.math.subtract(tf.constant(1.0),prob_max) 行,该函数工作正常,但是当我记录 (1-prob_max) 值时,它给出了 nan 值。我无法理解这背后的原因,因为我添加了一个标称值以避免同时使用log 0。有人可以帮我纠正这个错误。

【问题讨论】:

  • 对于prob_max 的哪个值,K.log 会产生 nans?您可以通过try-except 块查找;还可以考虑使用K.epsilon() 而不是0.00..1,确保所有reduce_max 输出都是正数,并尝试使用tf.math.log 而不是K.log
  • 它为每个值提供nan。我使用K.epsilon() 并且也使用tf.math.abs(probs_max) 只是为了避免负值并使用tf.math.log。但我仍然面临同样的问题。这太奇怪了!
  • 是的,这很奇怪——太奇怪了;可能的安装问题。在去那里之前,print(K.get_value(K.log(tf.constant(0.9))) 的输出是什么?如果nan,请告诉我,这是一个损坏的安装,我可以建议步骤。最后,您从哪里导入您的keras.backend?确保它与其他导入一致,并且它不是 tf.python.keras
  • @OverLordGoldDragon,print(K.get_value(K.log(tf.constant(0.9))),这给了我适当的价值,而不是nan。我将 keras 后端导入为keras.backend
  • 我会发现this script 的输出很有帮助;您可以将其粘贴为 pastebin

标签: python tensorflow keras deep-learning conv-neural-network


【解决方案1】:

您收到 nan 错误,因为您的 K.log() 为负值。此外,如果您将 K.log() 设为零值,则会出现 inf 错误。我附上一张图片来证明

我也附上我以前调试的代码,希望对你以后可以手动调试有帮助

编码愉快!

【讨论】:

  • 但即使我做了tf.math.abs(probs_max),我也会遇到同样的错误。这确保我总是有一个积极的价值,对吧?如果我错了,请纠正我。
  • 是的,使用 tf.math.abs() 使值变为正值,我在最后一步中的“attach_2”也变成了 ~13,8023 而不是 NaN,请尝试像我一样为 prob_max 使用替代名称确实,我曾经出错,因为我保留了prob_max的同名,所以我改为prob_max_1,prob_max_2,prob_max_3,请确保prob_max的维度正确(1,)并且范围为(0-1)跨度>
  • prob_max 的值肯定在 0 和 1 之间,因为我使用了 softmax 函数来获取概率。重命名变量后我仍然遇到问题。
  • 能否打印出这一行的值 prob_max = tf.math.reduce_max(probs_temp)
  • 你可以使用tf.Session()作为sess,然后打印(prob_max, feed_dict={probs_temp: probs_temp}),注意检查没有其他名为prob_max的变量,可能会打印最后一个改为名为 prob_max 的变量
【解决方案2】:

K.log() 的输入太小。所以,防止prob_max变得如此之小:

prob_max = K.clip(prob_max, 1e-36, 1e36)
val = K.log(prob_max)

我的实验:1e-36 很好,但是1e-40 太小了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 2019-09-06
    • 2022-06-12
    • 2018-11-08
    • 2012-06-27
    相关资源
    最近更新 更多