トレーニング中に損失/精度が変動するのはなぜですか?(ケラス、LSTM)


11

KerasでLSTMネットワークを使用しています。訓練中、損失は大きく変動しますが、なぜそれが起こるのか分かりません。

最初に使用していたNNは次のとおりです。 ここに画像の説明を入力してください

トレーニング中の損失と精度は次のとおりです。 ここに画像の説明を入力してください

(実際には最終的に精度は100%に達しますが、約800エポックかかります。)

これらの変動は、ドロップアウトレイヤー/学習率の変化(rmsprop / adamを使用)が原因で発生すると考えたので、より単純なモデルを作成しました。 ここに画像の説明を入力してください

私はまた、勢いや衰退のないSGDを使用しました。別の値を試しましlrたが、同じ結果が得られました。

sgd = optimizers.SGD(lr=0.001, momentum=0.0, decay=0.0, nesterov=False)

しかし、私はまだ同じ問題を抱えていました。損失は単に減少するのではなく変動していました。私は常に損失は徐々に下がっていくはずだと思っていましたが、ここではそのようには動作しないようです。

そう:

  1. トレーニング中に損失がそのように変動するのは正常ですか?そして、なぜそれが起こるのでしょうか?

  2. そうでない場合、lrパラメーターが非常に小さい値に設定されている単純なLSTMモデルでこれが発生するのはなぜですか?

ありがとう。(同様の質問をここで確認しましたが、問題の解決には役立たなかったことに注意してください。)

更新: 1000以上のエポックの損失(BatchNormalizationレイヤーなし、Kerasの修飾子RmsProp): ここに画像の説明を入力してください

更新。2: 最終的なグラフの場合:

model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
history = model.fit(train_x, train_y, epochs = 1500)

データ:(ロボットのセンサーからの)電流の値のシーケンス。

ターゲット変数:ロボットが動作している表面(ワンホットベクトル、6つの異なるカテゴリとして)。

前処理:

  1. シーケンスが長くなりすぎないようにサンプリング周波数を変更しました(LSTMは他に学習しないようです)。
  2. シーケンスを小さいシーケンスに切り取ります(小さいシーケンスすべてで同じ長さ:それぞれ100タイムステップ)。
  3. 6つのクラスのそれぞれに、トレーニングセット内のサンプルの数がほぼ同じであることを確認します。

パディングなし。

トレーニングセットの形状(#sequences、#timesteps in a sequence、#features):

(98, 100, 1) 

対応するラベルの形状(6つのカテゴリのワンホットベクトルとして):

(98, 6)

レイヤー:

ここに画像の説明を入力してください

残りのパラメーター(学習率、バッチサイズ)は、Kerasのデフォルトと同じです。

keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)

batch_size:整数またはなし。勾配更新ごとのサンプル数。指定しない場合、デフォルトで32になります。

更新。3: の損失batch_size=4

ここに画像の説明を入力してください

batch_size=2LSTMの場合、適切に学習していないようです(損失は同じ値の周りで変動し、減少しません)。

更新。4:問題がコードの単なるバグではないかどうかを確認する:人工的な例を作成しました(分類するのが難しくない2つのクラス:cosとarccos)。これらの例のトレーニング中の損失と精度: ここに画像の説明を入力してください


問題を適切に導入することについてはどうですか(回答しようとしている研究の質問は何か、データの説明、モデルの表示など)?レイヤーのみを表示しますが、データ、前処理、損失関数、バッチサイズ、および結果に影響を与える可能性のあるその他の詳細については何も知りません
DeltaIV

1
安定性に影響を与える可能性のある他の事柄は、ソート、シャッフル、パディング、およびミニバッチでトレーニングされたRNNがさまざまな長さのシーケンスで機能するために必要なすべてのダーティトリックです。1200エポックであなたが得る巨大なスパイクは、私がそれに正確に対処しなければならなかった場合を思い出させます。誰が知っているか、多分注意が必要な
だけ-DeltaIV

