私は爆発する勾配と同様の振る舞いをデバッグするのに途方もない時間を費やしました。あなたの答えは、損失関数、データ、アーキテクチャなどに依存します。何百もの理由があります。いくつか挙げます。
- 損失依存。対数尤度損失はクリップする必要があります。そうでない場合は、
log(0)
データセット内の悪い予測/異常値をほぼ評価し、爆発を引き起こす可能性があります。ほとんどのパッケージ(トーチ、テンソルフローなど)は、損失のためにデフォルトでクリッピングを実装します。
- データセットの外れ値。
- ϵy=(x−u)/(s+ϵ)sϵy
- データセットがbatchsizeで割り切れない場合、エポックの最終バッチは小さい可能性があります。トーチデータローダーにはフラグがあり
drop_last
ます。小さいバッチサイズ=高い分散
では、SGDではなくAdamでそれを見る理由は何でしょうか。明らかに、Adamの方が損失が少なくなっています。前述のように、データセットの99.9%が一部の観測を除いてある時点で最適値を持っている場合、ランダムに選択してバッチにすると、観測は「NO」と叫び、極小値から飛び出します。-ステップごとに表示されるdataset_size//batch_size+1
場合、おそらく最終的なバッチサイズが小さいことが原因です。SGDのスパイクは、損失が少なくなると見られると思います。
ボーナス:モーメンタムオプティマイザー(Adam)による本当に速い減少は、一部のレイヤー(入力レイヤー?出力レイヤー?)がスケールアウトして(大きい/小さい重みに)初期化されることを意味します。