Learning Rate
学習率は、学習中のすべての重み更新の大きさを調整します。値が高すぎると発散し、低すぎると学習が停滞する理由に加え、ウォームアップ、減衰スケジュール、調整方法について解説します。
学習率はハイパーパラメーターの一つで、学習の各ステップでモデルの重みをどれだけ動かすかを決めます。勾配降下法は、損失関数が最も速く増加する方向を示す勾配を計算し、各重みを w ← w − η × gradient で更新します。ここで η(イータ)は学習率です。ステップサイズも同じ意味で、コードでは通常 lr と表記されます。適切な学習率はニューラルネットワークが適切な解に素早く収束するのを助けますが、不適切な学習率では学習が発散したり遅くなったりします。そのため Leslie Smith の周期的学習率に関する論文では、調整すべき最も重要なハイパーパラメーターとされています。ディープネットワークでは特に重要です。
高すぎる場合、低すぎる場合、適切な場合#
学習率は速度と安定性のトレードオフを決めます。
- 高すぎる場合: 各ステップで最小値を通り越します。損失が振動したり、急上昇したり、NaN になるまで増加したりして、学習が発散します。
- 低すぎる場合: 各ステップで重みがほとんど動きません。損失の低下が遅く、収束にはるかに多くのエポックが必要になり、予算を固定した実行では未学習のまま終了します。
- 適切な場合: 損失が着実に低下し、最小値付近で安定します。
以下のPyTorchスクリプトは、同じ初期値から 4 つの学習率を使って損失 w² を最小化します。
import torch
# Minimize loss = w**2 (lowest at w = 0) from the same start with four learning rates
for lr in (0.01, 0.1, 0.9, 1.1):
w = torch.tensor(5.0, requires_grad=True)
optimizer = torch.optim.SGD([w], lr=lr)
path = []
for step in range(20):
optimizer.zero_grad()
loss = w**2
loss.backward()
optimizer.step() # w = w - lr * gradient
path.append(w.item())
print(f"lr={lr}: first steps {[round(v, 2) for v in path[:3]]}, after 20 steps w={path[-1]:.3f}")0.01 では 20 ステップ後も重みは 5 から 3.338 に少し下がるだけですが、0.1 では 0.058 になります。0.9 では符号が各ステップで反転します(−4.0、3.2、−2.56)が、それでも 0.058 に収束します。一方、1.1 では各ステップでさらに大きく最小値を通り越し、重みは 191.688 まで増加します。二次関数に対する勾配降下法が安定するのは、学習率が損失の曲率、つまり二階微分の 2 分の 1 より小さい場合に限られます。w² の曲率は 2 なので、ここでの上限はちょうど 1.0 です。学習率 0.5 なら 1 ステップで最小値に到達します。実際のネットワークでも、損失の最も急な方向が同じ種類の上限を決めます。そのため、あるモデルやバッチサイズで機能する学習率が、別の設定では発散を引き起こすことがあります。
学習率スケジュール#
学習で最初から最後まで同じ学習率を使うことはほとんどありません。スケジュールによって学習率を時間とともに変化させます。
- ウォームアップ: 小さな学習率から始め、最初の数エポックまたはイテレーションにわたって引き上げます。これにより、初期イテレーションの大きく不規則な勾配による学習の不安定化を防ぎます。
- ステップ減衰: 設定したエポック数に達したとき、または検証損失が頭打ちになったときに、通常は 10 などの固定係数で学習率を割ります。
- 線形減衰とコサイン減衰: 学習率を滑らかに下げ、最終的に小さな値にします。コサインアニーリングはコサイン波の半周期に沿って学習率を下げます。ウォームリスタートを使う変種では、新しいサイクルの開始時に学習率を高い値へ戻します。
- 周期的ポリシーとワンサイクルポリシー: トレーニング中に、学習率を下限と上限の間で変化させます。
序盤の大きなステップは重みを良好な領域へすばやく移動させ、終盤の小さなステップは最小値の周辺で振動させずに収束させます。YOLO26のUltralyticsでのトレーニングはlr0から開始し、warmup_epochs(デフォルトでは3)にわたってウォームアップした後、lr0 * lrfまで線形に減衰させるか、cos_lr=Trueを用いてコサインに沿って減衰させます。デフォルトのoptimizer="auto"では、トレーナーがオプティマイザーと初期学習率の両方を自動的に選択します。10,000イテレーションを超える実行では0.01のMuSGD、それ以外ではクラス数に合わせた学習率のAdamWが選択されるため、lr0が適用されるのはオプティマイザーを明示的に設定した場合のみです。
from ultralytics import YOLO
# 事前学習済みYOLO26 nanoモデルを読み込みます
model = YOLO("yolo26n.pt")
# オプティマイザーを明示するとlr0が適用されます。学習率はコサインに沿ってlr0 * lrfまで減衰します
results = model.train(data="coco8.yaml", epochs=10, optimizer="SGD", lr0=0.01, lrf=0.01, cos_lr=True)開始値の選び方#
一般的な初期値は、モメンタムを用いる確率的勾配降下法 (SGD)では0.01~0.1、Adamオプティマイザーでは0.001です。この値はAdamの論文で提案されたデフォルト値です。ファインチューニングでは、事前学習済みモデルの学習率をスクラッチから学習する場合よりも低く設定します。大きなステップでは、特徴が上書きされるため、転移学習が機能しなくなるからです。
同じ周期的学習率の論文で紹介された学習率範囲テストは、fastaiでは学習率ファインダーとしてパッケージ化されており、短時間の実行で適切な値を見つけます。ミニバッチごとに学習率を上げながら損失を記録し、損失が最も急速に低下する範囲を有効な範囲とします。損失が急増し始める前の範囲が目安です。
学習率と関連用語の比較#
- 最適化アルゴリズム: 学習率を使用する更新ルールです。Adamのような適応型オプティマイザーは、各重みのステップをそれぞれの勾配履歴に応じて調整しますが、それでもすべてのステップに単一のグローバル学習率を乗じます。
- モメンタム: 前回の更新の一部を現在の更新に加える別個のハイパーパラメーターです。これにより経路が平滑化され、一貫した方向における実効ステップサイズが大きくなります。
- Weight decay: 各ステップで重み自体をゼロに近づける正則化項です。一方、学習率の減衰は時間の経過とともにステップサイズを小さくします。
- バッチサイズ: 各勾配の平均に含めるサンプル数です。バッチサイズを大きくすると勾配のノイズが減り、より大きな学習率を使用できます。また、線形スケーリング則では、バッチサイズをk倍にすると学習率もk倍にします。










