2017-12-15 31 views
2

私はこの問題の最下部にリンクされているKerasオブジェクト検出モデルを訓練していますが、私の問題はKerasや訓練しようとしている特定のモデル(SSD)ではなく、データはトレーニング中にモデルに渡されます。私の訓練の損失は定期的なスパイクを持っていますか?

はここに私の問題(下の画像を参照)である。 私のトレーニング損失が全体的に減少しているが、それは鋭い通常のスパイクを示しています。

Training loss

をx軸上の単位訓練されていないエポックを、数十のトレーニングステップ。スパイクは、1390回のトレーニングステップごとに1回正確に発生します。これは、トレーニングデータセット上の1回のフルパスのトレーニングステップ数とまったく同じです。

訓練データセットの各フルパスの後にスパイクが常に発生するという事実は、モデル自体に問題があるのではなく、訓練中にデータが供給されていることを疑う。

トレーニング中にbatch generator provided in the repositoryを使用してバッチを生成しています。私はジェネレータのソースコードをチェックし、各パスの前にトレーニングデータセットをシャッフルしてsklearn.utils.shuffleを使用します。

私は2つの理由から完全に混乱している:

  1. トレーニングデータセットは、各パスの前にシャッフルされています。
  2. this Jupyter notebookのように、私はジェネレータのアドホックデータ拡張機能を使用しています。したがって、データセットは理論的には決して同じパスにならないはずです。すべての拡張はランダムです。

これは、私が損失機能でこのパターンを理解していない理由です。アドホックなデータ補強を使用し、すべてのパスの前にデータセットをシャッフルすることによって、私は基本的にデータセットの任意の構造を破壊しています:与えられたイメージの同じ変換がトレーニング中に2度起こることはほとんどありません。時計作業のようなデータセット上の各フルパスの後に正確にスパイクが発生します。

モデルが実際に何かを学習しているかどうかを確認するためにいくつかのテスト予測を行いました。予測は時間の経過とともに良くなっていきますが、モデルは非常にゆっくりと学習しています。これらのスパイクは1390ステップごとにグラデーションを台無しにしているようです。

これが何であるかに関するヒントは非常に高く評価されています!私は訓練のために上にリンクされた全く同じJupyterノートブックを使用していますが、私が変更した唯一の変数は32から16のバッチサイズです。それ以外のリンクノートには、ここで

モデルを含むリポジトリへのリンクです:

https://github.com/pierluigiferrari/ssd_keras

+0

これはあまりmcveではありませんが、私はこの質問が素敵なダイエットにつながると思います。回答が得られる確率は高くなります:) – DJK

+0

@ djk47463私はそれはほとんどコンパクトな例ではないと思いますが、複雑なオブジェクト検出モデルがあり、その問題がモデルのどの部分にあってもよい場合は、コンパクトな例ですか?とにかく、私はそれを自分で解決しました。結局ケラス特有の問題でした。多分、これはある時点で誰かにとって役に立ちます。 – Alex

答えて

1

私は自分自身をそれを考え出した:問題は、すべての後にKeras-特異的でした。

多分、この問題の解決策はある時点で誰かにとって役に立ちます。

Kerasは、損失をミニバッチサイズで除算することが判明しました。ここで理解しておくべき重要なことは、バッチサイズに対して平均する損失関数自体ではなく、平均化がトレーニングプロセスのどこかで発生することです。

なぜこの点が重要ですか?

SSDは、バッチサイズではなく、バッチ内の真実のバウンディングボックスの数によって、独自の平均化を行うかなり複雑なマルチタスク損失関数を使用します。今や損失関数が損失を既にバッチサイズと相関するいくつかの数で除算し、その後Kerasがバッチサイズで2回目ので除算すると、突然損失値がすべてバッチサイズに再び依存し始めます(正確には、バッチサイズに反比例する)。

通常、データセット内のサンプル数は、選択したバッチサイズの整数倍ではないため、エポックの最後のミニバッチ(ここでは、エポックを暗黙的にデータセット全体の1回の通過として定義します)バッチサイズよりも少ないサンプルしか含まれなくなります。これは、バッチサイズに依存する場合には損失値を崩し、勾配を崩してしまいます。私は勢いを持ってオプティマイザを使用しているので、勾配を乱し続けても、その後のいくつかのトレーニングステップのグラジエントに影響を与え続けます。

ロスにバッチサイズを掛けて(つまり、ケラスの分割をバッチサイズに戻して)ロス関数を調整したら、すべてがうまくいきました。

関連する問題