训练Nan问题分析

避免训练深度学习网络时候出现Nan的几种方法

问题原因:data有nan的坏数据,clear数据解决。
参考地址:https://www.zhihu.com/question/49346370

梯度爆炸解决办法:
1、数据归一化(减均值、除方差、BN、L2 norm);
2、使用xavier,msra修改参数初始化;
3、减小学习率、减小batch_size;
4、加入gradient_clipping;

学习率太大和网络设计问题解决办法:

说明训练不收敛了学习率太大,步子迈的太大导致梯度爆炸;有可能是网络结构设计的有问题:因为梯度爆炸、lr过大、不收敛原因。

解决办法:
1、 弱化场景,将样本简化,各个学习率等参数采用典型配置,比如10万样本都是同一张复制的,让这个网络去拟合,如果有问题,则是网络的
问题。否则则是各个参数的问题;
2、如果是网络的问题,则通过不断加大样本的复杂度和调整网络(调整拟合能力)来改变;
3、参数的微调,我个人感觉是在网络的拟合能力和样本的复杂度匹配的情况下,就是可以train到一定水平,然后想进行进一步优化的时候采用;
4、参数的微调,楼上说得几个也算是一种思路吧,其他的靠自己去积累,另外将weights可视化也是一个细调起来可以用的方法,现在digits的
tf里面都有相关的工具;

每次固定的迭代次数段都会loss突然变nan导致acc骤降变0。

loss突然变nan的原因training sample中出现了脏数据导致我的logits计算出了0,0传给 log(x|x=0) \rightarrow∞, 即nan;

解决办法:
1、设置batch_size = 1,shuffle = False,一步一步地将sample定位到了所有可能的脏数据删掉;
2、期间删了好几个还依然会loss断层为nan一直定位一直删到 work out;
3、实际业务上的真实数据差导致预处理占据80%的工作量;
4、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:每当梯度达到一定的阈值,就把他们设置回一个小一些的数字。
\frac{\partial E}{\partial W} \rightarrow g
if \left| \left| g \right| \right| \geq threshold then
\frac{threshlod}{\left| \left| g \right| \right| }g\rightarrow g
endif
2、调整学习速率。学习速率过大会导致不能正常收敛,因此可以把学习速率适当调小一些。
3、调整深度神经网络的结构。
To solve the problem of exploding gradients, Thomas Mikolov first introduced a simple heuristic solution that clips gradients
to a small number whenever they explode. That is, whenever they reach a certain threshold, they are set back to a small number
as shown in Algorithm 1. Figure 5 visualizes the effect of gradient clipping. It shows the decision surface of a small recurrent
neural network with respect to its W matrix and its bias terms, b. The model consists of a single unit of recurrent neural network
running through a small number of timesteps; the solid arrows illustrate the training progress on each gradient descent step.
When the gradient descent model hits the high error wall in the objective function, the gradient is pushed off to a far-away location
on the decision surface. The clipping model produces the dashed line where it instead pulls back the error gradient to somewhere close
to the original gradient landscape.

用的是交叉熵cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))的话,最后softmax层输出y_conv的取值范围在[0,1]页就是说允许取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的取值范围,别的框架不清楚。
是不是用了tanh?

相信很多人都遇到过训练一个deep model的过程中,loss突然变成了NaN。在这里对这个问题做一个总结。
一般来说,出现NaN有以下几种情况:
1、如果在迭代的100轮以内,出现NaN一般情况下的原因是因为你的学习率过高,需要降低学习率。
可以不断降低学习率直至不出现NaN为止一般来说低于现有学习率1-10倍即可。
2、如果当前的网络是类似于RNN的循环神经网络出现NaN可能是因为梯度爆炸的原因,一个有效的方式是增加“gradient clipping”(梯度截断来解决)
3、可能用0作为了除数;
4、可能0或者负数作为自然对数

5、需要计算loss的数组越界(尤其是自己,自定义了一个新的网络,可能出现这种情况)

6、在某些涉及指数计算,可能最后算得值为INF(无穷)(比如不做其他处理的softmax中分子分母需要计算exp(x),值过大,最后可能为INF/INF,得到NaN,
此时你要确认你使用的softmax中在计算exp(x)做了相关处理(比如减去最大值等等))

参考:
http://russellsstewart.com/notes/0.html

