トレーニング中のnansの一般的な原因


86

トレーニング中に頻繁に発生することNANが導入されていることに気づきました。

多くの場合、内積/完全に接続された層または畳み込み層の重みが爆発することによって導入されるようです。

これは、勾配計算が爆発しているために発生していますか?それとも、重みの初期化が原因ですか(もしそうなら、なぜ重みの初期化がこの効果をもたらすのですか)?それとも、入力データの性質が原因である可能性がありますか?

ここでの最も重要な質問は単純です。トレーニング中にNANが発生する最も一般的な理由は何ですか。そして第二に、これと戦うためのいくつかの方法は何ですか(そしてなぜそれらは機能しますか)?


特定のMATLAB関数を呼び出していますか?それはすべてあなた自身のコードですか?
マシューガン

2
@MatthewGunnこの質問は、MATLAB固有ではなく、caffe関連していると思います。
シャイ2015年

回答:


137

良い質問。
私はこの現象に何度か遭遇しました。これが私の観察です:


グラデーションブローアップ

理由:大きな勾配は学習プロセスを軌道から外します。

期待すべきこと:ランタイムログを見ると、反復ごとの損失値を確認する必要があります。損失は反復ごとに大幅に増加し始め、最終的には損失が大きすぎて浮動小数点変数で表すことができなくなり、になり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...
カフェでの学習率の詳細については、このスレッドを参照してください。


損失関数の障害

理由:損失レイヤーでの損失の計算により、nansが表示される場合があります。たとえば、InfogainLoss正規化されていない値のフィードレイヤー、バグのあるカスタム損失レイヤーの使用などです。

期待すべきこと:ランタイムログを見ると、おそらく異常なことは何も気付かないでしょう。損失は徐々に減少し、突然突然nan現れます。

何ができるか:エラーを再現できるかどうかを確認し、損失レイヤーにプリントアウトを追加して、エラーをデバッグします。

例:一度、バッチでのラベルの出現頻度によってペナルティを正規化する損失を使用しました。トレーニングラベルの1つがバッチにまったく表示されなかった場合、計算された損失によってnansが生成されました。その場合、(セット内のラベルの数に関して)十分な大きさのバッチで作業することで、このエラーを回避するのに十分でした。


入力不良

理由:入力がありますnan

期待すべきこと:学習プロセスがこの誤った入力に「ヒット」すると、出力はになりnanます。ランタイムログを見ると、おそらく異常なことは何も気付かないでしょう。損失は徐々に減少し、突然突然nan現れます。

何ができるか:入力データセット(lmdb / leveldn / hdf5 ...)を再構築して、トレーニング/検証セットに不正な画像ファイルがないことを確認します。デバッグの場合、入力レイヤーを読み取り、その上にダミーの損失があり、すべての入力を実行する単純なネットを構築できます。それらの1つに障害がある場合、このダミーネットもを生成する必要があり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"nan、数値が不安定なため、レイヤーがsを出力する場合があることが報告されました。
この問題はbvlc / caffeで発生し、PR#5136はそれを修正しようとしています。


最近、debug_infoフラグに気づきました。を設定debug_info: trueする'solver.prototxt'と、トレーニング中により多くのデバッグ情報(勾配の大きさやアクティブ化値を含む)をログに記録するカフェプリントが作成されます。この情報は、トレーニングプロセスでの勾配の爆発やその他の問題の発見に役立ちます


おかげで、それらの数字をどのように解釈するのですか?これらの数字は何ですか?pastebin.com/DLYgXK5vなぜレイヤー出力ごとに1つの番号しかないのですか?誰かが問題があるか、問題がないことを知るために、これらの数字はどのように見えるべきですか!?
リカ

@Hosseinこれはまさにこの投稿のすべてです。
Shai 2016

この答えをありがとう。DICE損失でトレーニングされた画像セグメンテーションアプリケーションでNAN損失が発生します(小さなイプシロン/滑らかさ定数を追加した後でも)。私のデータセットには、前景ラベルを含まない対応するグラウンドトゥルースを持つ画像がいくつか含まれています。これらの画像をトレーニングから削除すると、損失は安定しました。なぜなのかわかりません。
samrairshad20年

@samrairshad DICE損失のイプシロンを増やしてみましたか?
シャイ

はい、しました。スタックオーバーフローで投稿を開き、いくつかのエポックの損失の進展を貼り付けました。:ここに参照だstackoverflow.com/questions/62259112/...は
samra irshad

5

私の場合、畳み込み/デコンボリューションレイヤーにバイアスを設定しなかったことが原因でした。

解決策:畳み込みレイヤーのパラメーターに以下を追加します。

bias_filler {タイプ: "定数"値:0}


それはmatconvnetでどのように見えますか?'biases'.init_bias * ones(1,4、single)
h612 2017年

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
  }
}


-1

私はスパースオートエンコーダーを構築しようとしていて、スパース性を誘発するためにその中にいくつかのレイヤーがありました。ネットを走らせていると、NaNに出くわしました。いくつかのレイヤーを削除すると(私の場合、実際には1を削除する必要がありました)、NaNが消えていることがわかりました。したがって、スパース性が多すぎるとNaNも発生する可能性があると思います(0/0の計算が呼び出された可能性があります!?)


もう少し具体的にできますか?があった構成とnan固定構成の詳細を教えてください。どのタイプのレイヤーですか?どのパラメータ?
Shai 2016

1
@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(および対称デコーダーフェーズ)でした。ReLUと一緒に30層を削除すると、NaNが消えました。
LKB 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.