深度学习网络调试技巧
https://zhuanlan.zhihu.com/p/20792837
转载请注明:炼丹实验室
神经网络的代码,比一般的代码要难调试不少,和编译错误以及运行时程序崩溃相比,神经网络比较棘手的地方,往往在于程序运行正常,但是结果无法收敛,这个检查起来可要麻烦多了。下面是根据我平时调试神经网络的经验,总结的一些比较通用的调试技巧,后续会再写一篇文章,专门介绍一下theano如何进行调试,希望能对大家调试神经网络有所帮助。
遇到Nan怎么办?
Nan问题,我相信大部分人都遇到过,一般可能是下面几个原因造成的:
- 除0问题。这里实际上有两种可能,一种是被除数的值是无穷大,即Nan,另一种就是除数的值是0。之前产生的Nan或者0,有可能会被传递下去,造成后面都是Nan。请先检查一下神经网络中有可能会有除法的地方,例如softmax层,再认真的检查一下数据。我有一次帮别人调试代码,甚至还遇到过,训练数据文件中,有些值就是Nan。。。这样读进来以后,开始训练,只要遇到Nan的数据,后面也就Nan了。可以尝试加一些日志,把神经网络的中间结果输出出来,看看哪一步开始出现Nan。后面会介绍Theano的处理办法。
- 梯度过大,造成更新后的值为Nan。特别是RNN,在序列比较长的时候,很容易出现梯度爆炸的问题。一般有以下几个解决办法。
- 对梯度做clip(梯度裁剪),限制最大梯度,其实是value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15。
- 减少学习率。初始学习率过大,也有可能造成这个问题。需要注意的是,即使使用adam之类的自适应学习率算法进行训练,也有可能遇到学习率过大问题,而这类算法,一般也有一个学习率的超参,可以把这个参数改的小一些。
- 初始参数值过大,也有可能出现Nan问题。输入和输出的值,最好也做一下归一化。具体方法可以参考我之前的一篇文章:深度学习个人炼丹心得 - 炼丹实验室 - 知乎专栏
神经网络学不出东西怎么办?
可能我们并没有遇到,或者解决了Nan等问题,网络一直在正常的训练,但是cost降不下来,预测的时候,结果不正常。
- 请打印出训练集的cost值和测试集上cost值的变化趋势,正常情况应该是训练集的cost值不断下降,最后趋于平缓,或者小范围震荡,测试集的cost值先下降,然后开始震荡或者慢慢上升。如果训练集cost值不下降,有可能是代码有bug,有可能是数据有问题(本身有问题,数据处理有问题等等),有可能是超参(网络大小,层数,学习率等)设置的不合理。
请人工构造10条数据,用神经网络反复训练,看看cost是否下降,如果还不下降,那么可能网络的代码有bug,需要认真检查了。如果cost值下降,在这10条数据上做预测,看看结果是不是符合预期。那么很大可能网络本身是正常的。那么可以试着检查一下超参和数据是不是有问题。 - 如果神经网络代码,全部是自己实现的,那么强烈建议做梯度检查。确保梯度计算没有错误。
- 先从最简单的网络开始实验,不要仅仅看cost值,还要看一看神经网络的预测输出是什么样子,确保能跑出预期结果。例如做语言模型实验的时候,先用一层RNN,如果一层RNN正常,再尝试LSTM,再进一步尝试多层LSTM。
- 如果可能的话,可以输入一条指定数据,然后自己计算出每一步正确的输出结果,再检查一下神经网络每一步的结果,是不是一样的。