训练深度学习网络时候,出现Nan是啥原因,咋才能避免( 二 )


■网友
说明训练不收敛了, 学习率太大,步子迈的太大导致梯度爆炸等都是有可能的,另外也有可能是网络的问题,网络结构设计的有问题。我现在的采用方式是: 1. 弱化场景,将你的样本简化,各个学习率等参数采用典型配置,比如10万样本都是同一张复制的,让这个网络去拟合,如果有问题,则是网络的问题。否则则是各个参数的问题。 2. 如果是网络的问题,则通过不断加大样本的复杂度和调整网络(调整拟合能力)来改变。 3. 参数的微调,我个人感觉是在网络的拟合能力和样本的复杂度匹配的情况下,就是可以train到一定水平,然后想进行进一步优化的时候采用。 4. 参数的微调,楼上说得几个也算是一种思路吧,其他的靠自己去积累,另外将weights可视化也是一个细调起来可以用的方法,现在digits tf里面都有相关的工具.
■网友
用的是交叉熵cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))的话,最后softmax层输出y_conv的取值范围在页就是说允许取0值,有log(0)出现很有可能出现nan啊,cross_entropy = -tf.reduce_mean(y_*tf.log(tf.clip_by_value(y_conv,1e-15,1.0)))在tensorflow里可以限定一下y_conv的取值范围,别的框架不清楚。

■网友
对于我的case, 试了所有别的方法后都不管用 也是果然在检测输入数据的时候发现某几十万行那里发现了一行NAN,所以说第一步先检测输入数据里有没有NAN,然后再试别的方法。

■网友
跑飞了吧,数据太大了,已经超过了规定的极限--------------------------------------------------我是分割线--------------------------------loss出现Nan,说明你的loss已经发散了。下面是一点个人经验,无理论指导,欢迎板砖。解决办法:1、减小整体学习率。学习率比较大的时候,参数可能over shoot了,结果就是找不到极小值点。减小学习率可以让参数朝着极值点前进。2、改变网络宽度。有可能是网络后面的层参数更新异常,增加后面层的宽度试试。3、增加网络层数。4、改变层的学习率。每个层都可以设置学习率,可以尝试减小后面层的学习率试试。
■网友
最近在训练强化学习网络时碰到过loss为nan的情况,注意用tensorflow做softmax得到nan后不会报错,可以把结果输出来观察。
训练的是a3c网络,因为程序与环境交互比较慢,就先用传统算法得到标签,然后用监督学习训练策略网络,得到比较好的初值以加速训练。加载训练好的策略网络跑强化学习不久就出现了nan,折腾了好久最后解决了,总结有这么几点:
policy loss为交叉熵,因此需要对policy做clip,同时对梯度设置了上限40,避免梯度爆炸;关于数据的处理,楼上说要避免脏数据,还有做Batch Normalization。这个其实在刚开始就用了,因为一开始策略网络总是输出一个特定的action,想了下应该是state里有时间序列,这个值一直增大使得网络越趋向于输出那个特定的action。做了BN后,这种情况立刻就消失了,当网络训练不下去时BN确实是利器;减小学习率。网络出现nan后一直减小学习率到1e-7后就消失了;改进网络。监督学习中学习率为1e-4就很小了,而这里直到1e-7才不会出现nan,并且监督学习已经得到了比较合理的权重值,而强化学习训练不久就出现了nan,说明网络结构不合理,过于简单。因为state用的是序列数据,我加了几层1D-CNN,重新监督学习训练策略网络,加载权重后跑强化学习,loss开始下降,再也没有出现过nan。训练深度学习网络时候,出现Nan是啥原因,咋才能避免

最后再说一点,很多时候出现比较奇怪的结果要再检查检查程序逻辑,比如state和label是否对应。我有段时间训练a3c网络loss一直不降,最后发现犯了一个很低级的错误,a3c中为了使得训练稳定,通常设置一个global network来做梯度的更新,而其他local network负责与环境交互收集数据,得到梯度。而在一个episode开始之前local network从global network中得到最新权重,跑这个episode时与global network没有交互,哪怕其他线程的local network得到了梯度并更新了global network。这样可以保证训练的稳定性,有点像DQN中的target network。而我把这两个的顺序写反了,也就是其实权重根本就没有更新过,也就不奇怪loss一直震荡,维持在一个基本值附近。


推荐阅读