如何解决nan loss?
Posted
技术标签:
【中文标题】如何解决nan loss?【英文标题】:How to solve nan loss? 【发布时间】:2017-03-02 16:50:36 【问题描述】:问题
我在 MNIST 上运行深度神经网络,其中损失定义如下:
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, label))
该程序似乎运行正常,直到我在 10000+ th minibatch 中出现 nan 损失。有时,程序会正常运行,直到完成。我认为tf.nn.softmax_cross_entropy_with_logits
给了我这个错误。
这很奇怪,因为代码只包含mul
和add
操作。
可能的解决方案
也许我可以使用:
if cost == "nan":
optimizer = an empty optimizer
else:
...
optimizer = real optimizer
但我找不到nan
的类型。如何检查变量是否为nan
?
我还能如何解决这个问题?
【问题讨论】:
检查“tf.add_check_numerics_ops”的实现,将Assert
ops添加到每个张量以确保没有nan,因此您可以使用它用来检查nanness的任何东西
我是 tensorflow 新手,当我使用“tf.add_check_numerics_ops”时,它给我带来了一个错误“tensorflow.python.framework.errors.InvalidArgumentError: All inputs to node model/CheckNumerics_254 must be from the同框。”我用错了吗?
我的意思是您可以查看add_check_numerics_ops
的实现以查看哪个操作确定变量是否为NaN,并使用该操作
Tensorflow Nan loss reasons的可能重复
【参考方案1】:
我在这里发现了类似的问题TensorFlow cross_entropy NaN problem
感谢作者user1111929
tf.nn.softmax_cross_entropy_with_logits => -tf.reduce_sum(y_*tf.log(y_conv))
实际上是一种计算交叉熵的可怕方法。在某些样本中,一段时间后可以确定地排除某些类,导致该样本的 y_conv=0。这通常不是问题,因为您对这些不感兴趣,但是以 cross_entropy 的写入方式,它会为该特定样本/类产生 0*log(0) 。因此是 NaN。
替换为
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv + 1e-10))
或者
cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y_conv,1e-10,1.0)))
解决了 nan 问题。
【讨论】:
【参考方案2】:您得到 NaN 的原因很可能是在您的成本函数或 softmax 中的某个地方,您试图取零的对数,这不是一个数字。但是为了回答您关于检测 NaN 的具体问题,Python 具有在数学模块中测试 NaN 的内置功能。例如:
import math
val = float('nan')
val
if math.isnan(val):
print('Detected NaN')
import pdb; pdb.set_trace() # Break into debugger to look around
【讨论】:
log(0) = -据我所知无限【参考方案3】:检查您的学习率。您的网络越大,需要学习的参数就越多。这意味着您还需要降低学习率。
【讨论】:
【参考方案4】:我没有您的代码或数据。但是tf.nn.softmax_cross_entropy_with_logits
应该是稳定的,具有有效的概率分布(更多信息here)。我假设您的数据不符合此要求。 here 也讨论了一个类似的问题。这会导致您:
实现您自己的softmax_cross_entropy_with_logits
函数,例如试试(source):
epsilon = tf.constant(value=0.00001, shape=shape)
logits = logits + epsilon
softmax = tf.nn.softmax(logits)
cross_entropy = -tf.reduce_sum(labels * tf.log(softmax), reduction_indices=[1])
更新您的数据,使其具有有效的概率分布
【讨论】:
我用的是标准的mnist数据集,我认为它的概率分布是有效的。 为什么将 epsilon 添加到 logits 而不是 softmax?epsilon
被添加到 logits 中,因此得到的 softmax 的总和仍然为 1,但也不能包含零(这些结果为 NaN)。很奇怪,标准 mnist 数据集有这个问题......你能检查一下如果你使用这个新的 cross_entropy
函数会发生什么吗?如果这不起作用,您可能需要查看实际的 logits。
嗨,我刚刚在 SO here 上发现了一个类似的问题,在这种情况下,使用 clipping
调整了 cross_entropy。虽然在这里他从一个非常简单的 cross_entropy 实现开始,而不是 tf.nn.softmax_cross_entropy_with_logits
。顺便说一句,你现在开始工作了吗?以上是关于如何解决nan loss?的主要内容,如果未能解决你的问题,请参考以下文章
机器学习技巧-训练过程中,loss参数出现NAN怎么解决?解决方案汇总?