神经⽹络出现nan原因?以及解决
之前在TensorFlow中实现不同的神经⽹络,作为新⼿,发现经常会出现计算的loss中,出现Nan值的情况,总的来
说,TensorFlow中出现Nan值的情况有两种,⼀种是在loss中计算后得到了Nan值,另⼀种是在更新⽹络权重等等数据的时候出现了Nan值,本⽂接下来,⾸先解决计算loss中得到Nan值的问题,随后介绍更新⽹络时,出现Nan值的情况。Loss计算中出现Nan值
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的话确定就是)假的数值,会对优化器优化的过程造成⼀定的影响,导致优化器并不能正常的⼯作。
举例说明就是TensorFlow的官⽹给的教程,其输出层使⽤的是softmax激活函数,其数值在[0,1],这在设计的时候,基本就确定了会出现Nan值的情况,只是发⽣的时间罢了。更新⽹络时出现Nan值
更新⽹络中出现Nan值很难发现,但是⼀般调试程序的时候,会⽤summary去观测权重等⽹络中的值的更新,因⽽,此时出现Nan值的话,会报错类似如下:
InvalidArgumentError (see above for traceback): Nan in summary histogram for: weight_1
这样的情况,⼀般是由于优化器的学习率设置不当导致的,⽽且⼀般是学习率设置过⾼导致的,因⽽此时可以尝试使⽤更⼩的学习率进⾏训练来解决这样的问题。
提供⼀个⼩⼩的debug经验,其实是我之前遇到的很傻的坑,可能不能解决题主的问题。
log(0)log(0) * 0
当⽹络训练到达⼀定程度的时候,模型对分类的判断可能会产⽣0这样的数值,log(0)本⾝是没有问题的,-inf可以安全的参与绝⼤部分运算,除了(-inf * 0),会产⽣NaN。NaN的话,⼀旦参与reduce运算会让结果完蛋的… 因此呢,如果有
y_truth * log(y_predict)
# when y_truth[i] is 0, it is likely that y_predict[i] would be 0
这样的表达式,要考虑对log中的变量进⾏clip. ⽐如
safe_log = tf.clip_by_value(some_tensor, 1e-10, 1e100)bin_tensor * tf.log(safe_log)
这种错误实在有点傻,不过坑了我好⼏个⼩时。并且呢,这样的错误⼗分肯定会造成断崖式下跌。 希望对题主有所帮助。(不然就当做我的⼀次笔记吧~)
当然除了log函数之外,exp也是产⽣NaN的⼤户,也要多加防范。