よくある質問

最適化エラーをデバッグし、軽減するにはどうすればよいですか。

要約: モデルで最適化の問題が発生した場合は、他のことを試す前に問題を修正することが重要です。トレーニングの失敗の診断と修正は活発な研究分野です。

標準 WideResNet と Stride 1x1 WideResNet を比較したグラフ。
            Y 軸はテストエラー率、X 軸はベース学習率です。標準の WideResNet では、基本学習率が上がるにつれて、TestErrorRate が徐々に減少します。一方、Stride WideResNet では、基本学習率が高くなると激しく変動します。
図 4. WideResnet で 1 つの残差ブロック(2x2 -> 1x1)のストライドを変更すると、トレーニングが不安定になります。

 

図 4 について、次の点に注意してください。

  • ストライドを変更しても、学習率が低いとパフォーマンスは低下しません
  • 学習率が高いと不安定なため、トレーニングが十分でなくなっている。
  • 1, 000 ステップの学習率のウォームアップを適用すると、この不安定性のインスタンスが解決され、最大学習率 0.1 で安定したトレーニングが可能になります。

不安定なワークロードの特定

学習率が大きすぎると、ワークロードが不安定になります。不安定性が問題となるのは、小さすぎる学習率を使用せざるを得ない場合のみです。トレーニングの不安定性には、少なくとも次の 2 種類のものを区別する価値があります。

  • 初期化時やトレーニングの初期は不安定。
  • トレーニング中に突然不安定になった

ワークロードの安定性の問題は、次の方法で体系的に特定できます。

  • 学習率スイープを行って最適な学習率 lr* を見つける。
  • lr* のすぐ上の学習率についてトレーニング損失曲線をプロットする。
  • 学習率が lr* より大きい場合に損失が不安定である(トレーニング中に損失が下がるのではなく上昇する)場合は、不安定性を修正することで通常、トレーニングが改善されます。

トレーニング中に完全な損失勾配の L2 ノルムをログに記録します。これは、外れ値によってトレーニング中に誤った不安定性が生じる可能性があるためです。これにより、グラデーションや重みの更新をどの程度積極的にクリップするかがわかります。

注: 一部のモデルでは、初期段階では非常に不安定で、その後復元されるため、トレーニングは遅くて安定します。一般的な評価スケジュールでは、評価の頻度が十分でないと、このような問題を見落とす可能性があります。

これを確認するには、lr = 2 * current best を使用して約 500 ステップの省略された実行でトレーニングを行いますが、すべてのステップを評価します。

2 つのグラフ: 両方のグラフの x 軸はグローバル ステップ、y 軸はトレイン損失です。どちらのグラフも、コンバージョン ストライド(2,2)とコンバージョン ストライド(1,1)を比較しています。最初のグラフは、1,000 ステップごとの評価を示しています。この最初のグラフでは、両方のコンバージョン ストライドで、グローバル ステップ数が多く、緩やかな減少が見られます。2 番目のグラフは、最初の 25 ステップで頻繁に行われた評価を示しています。この 2 番目のグラフでは、(2,2)のコンバージョン ストライドでは、最初のいくつかのグローバル ステップで列車の損失に急激な変動が見られるものの、その後グローバル ステップで 20 ステップ減少しています。コンバージョン ストライドが(1,1)の場合、最初のグローバル ステップ後も、トレイン損失が一貫して低くなっています。
図 5. トレーニング開始時の評価をより頻繁に行うことの価値。初期のトレーニングが不安定で、モデルに問題が発生している可能性がある場合に便利です。

 

一般的な不安定性パターンの修正候補

一般的な不安定性パターンに対して、次の修正方法を検討してください。

  • 学習率のウォームアップを適用します。これは、初期のトレーニングが不安定な場合に最適です。
  • グラデーション クリッピングを適用します。これは、トレーニングの初期と中期の不安定性に優れており、ウォームアップではできない不適切な初期化を修正できる可能性があります。
  • 新しいオプティマイザーを試してください。Momentum ではできない不安定要素にも対処できることがあります。これは活発な研究分野です。
  • モデル アーキテクチャが、ベスト プラクティスと最適な初期化(以下の例を参照)を使用していることを確認してください。モデルに残差接続と正規化が含まれていない場合は、それらを追加します。
  • 残差前の最後の演算として正規化します。(例: x + Norm(f(x)))。Norm(x + f(x)) が原因で問題が発生する可能性があります。
  • 残ったブランチを 0 に初期化してみてください。(ReZero is All You Need: Fast Convergence at Large Depth を参照)。
  • 学習率を低くする。これは最後の手段です。

