6.1.5 オプティマイザ

この節では、小さな PyTorch 最適化実験を実行します。
- 同じ単純な loss で SGD、Momentum、Adam を比較する;
- オーバーシュートを直接見る;
- 学習率の感度を確認する;
- 安全なオプティマイザ選択順を学ぶ。

セットアップ
Section titled “セットアップ”python -m pip install -U torch完全な実験を実行する
Section titled “完全な実験を実行する”optimizer_lab.py を作成します。
import torch
def run_optimizer(name, optimizer_factory, steps=25): torch.manual_seed(42) w = torch.nn.Parameter(torch.tensor([5.0])) optimizer = optimizer_factory([w]) for step in range(1, steps + 1): loss = (w - 2).pow(2).mean() optimizer.zero_grad() loss.backward() optimizer.step() if step in [1, 5, 10, 25]: print(f"{name:<8} step={step:<2} w={w.item():.3f} loss={loss.item():.4f}")
print("optimizer_comparison")run_optimizer("sgd", lambda params: torch.optim.SGD(params, lr=0.1))run_optimizer("momentum", lambda params: torch.optim.SGD(params, lr=0.1, momentum=0.9))run_optimizer("adam", lambda params: torch.optim.Adam(params, lr=0.1))
print("learning_rate_check")for lr in [0.01, 0.1, 1.1]: torch.manual_seed(42) w = torch.nn.Parameter(torch.tensor([5.0])) optimizer = torch.optim.SGD([w], lr=lr) for _ in range(10): loss = (w - 2).pow(2).mean() optimizer.zero_grad() loss.backward() optimizer.step() final_loss = (w - 2).pow(2).item() print(f"lr={lr:<4} final_w={w.item():.3f} final_loss={final_loss:.4f}")実行します。
python optimizer_lab.py期待される出力:
optimizer_comparisonsgd step=1 w=4.400 loss=9.0000sgd step=5 w=2.983 loss=1.5099sgd step=10 w=2.322 loss=0.1621sgd step=25 w=2.011 loss=0.0002momentum step=1 w=4.400 loss=9.0000momentum step=5 w=0.259 loss=0.8571momentum step=10 w=2.013 loss=0.6767momentum step=25 w=2.475 loss=0.0200adam step=1 w=4.900 loss=9.0000adam step=5 w=4.502 loss=6.7648adam step=10 w=4.014 loss=4.4535adam step=25 w=2.739 loss=0.6569learning_rate_checklr=0.01 final_w=4.451 final_loss=6.0085lr=0.1 final_w=2.322 final_loss=0.1038lr=1.1 final_w=20.575 final_loss=345.0386
この loss は次です。
loss = (w - 2)^2最良値は w=2 です。すべてのオプティマイザは w=5 から始まります。
この単純な例では、適切な学習率の SGD が非常によく動きます。
sgd step=25 w=2.011 loss=0.0002Momentum は速く動きますが、行き過ぎることがあります。
momentum step=5 w=0.259Adam は深層学習でよく使われる既定選択ですが、魔法ではありません。この小さな問題では、lr=0.1 の Adam は調整された SGD より遅く動きました。大事なのは「Adam が悪い」ではなく、次です。
訓練の挙動を必ず見る。オプティマイザ選択と学習率はセットで働く。
学習率が最初のつまみ
Section titled “学習率が最初のつまみ”学習率の確認はあえて単純にしています。
lr=0.01 final_w=4.451 final_loss=6.0085lr=0.1 final_w=2.322 final_loss=0.1038lr=1.1 final_w=20.575 final_loss=345.0386小さすぎる:学習が遅い。
ちょうどよい:最適値に近づく。
大きすぎる:発散する。
ノートには optimizer 比較を 1 つ残します。
- 同じ損失
- (w - 2)^2
- 同じ開始
- w = 5
- sgd結果
- lr=0.1 で w = 2 に近づく
- momentum の結果
- より速く動くが行き過ぎる
- 悪い lr の結果
- lr=1.1 で発散する
これは optimizer 名を暗記するより役立ちます。勾配は方向を与え、optimizer の設定は動く大きさと動き方を決める、という本質を示すからです。
オプティマイザの直感
Section titled “オプティマイザの直感”| オプティマイザ | 直感 | 最初に使いやすい場面 |
|---|---|---|
| SGD | 勾配の反対方向へ直接動く | 単純な基線、制御された実験 |
| SGD + Momentum | 前のステップの速度を残す | ノイズのある方向で進みやすい |
| Adam | 勾配履歴からステップ幅を調整する | 多くのニューラルネットワークの強い既定値 |
実際のニューラルネットワークでは、Adam または AdamW が実用的な出発点になることが多いです。最終的には、タスクの検証指標で比較します。
実用的な選択順
Section titled “実用的な選択順”- ニューラルネットワークの基線は Adam または AdamW から始める。
- オプティマイザ名を議論する前に、学習率を調整する。
- training loss と validation loss の曲線を見る。
- validation が不安定なら、LR を下げるか schedule を入れる。
- training が遅いが安定しているなら、LR schedule や optimizer 変更を試す。
よくあるトラブル
Section titled “よくあるトラブル”| 症状 | よくある原因 | 修正 |
|---|---|---|
| loss が爆発する | 学習率が高すぎる | LR を下げる |
| loss が遅くしか下がらない | LR が低すぎる、または入力尺度が悪い | LR を慎重に上げ、入力を正規化する |
| training loss は下がるが validation が悪化 | オーバーフィット | 正則化、データ追加、早期停止 |
| loss が振動する | momentum/LR が強すぎる | LR または momentum を下げる |
| Adam は動くが最終品質が弱い | optimizer が他の問題を隠している | データ、構造、正則化を確認する |
- SGD の学習率を
0.05、0.2、0.8に変えてください。 - momentum を
0.9から0.5に変えてください。オーバーシュートは減りますか? AdamをAdamWに置き換えてください。- 各 step で
w.gradを表示し、勾配と更新を結びつけてください。 - 各オプティマイザの
wの変化をグラフにしてください。
参考実装と解説
- 学習率が小さいほど安全ですが遅く、大きいほど速い一方で振動しやすくなります。
0.8は overshoot の観察に向いています。 - momentum を下げると慣性が弱くなり、行き過ぎは減ることがありますが、収束速度も落ちる場合があります。
- AdamW は weight decay を Adam の更新から分離して扱うため、正則化の挙動をより読みやすくできます。
w.gradの符号と大きさを見ると、重みがどちらにどれだけ動くかを説明できます。- グラフでは最終値だけでなく、振動、停滞、滑らかさも比較します。optimizer の違いは曲線に出ます。
合格チェック
Section titled “合格チェック”次を説明できれば、この節はクリアです。
- 勾配は loss を変える方向を示す;
- オプティマイザはパラメータをどれだけ動かすかを決める;
- 学習率は訓練を遅くしたり、収束させたり、発散させたりする;
- momentum は速くできるが、行き過ぎることもある;
- Adam は便利だが、訓練曲線の確認の代わりにはならない。