来源:知乎用户:炼丹实验室,https://zhuanlan.zhihu.com/p/20792837,https://zhuanlan.zhihu.com/p/24720954
这里对这两篇文章稍作一下整理。
1、训练过程出现NAN的原因
- 除0问题。这里实际上有两种可能,一种是被除数的值是无穷大,即Nan,另一种就是除数的值是0。之前产生的Nan或者0,有可能会被传递下去,造成后面都是Nan。请先检查一下神经网络中有可能会有除法的地方,例如softmax层,再认真的检查一下数据。我有一次帮别人调试代码,甚至还遇到过,训练数据文件中,有些值就是Nan。。。这样读进来以后,开始训练,只要遇到Nan的数据,后面也就Nan了。可以尝试加一些日志,把神经网络的中间结果输出出来,看看哪一步开始出现Nan。
(训练日志生成参考:
./darknet detector train cfg/voc.data cfg/yolov3.cfg darknet53.conv.74 2>1 | tee visualization/train_yolov3.log
) - 梯度过大,造成更新后的值为Nan。特别是RNN,在序列比较长的时候,很容易出现梯度爆炸的问题。一般有以下几个解决办法。
对梯度做clip(梯度裁剪),限制最大梯度,其实是value = sqrt(w12+w22….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15。
减少学习率。初始学习率过大,也有可能造成这个问题。需要注意的是,即使使用adam之类的自适应学习率算法进行训练,也有可能遇到学习率过大问题,而这类算法,一般也有一个学习率的超参,可以把这个参数改的小一些。 - 初始参数值过大,也有可能出现Nan问题。输入和输出的值,最好也做一下归一化。
2、loss/cost降不下来
网络一直在正常的训练,但是loss/