学習率のウォームアップ

同じテストを示す 2 つのグラフ。最初のグラフの X 軸はグローバル ステップ、Y 軸はトレイン損失です。学習率のウォームアップ値が低いため、Train Loss は非常に不安定でした。学習率のウォームアップ値が高いほど、トレイン損失が安定するようになりました。
図 6.ウォームアップ期間中の不安定性の例(横軸の対数目盛に注意)。このケースでトレーニングを成功させるには 4 万ステップのウォームアップが必要でした。

学習率のウォームアップを適用するタイミング

検証セットでの交差エントロピー損失(y 軸)とベース学習率(x 軸)の比較を示すグラフ。グラフには、6 つの実行可能なトライアルが示されており、いずれのトライアルもベース学習率が比較的低くなっています。検証損失は、基本学習率が高くなるにつれ減少し、上昇を開始する前に低値に達します。グラフには、4 つの実行不可能なトライアルも示されていますが、いずれのトライアルも比較的高い Base 学習率になっています。
図 7a.トレーニングが不安定であるモデルのハイパーパラメータ軸プロットの例。最適な学習率は、実現可能な限界に達します。「実行不可能な」トライアルでは、NaN または異常な高い損失値が生成されます。

 

トレーニング セット上の交差エントロピー損失(y 軸)とグローバル ステップ(x 軸)の比較を示すグラフ。最初のグローバル ステップでは、損失はすぐに減少します。その後、損失は約 10,000 歩で大幅に増加します。その後、損失は 15,000 歩前後に徐々に減少します。
図 7b.不安定性がある学習率でトレーニングされたモデルのトレーニング損失。

 

図 7a は、モデルに最適化が不安定になっていることを示すハイパーパラメータの軸プロットを示しています。最適な学習率は不安定の端にあるためです。

図 7b は、このピークの 5 倍または 10 倍の学習率でトレーニングされたモデルのトレーニングの損失を調べることで、この点をダブルチェックする方法を示しています。そのプロットで、一定の減少の後に損失が急激に増加している場合(上の図のステップ 10,000 など)、モデルの最適化が不安定になっている可能性があります。

学習率のウォームアップを適用する方法

ステップ 76619 の検証損失(y 軸)と基本学習率(x 軸)のグラフ。このグラフは、WMT14 EN-De の LayerNorm Transformer の 4 つの異なる状況の結果を比較したものです。学習率のウォームアップにより、低い学習率で検証損失が減少しました。
図 8. 学習率のウォームアップは、トレーニングの不安定性への対処に有効な効果があります。

 

上記の手順を使用して、モデルが不安定になる学習率を 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_stepspost_warmup_steps を調整する必要があります。通常は、post_warmup_steps2*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 以上のステップが必要なモデル(特に変圧器)もあります。

グラデーション クリッピング

Grad l2 ノルム(y 軸)とグローバル ステップ(x 軸)のグラフ。初期のグローバル ステップでは、「典型的な」勾配ノルムのトレーニングは非常に不安定でした。クリップのしきい値が高すぎると、学習率が低下し、トレーニングが遅くなります。クリップのしきい値(通常の勾配ノルムをわずかに上回る程度)を改善することで、初期のトレーニングが安定します。
図 9. 初期のトレーニングの不安定性を修正する勾配クリッピング

 

勾配のクリッピングは、大きな勾配または外れ値の勾配の問題が発生した場合に最も有用です。グラデーションのクリップを使用すると、次のいずれかの問題を解決できます。

  • 初期のトレーニングが不安定(大きな勾配ノルムが早く発生する)
  • トレーニング中の不安定性(トレーニング中に急激に勾配が急上昇する)。

ウォームアップ期間を長くすると、クリッピングでは発生しない不安定性が解消されることがあります。詳細については、学習率のウォームアップをご覧ください。

🤖? ウォームアップ中のクリップについても

理想的なクリップのしきい値は、「典型的な」勾配ノルムの少し上です。

勾配のクリップを行う方法の例を次に示します。

  • 勾配のノルム $\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}\]