1. ホーム
  2. machine-learning

[解決済み] トレーニング中のナンの原因

2022-11-16 16:51:47

質問

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

多くの場合、内積/完全連結または畳み込み層の重みが吹き飛ぶことによって導入されるようです。

これは勾配計算が吹っ飛ぶから発生しているのでしょうか?それとも重みの初期化が原因なのでしょうか (もしそうなら、なぜ重みの初期化がこのような影響を及ぼすのでしょうか)。あるいは、入力データの性質が原因でしょうか。

ここでの包括的な疑問は、単純に トレーニング中に NAN が発生する最も一般的な理由は何でしょうか。 そして第二に、これに対抗するためのいくつかの方法(そして、なぜそれが有効なのか)は何でしょうか?

どのように解決するのですか?

私はこの現象に何度か遭遇しました。以下は私の観察結果です。


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

理由 大きな勾配は学習プロセスを狂わせます。

期待すること 実行時ログを見ると、反復ごとの損失値を見る必要があります。損失が大きくなり始めていることに気がつくでしょう。 著しく になり、最終的に損失は浮動小数点変数で表せないほど大きくなってしまい、その結果 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の学習率について詳しくは このスレッド .


ロス機能の不具合

理由 時々、損失層での損失の計算が原因で nan が表示されることがあります。例えば、フィーディング InfogainLoss レイヤーに正規化されていない値 バグを含むカスタム損失レイヤーを使用する、など。

期待すること 実行時ログを見ると、おそらく何も異常はないでしょう。損失は徐々に減少し、突然 nan が表示されます。

何ができるのか。 エラーの再現性を確認し、損失レイヤーにプリントアウトを追加し、エラーをデバッグしてください。

たとえば、次のような場合です。かつて私は、バッチ内のラベルの出現頻度によってペナルティを正規化する損失を使用しました。たまたま、学習ラベルの1つがバッチに全く現れなかった場合、計算された損失は、以下のようになります。 nan s. その場合、(セット内のラベルの数に関して)十分に大きなバッチで作業することが、このエラーを回避するのに十分でした。


欠陥のある入力

理由 で入力されています。 nan が入っています。

期待すること 学習プロセスがこの欠陥のある入力にぶつかると、出力は次のようになります。 nan . 実行時ログを見ると、おそらく何も異常はないだろう:損失は徐々に減少し、突然 nan が表示されます。

何ができるのか。 入力データセット(lmdb/leveldn/hdf5...)を再ビルドし、トレーニング/バリデーションセットに悪い画像ファイルがないことを確認することです。デバッグのために、入力層を読み込む簡単なネットを構築し、その上にダミーの損失を乗せて、すべての入力を実行することができます:それらのいずれかに欠陥がある場合、このダミーネットも生成する必要があります nan .


でカーネルサイズより大きなストライドを "Pooling"

なぜか stride > kernel_size で結果をプーリングすることができます。 nan s. 例えば

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

の結果は nan の中に y .


の不安定さ "BatchNorm"

一部の設定において "BatchNorm" レイヤーの出力が nan を出力することがあります。

これは 問題 は、bvlc/caffe で提起され PR #5136 がそれを修正しようとしています。


最近、私は debug_info フラグ: 設定 debug_info: true'solver.prototxt' は、学習中のデバッグ情報(勾配の大きさや活性化値など)をより多く記録するためにcaffe printを行います。この情報は この情報は、学習過程における勾配の爆発やその他の問題を発見するのに役立ちます。 .