深度学习网络训练,Loss出现Nan的解决办法

文章目录


前言

模型的训练不是单纯的调参,重要的是能针对出现的各种问题提出正确的解决方案。本文就训练网络loss出现Nan的原因做了具体分析,并给出了详细的解决方案,希望对大家训练模型有所帮助。


一、原因

一般来说,出现NaN有以下几种情况:

  1. 如果在迭代的100轮数以内,出现NaN,一般情况下的原因是你的学习率过高,需要降低学习率。可以不断降低学习率直至不出现NaN为止,一般来说低于现有学习率1-10倍即可。
  2. 如果当前的网络是类似于RNN的循环神经网络的话,出现NaN可能是因为梯度爆炸的原因,一个有效的方式是增加“gradient clipping”(梯度截断来解决)。
  3. 可能用0作了除数。
  4. 可能用0或者负数作为自然对数。
  5. 需要计算loss的数组越界(尤其是自己定义了一个新的网络,可能出现这种情况)。
  6. 在某些涉及指数计算,可能最后算得值为INF(无穷)(比如不做其他处理的softmax中分子分母需要计算ex(x),值过大,最后可能为INF/INF,得到NaN,此时你要确认你使用的softmax中在计算exp(x) 做了相关处理(比如减去最大值等等))。
  7. 训练深度网络的时候,label缺失问题也会导致loss一直是nan,需要检查label。

二、典型实例

1. 梯度爆炸

原因:梯度变得非常大,使得学习过程难以继续。

现象:观察log,注意每一轮迭代后的loss。loss随着每轮迭代越来越大,最终超过了浮点型表示的范围,就变成了NaN。

措施:

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

2. 不当的损失函数

原因:有时候损失层中的loss的计算可能导致NaN的出现。比如,给InfogainLoss层(信息熵损失)输入没有归一化的值,使用带有bug的自定义损失层等等。

现象:观测训练产生的log时一开始并不能看到异常,loss也在逐步的降低,但突然之间NaN就出现了。

措施:看看你是否能重现这个错误,在loss layer中加入一些输出以进行调试。

3. 不当的输入

原因:输入中就含有NaN。

现象:每当学习的过程中碰到这个错误的输入,就会变成NaN。观察log的时候也许不能察觉任何异常,loss逐步的降低,但突然间就变成NaN了。

措施:重整你的数据集,确保训练集和验证集里面没有损坏的图片。调试中你可以使用一个简单的网络来读取输入层,有一个缺省的loss,并过一遍所有输入,如果其中有错误的输入,这个缺省的层也会产生NaN。

参考:https://zhuanlan.zhihu.com/p/599887666

          江大白

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JOYCE_Leo16

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值