培训期间出现nans的常见原因

Posted

技术标签:

【中文标题】培训期间出现nans的常见原因【英文标题】:Common causes of nans during training of neural networks 【发布时间】:2016-03-01 22:36:00 【问题描述】:

我注意到在训练过程中经常出现NANs 被引入。

通常它似乎是由内积/全连接或卷积层爆炸的权重引入的。

出现这种情况是因为梯度计算崩溃了吗?还是因为权重初始化(如果是,为什么权重初始化会有这个效果)?还是可能是输入数据的性质造成的?

这里的首要问题很简单:NAN 在训练期间出现的最常见原因是什么?其次,有哪些方法可以解决这个问题(以及它们为什么有效)? p>

【问题讨论】:

您在调用特定的 MATLAB 函数吗?都是你自己的代码吗? @MatthewGunn 我不认为这个问题是 matlab 特有的,而是 caffe-related。 【参考方案1】:

在我的例子中,原因是没有在卷积/反卷积层中设置偏差。

解决方法:在卷积层参数中加入以下内容。

bias_filler 
      type: "constant"
      value: 0
    

【讨论】:

在 matconvnet 中看起来如何?我有类似 'biases'.init_bias*ones(1,4,single)【参考方案2】:

我多次遇到这种现象。以下是我的观察:


梯度爆炸

原因:大梯度会使学习过程偏离轨道。

您应该期待什么:查看运行时日志,您应该查看每次迭代的损失值。您会注意到,随着迭代的进行,损失开始显着增长,最终损失将太大而无法用浮点变量表示,它将变为nan

你能做什么:base_lr(在solver.prototxt中)减少一个数量级(至少)。如果您有多个损失层,您应该检查日志以查看导致梯度爆炸的层并减少该特定层的loss_weight(在 train_val.prototxt 中),而不是一般的base_lr


错误的学习率政策和参数

原因: caffe 未能计算出有效的学习率,而是得到'inf''nan',这个无效的学习率乘以所有更新,从而使所有参数无效。

你应该期待什么:查看运行时日志,你应该看到学习率本身变成了'nan',例如:

... sgd_solver.cpp:106] Iteration 0, lr = -nan

你能做什么:在你的'solver.prototxt'文件中修复所有影响学习率的参数。 例如,如果您使用 lr_policy: "poly" 而您忘记定义 max_iter 参数,您最终会得到 lr = nan... 有关 caffe 学习率的更多信息,请参阅this thread。


损失函数错误

原因: 有时损失层中损失的计算会导致出现nans。比如FeedingInfogainLoss layer with non-normalized values,使用带bug的自定义损失层等。

您应该期待什么:查看运行时日志您可能不会注意到任何异常:损失逐渐减少,突然出现nan

你能做什么:看看你是否可以重现错误,将打印输出添加到损失层并调试错误。

例如:曾经我使用了一个损失,该损失通过批次中标签出现的频率对惩罚进行了归一化。碰巧的是,如果其中一个训练标签根本没有出现在批次中 - 计算出的损失会产生nans。在这种情况下,使用足够大的批次(相对于集合中的标签数量)足以避免此错误。


输入错误

原因:您有一个包含nan 的输入!

你应该期待什么:一旦学习过程“命中”这个错误的输入 - 输出变成nan。查看运行时日志你可能不会注意到任何异常:损失逐渐减少,突然出现nan

你能做什么:重新构建你的输入数据集 (lmdb/leveldn/hdf5...) 确保你的训练/验证集中没有错误的图像文件。对于调试,您可以构建一个简单的网络来读取输入层,在其顶部有一个虚拟损失并遍历所有输入:如果其中一个有故障,这个虚拟网络也应该产生nan


步幅大于"Pooling" 层中的内核大小

出于某种原因,选择stride > kernel_size 进行池化可能会导致nans。例如:

layer 
  name: "faulty_pooling"
  type: "Pooling"
  bottom: "x"
  top: "y"
  pooling_param 
    pool: AVE
    stride: 5
    kernel: 3
  

nans 的结果为 y


"BatchNorm" 中的不稳定性

