tensorflow出现LossTensor is inf or nan : Tensor had Inf values

之前在TensorFlow中实现不同的神经网络,作为新手,发现经常会出现计算的loss中,出现Nan值的情况,总的来说,TensorFlow中出现Nan值的情况有两种,一种是在loss中计算后得到了Nan值,另一种是在更新网络权重等等数据的时候出现了Nan值,本文接下来,首先解决计算loss中得到Nan值的问题,随后介绍更新网络时,出现Nan值的情况。

Loss计算中出现Nan 

     在搜索以后,找到StackOverflow上找到大致的一个解决办法(https://stackoverflow.com/questions/33712178/tensorflow-nan-bug)(https://stackoverflow.com/questions/49103830/ctc-losstensor-is-inf-or-nan-tensor-had-inf-values),大致的解决办法就是,在出现Nan值的loss中一般是使用的TensorFlow的log函数,然后计算得到的Nan,一般是输入的值中出现了负数值或者0值,在TensorFlow的官网上的教程中,使用其调试器调试Nan值的出现,也是查到了计算log的传参为0;而解决的办法也很简单,假设传参给log的参数为y,那么在调用log前,进行一次数值剪切,修改调用如下:

loss = tf.log(tf.clip_by_value(y,1e-8,1.0))

这样,y的最小值为0的情况就被替换成了一个极小值,1e-8,这样就不会出现Nan值了,StackOverflow上也给出了相同的解决方案。于是,我就采用了上述的解决方案对于log的参数进行数值限制,但是我更加复杂化了这个限制。

tf.clip_by_value这个函数,是将第一个参数,限制在第二、三个参数指定的范围之内,使用这个函数的原意是要避免0值,并没有限制最大值,因而我将限制的调用修改如下:

loss = tf.log(tf.clip_by_value(y,1e-8,tf.reduce_max(y)))

这样就确保了对于y值的剪切,不会影响到其数值的上限。但是在实际的神经网络中使用的时候,我发现这样修改后,虽然loss的数值一直在变化,可是优化后的结果几乎是保持不变的,这就存在问题了。

经过检查,其实并不能这么简单的为了持续训练,而修改计算损失函数时的输入值。这样修改后,loss的数值很可能(存在0的话确定就是)假的数值,会对优化器优化的过程造成一定的影响,导致优化器并不能正常的工作。

要解决这个假的loss的方法很简单,就是人为的改造神经网络,来控制输出的结果,不会存在0。这就需要设计好最后一层输出层的激活函数,每个激活函数都是存在值域的,详情请见博客http://www.jianshu.com/p/ffd3e63f39ef,比如要给一个在(0,1)之间的输出(不包含0),那么显然sigmoid是最好的选择。不过需要注意的是,在TensorFlow中,tf.nn.sigmoid函数,在输出的参数非常大,或者非常小的情况下,会给出边界值1或者0的输出,这就意味着,改造神经网络的过程,并不只是最后一层输出层的激活函数,你必须确保自己大致知道每一层的输出的一个范围,这样才能彻底的解决Nan值的出现。

举例说明就是TensorFlow的官网给的教程,其输出层使用的是softmax激活函数,其数值在[0,1],这在设计的时候,基本就确定了会出现Nan值的情况,只是发生的时间罢了。

更新网络时出现Nan

更新网络中出现Nan值很难发现,但是一般调试程序的时候,会用summary去观测权重等网络中的值的更新,因而,此时出现Nan值的话,会报错类似如下:

InvalidArgumentError (see above for traceback): Nan in summary histogram for: weight_1

这样的情况,一般是由于优化器的学习率设置不当导致的,而且一般是学习率设置过高导致的,因而此时可以尝试使用更小的学习率进行训练来解决这样的问题。

 

 

最近用Tensorflow训练网络,在增加层数和节点之后,出现loss = NAN的情况,在网上搜寻了很多答案,最终解决了问题,在这里汇总一下。

  • 数据本身,是否存在Nan,可以用numpy.any(numpy.isnan(x))检查一下input和target
  • 在训练的时候,整个网络随机初始化,很容易出现Nan,这时候需要把学习率调小,可以尝试0.1,0.01,0.001,直到不出现Nan为止,如果一直都有,那可能是网络实现问题。学习率和网络的层数一般成反比,层数越多,学习率通常要减小。有时候可以先用较小的学习率训练5000或以上次迭代,得到参数输出,手动kill掉训练,用前面的参数fine tune,这时候可以加大学习率,能更快收敛哦
  • 如果是图片,那么得转化为float 也就是/255.
  • relu和softmax两层不要连着用,最好将relu改成tanh,什么原因呢
  • 参数初始化
  • batch size 选择过小
  • 最后还没有排除问题的话,TensorFlow有专门的内置调试器(tfdbg)来帮助调试此类问题
    tensorflow.org/programmers_guide/debugger
from tensorflow.python import debug as tf_debug
<meta charset="utf-8">

# 建立原来的Session

sess = tf.Session()

# 用tfdbg的Wrapper包裹原来的Session对象:

sess = tf_debug.LocalCLIDebugWrapperSession(sess)

sess.add_tensor_filter("has_inf_or_nan", tf_debug.has_inf_or_nan)

# 以上为所有需要的代码变动,其余的代码可以保留不变,因为包裹有的sess和原来的界面一致。

# 但是每次执行`sess.run`的时候,自动进入调试器命令行环境。

sess.run(train_op, feed_dict=...)
在tfdbg命令行环境里面,输入如下命令,可以让程序执行到inf或nan第一次出现。
tfdbg> run -f has_inf_or_nan

一旦inf/nan出现,界面现实所有包含此类病态数值的张量,按照时间排序。所以第一个就最有可能是最先出现inf/nan的节点。可以用node_info, list_inputs等命令进一步查看节点的类型和输入,来发现问题的缘由。

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个警告是指在输入张量中发现了 NaNInfNaN 表示不是数字(Not a Number),Inf 表示无穷大(Infinity)。在机器学习和深度学习中,这通常表示模型训练过程中出现了问题,例如数值溢出或未处理的缺失值。为了确保模型的正确性,需要对输入数据进行检查并解决这个问题。 ### 回答2: 在机器学习或深度学习模型的训练过程中,我们通常会将大量的数据输入到模型中进行学习。然而,由于训练数据的质量的问题或者数据处理的问题等,我们有时会在数据中发现一些不合理的值,例如“NaN”或“Inf”。当出现这些问题时,我们通常会从模型的输出信息或者训练过程的日志中看到这样的警告信息:“Warning: root: NaN or Inf found in input tensor.”。这个警告信息告诉我们在输入张量中存在NaNInf。 首先,NaN代表不是一个数,通常出现在无穷大的运算中,例如0/0。Inf代表正无穷或负无穷,通常出现在除以0的运算中。当我们在处理数据时,如果一个输入张量包含NaNInf,模型的输出结果很可能是不可靠的。 发现这种问题时,我们应该尽快查找原因以及修复这个问题。通常找到这个问题的方法包括: 1. 检查数据源:首先我们应该检查我们的输入数据是否正确。如果数据源出现了问题,像数据文件损坏或数据采集出现漏洞,将大大影响整个模型的训练。 2. 检查数据预处理过程:我们的数据可能需要在输入到模型之前进行预处理,这可能就是数据出现问题的地方。例如,我们可能会对某些数据进行标准化处理,但是如果我们在标准化过程中出现了0作为除数的情况,就会出现Inf。 3. 检查模型的架构和参数:如果实际数据值本身不可能包含NaNInf,则问题可能出现在模型架构、参数或模型的实现中。 所以,当我们在训练模型时看到这个警告信息时,我们需要仔细检查我们的数据集,确保数据质量没有问题,并且要检查模型的架构和参数是否存在问题。正确的解决方法将有助于我们的模型在训练过程中更快地走向成功。 ### 回答3: 这个警告是在深度学习模型中出现的常见问题。它表示在输入张量中出现NaN(非数)或Inf(无穷大)的值。它可能是由于训练数据中存在错误或缺失值等问题导致的。 在深度学习中,NaNInf值会影响计算结果,因为它们可能会在模型中传播,导致输出结果不稳定。这可能导致训练不收敛或模型在测试时产生错误的结果。 为了解决这个问题,我们可以检查输入数据中是否存在缺失值或无效值,并进行必要的数据清理和预处理。我们还可以使用数据填充或删除缺失值的方法,避免NaNInf值的出现。 此外,我们可以通过添加激活函数,正则化或减少学习率等技术来防止模型中出现NaNInf值。此外,我们可以添加断言或assert语句来检查模型是否输出了异常值。这样可以帮助我们及时发现问题并解决它们。 最后,我们应该认真处理这个警告并采取必要的措施来确保我们的深度学习模型可以正常运行,并产生准确可靠的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值