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

最近做了一组实验,每次在固定的迭代次数段,都会loss突然变nan,导致acc骤降,慢慢变0。
于是找啊找啊找bug……
很难受,在意志力的坚持下,找到海枯石烂终于知道了!
loss突然变nan的原因,很可惜并不是这里其他所有答主所说的“因为梯度爆炸”、“lr过大”、“不收敛”等等原因,而是因为training sample中出现了脏数据!
脏数据的出现导致我的logits计算出了0,0传给 【训练深度学习网络时候,出现Nan是啥原因,咋才能避免】 训练深度学习网络时候,出现Nan是啥原因,咋才能避免
即nan。
所以我通过设置batch_size = 1,shuffle = False,一步一步地将sample定位到了所有可能的脏数据,删掉。期间,删了好几个还依然会loss断崖为nan,不甘心,一直定位一直删。终于tm work out!
之所以会这样,是因为我的实验是实际业务上的真实数据,有实际经验的就知道的,现实的数据非常之脏,基本上数据预处理占据我80%的精力。
好怀念以前可以天真快乐的在open dataset上做task跑模型的时候,真是啥都不用管,专注模型算法……

■网友
在训练深度神经网络的时候,出现NaN比较大的可能是因为学习速率过大,梯度值过大,产生梯度爆炸。 During experimentation, once the gradient value grows extremely large, it causes an overflow (i.e. NaN) which is easily detectable at runtime; this issue is called the Gradient Explosion Problem.参考斯坦福CS 224D的lecture note,我们也可以找到一些解决方法:1. 加入Gradient clipping:每当梯度达到一定的阈值,就把他们设置回一个小一些的数字。训练深度学习网络时候,出现Nan是啥原因,咋才能避免
训练深度学习网络时候,出现Nan是啥原因,咋才能避免
训练深度学习网络时候,出现Nan是啥原因,咋才能避免
训练深度学习网络时候,出现Nan是啥原因,咋才能避免
训练深度学习网络时候,出现Nan是啥原因,咋才能避免
训练深度学习网络时候,出现Nan是啥原因,咋才能避免
2. 调整学习速率。学习速率过大会导致不能正常收敛,因此可以把学习速率适当调小一些。3. 调整深度神经网络的结构。To solve the problem of exploding gradients, Thomas Mikolov firstintroduced a simple heuristic solution that clips gradients to a smallnumber whenever they explode. That is, whenever they reach a certainthreshold, they are set back to a small number as shown in Algorithm1. Figure 5 visualizes the effect of gradient clipping. It shows the decisionsurface of a small recurrent neural network with respect to itsW matrix and its bias terms, b. The model consists of a single unitof recurrent neural network running through a small number of timesteps;the solid arrows illustrate the training progress on each gradientdescent step. When the gradient descent model hits the high error wallin the objective function, the gradient is pushed off to a far-away locationon the decision surface. The clipping model produces the dashedline where it instead pulls back the error gradient to somewhere closeto the original gradient landscape.
■网友
梯度爆炸了吧。我的解决办法一般以下几条:1、数据归一化(减均值,除方差,或者加入normalization,例如BN、L2 norm等);2、更换参数初始化方法(对于CNN,一般用xavier或者msra的初始化方法);3、减小学习率、减小batch size;4、加入gradient clipping;


推荐阅读