据报道,在某些设置下"BatchNorm"层可能会由于数值不稳定而输出nans。 这个issue 是在 bvlc/caffe 中提出的,PR #5136 正在尝试修复它。


最近,我意识到debug_info标志:在'solver.prototxt'中设置debug_info: true将使caffe print在训练期间记录更多的调试信息(包括梯度幅度和激活值):这些信息可以help in spotting gradient blowups and other problems in the training process。

【讨论】:

谢谢,如何解释这些数字?这些数字是什么? pastebin.com/DLYgXK5v为什么每层输出只有一个数字!?这些数字应该是什么样子,以便有人知道有问题或没有问题!? @Hossein 这正是this post 的全部意义所在。 感谢您的回答。对于使用 DICE 损失训练的图像分割应用程序,我得到了 NAN 损失(即使在添加了一个小的 epsilon/平滑常数之后)。我的数据集包含一些图像,其对应的真实值不包含任何前景标签,当我从训练中删除这些图像时,损失是稳定的。我不确定这是为什么? @samrairshad 你试过增加 DICE 损失中的 epsilon 吗? 是的,我做到了。我在 stack-overflow 上打开了这篇文章,并粘贴了一些时期的损失演变。这是参考:***.com/questions/62259112/…【参考方案3】:

learning_rate 很高,应该降低 RNN 代码的准确率是 nan,选择它修复的学习率的低值

【讨论】:

【参考方案4】:

这个答案不是关于nans 的原因,而是提出了一种帮助调试它的方法。 你可以有这个 python 层:

class checkFiniteLayer(caffe.Layer):
  def setup(self, bottom, top):
    self.prefix = self.param_str
  def reshape(self, bottom, top):
    pass
  def forward(self, bottom, top):
    for i in xrange(len(bottom)):
      isbad = np.sum(1-np.isfinite(bottom[i].data[...]))
      if isbad>0:
        raise Exception("checkFiniteLayer: %s forward pass bottom %d has %.2f%% non-finite elements" %
                        (self.prefix,i,100*float(isbad)/bottom[i].count))
  def backward(self, top, propagate_down, bottom):
    for i in xrange(len(top)):
      if not propagate_down[i]:
        continue
      isf = np.sum(1-np.isfinite(top[i].diff[...]))
        if isf>0:
          raise Exception("checkFiniteLayer: %s backward pass top %d has %.2f%% non-finite elements" %
                          (self.prefix,i,100*float(isf)/top[i].count))

将此层添加到您的 train_val.prototxt 在某些您怀疑可能会导致问题的地方:

layer 
  type: "Python"
  name: "check_loss"
  bottom: "fc2"
  top: "fc2"  # "in-place" layer
  python_param 
    module: "/path/to/python/file/check_finite_layer.py" # must be in $PYTHONPATH
    layer: "checkFiniteLayer"
    param_str: "prefix-check_loss" # string for printouts
  

【讨论】:

【参考方案5】:

我试图构建一个稀疏的自动编码器,并在其中设置了几层来诱导稀疏性。在运行我的网络时,我遇到了 NaN。在删除一些层时(在我的情况下,我实际上必须删除 1),我发现 NaN 消失了。所以,我想太多的稀疏性也可能导致 NaN(可能已经调用了一些 0/0 计算!?)

【讨论】:

你能再具体一点吗?您能否提供有关具有nans 和固定配置的配置的详细信息?什么类型的图层?什么参数? @shai 我使用了几个 InnerProduct (lr_mult 1, decay_mult 1, lr_mult 2, decay_mult 0, xavier, std: 0.01) 层,每个层后跟 ReLU(最后一个除外)。我正在使用 MNIST,如果我没记错的话,架构是 784 -> 1000 -> 500 -> 250 -> 100 -> 30(和对称解码器阶段);移除 30 层及其 ReLU 使 NaN 消失。

以上是关于培训期间出现nans的常见原因的主要内容,如果未能解决你的问题,请参考以下文章

Linux入门培训教程 常见linux命令释义

我拼搏的2016python学习的新认知和培训期间

如何在培训期间更改批量大小?

参加51CTO培训,PMP考试通过啦

北大青鸟设计培训:都有哪些常见的web开发技术?

李新海:培训师有十大好处,你知道吗?