1
私はそれがクレイジーであることを知っています。それがまさに私がここにいる理由です。なぜそれがこのようなものであるのか/どのようにそれを修正するのかを理解するためです。
Valeria

1
1.ロボットには多くのセンサーがありますが、私は電流の測定のみを使用しています。
バレリア

回答:


4

エポック上のトレーニングロスの変動を引き起こす可能性があるいくつかの理由があります。ただし、主なものは、ほとんどすべてのニューラルネットがさまざまな形式の確率勾配勾配で訓練されているという事実です。これが、モデルパラメータを1回更新するために使用するサンプルの数を決定するbatch_sizeパラメータが存在する理由です。更新ごとにすべてのサンプルを使用すると、サンプルが減少し、最終的に制限に達することがわかります。損失が確率的な動作をする理由は他にもあることに注意してください。

これが、振動が見られる理由です。しかし、あなたの場合、それは私が言うよりも普通のことです。コードを見ると、考えられるソースが2つあります。

  1. 大規模なネットワーク、小規模なデータセット:200K以上のパラメーターを使用し、非常に少数のサンプル(約100)で比較的大規模なネットワークをトレーニングしているようです。これを見通しに入れるには、200Kのパラメーターを学習するか、100サンプルだけを使用して200K-D空間で適切な極小値を見つけます。したがって、あなたは良い極小値に固執するのではなく、ただ歩き回ってしまうかもしれません。(放浪は、以下の2番目の理由も原因です)。

  2. 非常に小さいbatch_size。非常に小さいbatch_sizeを使用します。つまり、データポイントのごく一部を信頼しているようなものです。データポイント内に、誤ったラベルのサンプルがあるとします。このサンプルを2〜3個の適切にラベル付けされたサンプルと組み合わせると、更新によってグローバルな損失は減少しませんが、増加するか、極小値から破棄されます。batch_sizeが大きい場合、そのような影響は減少します。他の理由とともに、batch_sizeをいくつかの最小値より大きくすることをお勧めします。大きすぎると、トレーニングが遅くなります。したがって、batch_sizeはハイパーパラメーターとして扱われます。


0

あなたの損失曲線は私にはそれほど悪く見えません。これは、一般的な傾向が下降傾向である限り、多少上下に「変動」するはずです。これは理にかなっています。

バッチサイズは、ネットワークの学習方法にも影響を与えるため、学習率と合わせて最適化することをお勧めします。また、曲線全体をプロットします(100%の精度/最小損失に達するまで)。800エポックでトレーニングしたようで、最初の50エポックしか表示されていません。曲線全体で非常に異なるストーリーが得られる可能性があります。


あなたが正しいです。その上、トレーニングを再実行した後、それは以前よりも安定性が低くなっているため、エラーが欠落していることはほぼ確実です。1000以上のエポックのトレーニングで投稿を更新しました。
バレリア

0

変動は特定の制限内で正常であり、ヒューリスティック手法を使用しているという事実に依存しますが、ケースでは過度です。すべてのパフォーマンスにもかかわらず、明確な方向性があるため、システムは機能します。あなたが投稿したグラフから、問題はデータに依存するため、難しいトレーニングです。学習率を変更しようとした場合は、トレーニングアルゴリズムを変更してみてください。データをテストすることに同意します。まず、KNNを使用してベイズエラー率を計算し(必要な場合はトリック回帰を使用)、このようにして、入力データに必要なすべての情報が含まれているかどうかを確認できます。次に、検証やドロップアウトなしでLSTMを試して、必要な結果が得られることを確認します。トレーニングアルゴリズムが適切でない場合は、検証やドロップアウトがなくても同じ問題が発生するはずです。最後にトレーニングと検証サイズを調整して、テストセットで最良の結果を取得します。統計学習理論は一度に語れる話題ではなく、一歩一歩進んでいく必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.