tensorflow训练中出现nan问题
深度学习中对于网络的训练是参数更新的过程,需要注意一种情况就是输入数据未做归一化时,如果前向传播结果已经是[0,0,0,1,0,0,0,0]这种形式,
而真实结果是[1,0,0,0,0,0,0,0,0],此时由于得出的结论不惧有概率性,而是错误的估计值,此时反向传播会使得权重和偏置值变的无穷大,
导致数据溢出,也就出现了nan的问题。

解决办法:
1、对输入数据进行归一化处理,如将输入的图片数据除以255将其转化成0-1之间的数据;
2、对于层数较多的情况,各层都做batch_nomorlization;
3、对设置Weights权重使用tf.truncated_normal(0, 0.01, [3,3,1,64])生成,同时值的均值为0,方差要小一些;
4、激活函数可以使用tanh;
5、减小学习率lr。
参考博客:http://blog.csdn.net/fireflychh/article/details/73691373

使用caffe训练时Loss变为nan的原因梯度爆炸
原因:梯度变得非常大,使得学习过程难以继续
现象:观察log,注意每一轮迭代后的loss。loss随着每轮迭代越来越大,最终超过了浮点型表示的范围,就变成了NaN。

措施:
1、减小solver.prototxt中的base_lr,至少减小一个数量级。如果有多个loss layer,需要找出哪个损失层导致了梯度爆炸,
并在train_val.prototxt中减小该层的loss_weight,而非是减小通用的base_lr。
2、设置clip gradient,用于限制过大的diff

不当的损失函数
原因:有时候损失层中loss的计算可能导致NaN的出现。比如,给InfogainLoss层(信息熵损失)输入没有归一化的值,使用带有bug的自定义损失层等等。
现象:观测训练产生的log时一开始并不能看到异常,loss也在逐步的降低,但突然之间NaN就出现了。
措施:看看你是否能重现这个错误,在loss layer中加入一些输出以进行调试。

示例:有一次我使用的loss归一化了batch中label错误的次数。如果某个label从未在batch中出现过,loss就会变成NaN。在这种情况下,可以用足够大的batch来尽量避免这个错误。
不当的输入
原因:输入中就含有NaN。
现象:每当学习的过程中碰到这个错误的输入,就会变成NaN。观察log的时候也许不能察觉任何异常,loss逐步的降低,但突然间就变成NaN了。
措施:重整你的数据集,确保训练集和验证集里面没有损坏的图片。调试中你可以使用一个简单的网络来读取输入层,有一个缺省的loss,并过一遍所有输入,如果其中有错误的输入,
这个缺省的层也会产生NaN。
案例:有一次公司需要训练一个模型,把标注好的图片放在了七牛上,拉下来的时候发生了dns劫持,有一张图片被换成了淘宝的购物二维码,且这个二维码格式与原图的格式不符合
因此成为了一张“损坏”图片。每次训练遇到这个图片的时候就会产生NaN。良好的习惯是,你有一个检测性的网络,每次训练目标网络之前把所有的样本在这个检测性的网络里面过一遍,去掉非法值。

池化层中步长比核的尺寸大
如下例所示,当池化层中stride > kernel的时候会在y中产生NaN
layer {
name: “faulty_pooling”
type: “Pooling”
bottom: “x”
top: “y”
pooling_param {
pool: AVE
stride: 5
kernel: 3
}
}
参考地址:http://stackoverflow.com/questions/33962226/common-causes-of-NaNs-during-training
参考地址:http://blog.csdn.net/huangynn/article/details/52947894

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MATLAB中,NAN(Not a Number)是一种特殊的值,表示无效或未定义的数值。NAN通常出现在计算过程中,例如分母为0的情况,或者当将字符串作为数值导入时。在处理NAN时,可以使用isnan函数来检查矩阵中的NAN值。这个函数可以用于每个可能出现NAN的地方进行测试。另外,在处理大量矩阵数据时,为了保持矩阵的规则性,MATLAB会使用NAN来表示非数字字符。为了提高矩阵运算效率,需要对NAN进行处理。对于一维矩阵,可以使用一些处理方法来处理NAN值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Matlab出现NaN错误](https://blog.csdn.net/jzwong/article/details/78943575)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【Matlab技巧——矩阵运算、Nan字符处理】](https://blog.csdn.net/weixin_43347280/article/details/124852047)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [NaN是什么,怎么处理 --matlab](https://blog.csdn.net/qq_46118539/article/details/109788612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值