最適化エラーをデバッグし、軽減するにはどうすればよいですか。
要約: モデルで最適化の問題が発生した場合は、他のことを試す前に問題を修正することが重要です。トレーニングの失敗の診断と修正は活発な研究分野です。
図 4 について、次の点に注意してください。
- ストライドを変更しても、学習率が低いとパフォーマンスは低下しません。
- 学習率が高いと不安定なため、トレーニングが十分でなくなっている。
- 1, 000 ステップの学習率のウォームアップを適用すると、この不安定性のインスタンスが解決され、最大学習率 0.1 で安定したトレーニングが可能になります。
不安定なワークロードの特定
学習率が大きすぎると、ワークロードが不安定になります。不安定性が問題となるのは、小さすぎる学習率を使用せざるを得ない場合のみです。トレーニングの不安定性には、少なくとも次の 2 種類のものを区別する価値があります。
- 初期化時やトレーニングの初期は不安定。
- トレーニング中に突然不安定になった
ワークロードの安定性の問題は、次の方法で体系的に特定できます。
- 学習率スイープを行って最適な学習率 lr* を見つける。
- lr* のすぐ上の学習率についてトレーニング損失曲線をプロットする。
- 学習率が lr* より大きい場合に損失が不安定である(トレーニング中に損失が下がるのではなく上昇する)場合は、不安定性を修正することで通常、トレーニングが改善されます。
トレーニング中に完全な損失勾配の L2 ノルムをログに記録します。これは、外れ値によってトレーニング中に誤った不安定性が生じる可能性があるためです。これにより、グラデーションや重みの更新をどの程度積極的にクリップするかがわかります。
注: 一部のモデルでは、初期段階では非常に不安定で、その後復元されるため、トレーニングは遅くて安定します。一般的な評価スケジュールでは、評価の頻度が十分でないと、このような問題を見落とす可能性があります。
これを確認するには、lr = 2 * current best
を使用して約 500 ステップの省略された実行でトレーニングを行いますが、すべてのステップを評価します。
一般的な不安定性パターンの修正候補
一般的な不安定性パターンに対して、次の修正方法を検討してください。
- 学習率のウォームアップを適用します。これは、初期のトレーニングが不安定な場合に最適です。
- グラデーション クリッピングを適用します。これは、トレーニングの初期と中期の不安定性に優れており、ウォームアップではできない不適切な初期化を修正できる可能性があります。
- 新しいオプティマイザーを試してください。Momentum ではできない不安定要素にも対処できることがあります。これは活発な研究分野です。
- モデル アーキテクチャが、ベスト プラクティスと最適な初期化(以下の例を参照)を使用していることを確認してください。モデルに残差接続と正規化が含まれていない場合は、それらを追加します。
- 残差前の最後の演算として正規化します。(例:
x + Norm(f(x))
)。Norm(x + f(x))
が原因で問題が発生する可能性があります。 - 残ったブランチを 0 に初期化してみてください。(ReZero is All You Need: Fast Convergence at Large Depth を参照)。
- 学習率を低くする。これは最後の手段です。
学習率のウォームアップ
学習率のウォームアップを適用するタイミング
図 7a は、モデルに最適化が不安定になっていることを示すハイパーパラメータの軸プロットを示しています。最適な学習率は不安定の端にあるためです。
図 7b は、このピークの 5 倍または 10 倍の学習率でトレーニングされたモデルのトレーニングの損失を調べることで、この点をダブルチェックする方法を示しています。そのプロットで、一定の減少の後に損失が急激に増加している場合(上の図のステップ 10,000 など)、モデルの最適化が不安定になっている可能性があります。
学習率のウォームアップを適用する方法
上記の手順を使用して、モデルが不安定になる学習率を unstable_base_learning_rate
とします。
ウォームアップでは、学習率を 0 から unstable_base_learning_rate
より 1 桁以上大きい安定した base_learning_rate
に徐々に上げていく学習率スケジュールを事前に行います。デフォルトでは、unstable_base_learning_rate
の 10 倍の base_learning_rate
が試行されます。ただし、unstable_base_learning_rate
を 100 倍に増やして、この手順全体を再度実行することは可能です。具体的なスケジュールは次のとおりです。
- healthup_steps を 0 から base_learning_rate に昇格します。
- post_warmup_steps で一定のレートでトレーニングします。
目標は、unstable_base_learning_rate
を大幅に上回るピーク学習率を実現できる warmup_steps
の最小数を見つけることです。そのため、base_learning_rate
ごとに warmup_steps
と post_warmup_steps
を調整する必要があります。通常は、post_warmup_steps
を 2*warmup_steps
に設定しても問題ありません。
ウォームアップは、既存の減衰スケジュールとは別に調整できます。warmup_steps
は数桁でスイープされるはずです。たとえば、スタディの例では [10, 1000, 10,000, 100,000]
を試すことができます。実現可能な最大ポイントは、max_train_steps
の 10% を超えることはできません。
base_learning_rate
でトレーニングを爆発しない warmup_steps
を確立したら、ベースライン モデルに適用する必要があります。基本的には、このスケジュールを既存のスケジュールの先頭に追加し、前述の最適なチェックポイントの選択を使用して、このテストをベースラインと比較します。たとえば、最初の max_train_steps
が 10,000 で、warmup_steps
を 1,000 ステップ実行した場合、新しいトレーニング手順は合計 11,000 ステップで実行されます。
安定したトレーニングに長い warmup_steps
が必要な場合は(max_train_steps
の 5% 超)、その分を考慮して max_train_steps
の値を増やす必要があります。
すべてのワークロードにわたって「典型的な」値というものはありません。100 ステップで十分なモデルもあれば、40, 000 以上のステップが必要なモデル(特に変圧器)もあります。
グラデーション クリッピング
勾配のクリッピングは、大きな勾配または外れ値の勾配の問題が発生した場合に最も有用です。グラデーションのクリップを使用すると、次のいずれかの問題を解決できます。
- 初期のトレーニングが不安定(大きな勾配ノルムが早く発生する)
- トレーニング中の不安定性(トレーニング中に急激に勾配が急上昇する)。
ウォームアップ期間を長くすると、クリッピングでは発生しない不安定性が解消されることがあります。詳細については、学習率のウォームアップをご覧ください。
🤖? ウォームアップ中のクリップについても
理想的なクリップのしきい値は、「典型的な」勾配ノルムの少し上です。
勾配のクリップを行う方法の例を次に示します。
- 勾配のノルム $\left | g\right |$ が勾配のクリッピングしきい値 $\lambda$ より大きい場合は、${g}'= \lambda \times \frac{g}{\left | g\right |}$ ここで ${g}'$ は新しい勾配です。
トレーニング中にクリップされていない勾配ノルムをログに記録します。デフォルトで以下を生成します。
- 勾配ノルムとステップのプロット
- すべてのステップで集約された勾配ノルムのヒストグラム
勾配ノルムの 90 パーセンタイルに基づいて勾配クリッピングのしきい値を選択します。しきい値はワークロードによって異なりますが、90% が出発点として適しています。90% に達しない場合は、このしきい値を調整できます。
🤖? 適応型戦略はどうでしょうか?
勾配のクリッピングを試しても不安定な問題が残っている場合は、さらに困難を試すことができます。つまり、しきい値を小さくすることができます。
極めて積極的な勾配クリッピング(つまり、更新の 50% 超がクリップされる)は、本質的には学習率を低下させるおかしな方法です。クリッピングが極端に多い場合は、学習率を下げることをおすすめします。
学習率やその他の最適化パラメータをハイパーパラメータと呼ぶのはなぜですか。事前分布のパラメータではありません。
ベイズ ML では、「ハイパーパラメータ」という用語は正確な意味を持つため、学習率やその他の調整可能なディープ ラーニング パラメータのほとんどを「ハイパーパラメータ」と呼ぶことは、間違いなく用語の乱用です。ディープ ラーニングでは、学習率、アーキテクチャ パラメータ、その他の調整可能な項目に対して「メタパラメータ」という用語を使用したいと考えています。これは、メタパラメータが「ハイパーパラメータ」という単語の誤用による混乱の可能性を回避しているためです。この混乱は、確率的レスポンス サーフェス モデルに独自の真のハイパーパラメータがあるベイズ最適化について説明する場合に特に当てはまります。
残念ながら、混乱を招く可能性がありますが、ディープ ラーニング コミュニティでは「ハイパーパラメータ」という用語が非常に一般的になりました。そのため、この専門性を知らない多くの人を含む幅広い対象者を対象としたこのドキュメントでは、他の混乱を回避するために、この分野の混乱の原因となる 1 つに貢献することを選択しました。ただし、研究論文を発表する場合は別の選択をすることもあれば、ほとんどのコンテキストで代わりに「メタパラメータ」を使用することをおすすめしています。
検証セットのパフォーマンスを直接改善するためにバッチサイズを調整するべきではないのはなぜですか。
トレーニング パイプラインの他の詳細を変更せずにバッチサイズを変更すると、多くの場合、検証セットのパフォーマンスに影響します。ただし、トレーニング パイプラインをバッチサイズごとに個別に最適化すると、2 つのバッチサイズ間の検証セットのパフォーマンスの差は通常なくなります。
バッチサイズと最も強く相互作用するため、バッチサイズごとに個別に調整することが最も重要なハイパーパラメータは、オプティマイザーのハイパーパラメータ(学習率、モメンタムなど)と正則化ハイパーパラメータです。バッチサイズが小さいほど、サンプルの分散によりトレーニング アルゴリズムに取り込まれるノイズが増えます。このノイズは正則化効果をもたらす可能性があります。したがって、バッチサイズが大きいほど過学習が起こりやすくなり、より強力な正則化や追加の正則化手法が必要になる場合があります。また、バッチサイズを変更するときに、トレーニング ステップ数の調整が必要になることがあります。
これらの影響をすべて考慮すると、達成可能な検証パフォーマンスがバッチサイズに影響するという説得力のある証拠は得られません。詳細については、Shallue et al. 2018 をご覧ください。
一般的な最適化アルゴリズムの更新ルールについて教えてください。
このセクションでは、いくつかの一般的な最適化アルゴリズムの更新ルールについて説明します。
確率的勾配降下法(SGD)
\[\theta_{t+1} = \theta_{t} - \eta_t \nabla \mathcal{l}(\theta_t)\]
ここで、$\eta_t$ はステップ $t$ における学習率です。
モメンタム
\[v_0 = 0\]
\[v_{t+1} = \gamma v_{t} + \nabla \mathcal{l}(\theta_t)\]
\[\theta_{t+1} = \theta_{t} - \eta_t v_{t+1}\]
ここで、$\eta_t$ はステップ $t$ の学習率、$\gamma$ は運動係数です。
ネストロフ
\[v_0 = 0\]
\[v_{t+1} = \gamma v_{t} + \nabla \mathcal{l}(\theta_t)\]
\[\theta_{t+1} = \theta_{t} - \eta_t ( \gamma v_{t+1} + \nabla \mathcal{l}(\theta_{t}) )\]
ここで、$\eta_t$ はステップ $t$ の学習率、$\gamma$ は運動係数です。
RMSProp
\[v_0 = 1 \text{, } m_0 = 0\]
\[v_{t+1} = \rho v_{t} + (1 - \rho) \nabla \mathcal{l}(\theta_t)^2\]
\[m_{t+1} = \gamma m_{t} + \frac{\eta_t}{\sqrt{v_{t+1} + \epsilon}}\nabla \mathcal{l}(\theta_t)\]
\[\theta_{t+1} = \theta_{t} - m_{t+1}\]
ADAM
\[m_0 = 0 \text{, } v_0 = 0\]
\[m_{t+1} = \beta_1 m_{t} + (1 - \beta_1) \nabla \mathcal{l} (\theta_t)\]
\[v_{t+1} = \beta_2 v_{t} + (1 - \beta_2) \nabla \mathcal{l}(\theta_t)^2\]
\[b_{t+1} = \frac{\sqrt{1 - \beta_2^{t+1}}}{1 - \beta_1^{t+1}}\]
\[\theta_{t+1} = \theta_{t} - \alpha_t \frac{m_{t+1}}{\sqrt{v_{t+1}} + \epsilon} b_{t+1}\]
ナダム
\[m_0 = 0 \text{, } v_0 = 0\]
\[m_{t+1} = \beta_1 m_{t} + (1 - \beta_1) \nabla \mathcal{l} (\theta_t)\]
\[v_{t+1} = \beta_2 v_{t} + (1 - \beta_2) \nabla \mathcal{l} (\theta_t)^2\]
\[b_{t+1} = \frac{\sqrt{1 - \beta_2^{t+1}}}{1 - \beta_1^{t+1}}\]
\[\theta_{t+1} = \theta_{t} - \alpha_t \frac{\beta_1 m_{t+1} + (1 - \beta_1) \nabla \mathcal{l} (\theta_t)}{\sqrt{v_{t+1}} + \epsilon} b_{t+1}\]