模型训练中遇到的问题——梯度消失/爆炸(Loss为nan)

可能出现的原因

  • Learning_rate过大,导致梯度较大,导致梯度爆炸
  • **函数、损失函数选取不当,在这种情况很少出现
  • 当网络的层数比较多,模型的数值稳定性容易变差,容易产生梯度消失和梯度爆炸,这会导致我们的loss在训练时变为nan,也称之为数据溢出。
  • 采用stride大于kernel size的池化层

解决方法(个人经验)

  • 首先不要先考虑**函数,应该先考虑的是learning_rate,试着降低学习率,虽然优化器(Adam)推荐0.001,但并不适用全部网络,试着减少一个量级。
  • 如果发现减少一个量级或者甚至两个量级还会出现loss为nan 的情况
  • 此时排除学习率的问题,应该考虑我们的loss是不是由多个层中的loss 组成,例如VAE,我们需要检查每个层的loss(关闭该层loss,用剩下的看是不是还是存在loss为nan的情况)
  • 最后检查所有用到log运算的式子,防止数据溢出
  • 一个trick:如果网络中的某个值你不确定该值是不是稳定,可以考虑给该值加上一个sigmoid或者tanh单调函数,这样也可以有效防止loss 为nan的情况。
  • 另一个trick:梯度剪裁,实现代码如下:
    模型训练中遇到的问题——梯度消失/爆炸(Loss为nan)