コンテンツにスキップ

6.7.2 ハイパーパラメータ調整戦略

  • 何でも同時に変えず、安定した順序で調整できる。
  • PyTorch で小さな learning-rate sweep を実行できる。
  • validation loss、validation accuracy、訓練の安定性を一緒に読める。
  • 再利用できる表で実験 evidence を記録できる。
  • learning rate、batch size、正則化、early stopping のどれを次に調整すべきか判断できる。

深層学習の tuning と診断ルート

実践的な順序:

訓練を動かすlearning rate を調整するvalidation を見るoverfitting を抑える局所的に細かく詰める

最初からすべての knob を回さないでください。有用な調整実験は、1 つの質問に答えるべきです。

質問まず試すパラメータ見るもの
モデルはそもそも学習するかlearning ratetrain loss の傾向
訓練が不安定かlearning rate、gradient clipping、batch sizespike や divergence
validation が training より悪いかweight decay、dropout、augmentation、early stoppinggeneralization gap
訓練が遅すぎるかbatch size、model size、precision時間とメモリ
deploy には重すぎるかarchitecture、pruning、quantizationlatency と size

実験:Learning-Rate Sweep を走らせる

Section titled “実験:Learning-Rate Sweep を走らせる”

この toy classification task は小さくてすぐ動きますが、調整の流れを学べます。

lr_sweep.py を作成します。

import torch
from torch import nn
torch.manual_seed(11)
X = torch.randn(240, 2)
y = ((X[:, 0] * 0.8 + X[:, 1] * -0.5) > 0).long()
train_x, val_x = X[:180], X[180:]
train_y, val_y = y[:180], y[180:]
def run(lr):
torch.manual_seed(123)
model = nn.Sequential(nn.Linear(2, 8), nn.ReLU(), nn.Linear(8, 2))
opt = torch.optim.SGD(model.parameters(), lr=lr)
loss_fn = nn.CrossEntropyLoss()
for _ in range(40):
logits = model(train_x)
loss = loss_fn(logits, train_y)
opt.zero_grad()
loss.backward()
opt.step()
with torch.no_grad():
train_loss = loss_fn(model(train_x), train_y).item()
val_logits = model(val_x)
val_loss = loss_fn(val_logits, val_y).item()
val_acc = (val_logits.argmax(dim=1) == val_y).float().mean().item()
return train_loss, val_loss, val_acc
results = []
for lr in [1e-3, 1e-2, 1e-1, 1.0, 10.0]:
train_loss, val_loss, val_acc = run(lr)
results.append((lr, train_loss, val_loss, val_acc))
print("lr_sweep")
for lr, train_loss, val_loss, val_acc in results:
print(
f"lr={lr:g} "
f"train_loss={train_loss:.3f} "
f"val_loss={val_loss:.3f} "
f"val_acc={val_acc:.3f}"
)
best = min(results, key=lambda row: row[2])
print("best_lr:", best[0])

実行します。

Terminal window
python lr_sweep.py

期待される出力:

Terminal window
lr_sweep
lr=0.001 train_loss=0.763 val_loss=0.733 val_acc=0.450
lr=0.01 train_loss=0.675 val_loss=0.663 val_acc=0.533
lr=0.1 train_loss=0.340 val_loss=0.373 val_acc=0.967
lr=1 train_loss=0.053 val_loss=0.072 val_acc=0.983
lr=10 train_loss=0.280 val_loss=0.291 val_acc=0.883
best_lr: 1.0

LR sweep 出力結果図

読み方:

  • 0.0010.01 は、この budget では遅すぎます。
  • 0.11.0 はよく学習しています。
  • 10.0 はまだ訓練できますが悪化しているので、大きければよいわけではありません。
  • ここでは training loss ではなく validation loss で選びます。

Hyperparameter tuning の探索図

妥当な learning rate を見つけたら、次の順で進めます。

  1. Batch size:メモリ、速度、gradient noise を調整する。
  2. Epochs と early stopping:validation が伸びなくなったら止める。
  3. Weight decay と dropout:overfitting を抑える。
  4. Architecture size:loop が安定してから容量を変える。
  5. Optimizer details:必要に応じて betas、scheduler、warmup、momentum を調整する。

ルール:

まず広く探し、あとで近くを細かく詰める

小さな project でも log を残します。

グループ記録する項目
識別情報experiment_idcode_versiondata_versionseed
ハイパーパラメータlrbatch_sizeoptimizerweight_decaydropoutepochs
結果best_val_metrictrain_timedecision

decision の例:

quick sweep では lr=1.0 が最も良い validation loss。
次は lr=1.0 を固定し、batch_size=32 と 64 を比較する。

tuning decision card を 1 つ残します。

質問
どの単一変数がテストされたか?
固定済み
データ分割、seed、モデル、optimizer の種類、学習予算
変更点
学習率の値
選択指標
検証損失または検証精度
最良設定
速い探索で lr=1.0
次の実験
一度に多くの設定を変えず、ローカルな微調整を1つ行う
パターンありそうな原因次の実験
train loss が動かないLR が低い、モデルが小さい、label が悪いLR を上げる、data を確認する、モデルを大きくする
train loss が発散するLR が高い、gradient が不安定LR を下げる、clipping を入れる
train は良いが validation が悪いoverfitting または leakage正則化を足し、split を確認する
validation が良くなった後で悪化するbest epoch の後に overfittingearly stopping
seed で結果が大きく変わる訓練が不安定、または data が少ない3 seed で mean/std を出す
間違い直し方
LR、batch size、optimizer、model を同時に変える1 実験で主変数を 1 つに絞る
training metric で選ぶvalidation metric で選ぶ
runtime を無視する時間とメモリも記録する
lucky seed を信じる重要な run は複数 seed で繰り返す
data が汚いまま調整するlabel、leakage、preprocessing を先に確認する
  1. sweep に lr=0.3lr=3.0 を追加してください。どちらが良い領域に近いですか。
  2. training budget を 40 step から 10 step に変えてください。best LR は変わりますか。
  3. 各 LR を 2 つの seed で実行し、seed 列を追加してください。
  4. LR sweep の後に行う次の実験を 1 文で書いてください。
  5. 1 つの実験が 1 つの質問に答える形だと、なぜ調整が簡単になるのか説明してください。
参考実装と解説
  1. 多くの場合 lr=0.3 の方が使える領域に近く、lr=3.0 は発散や振動を起こしやすいです。最終判断は検証曲線で行います。
  2. 予算が短いと、大きめの学習率が良く見えることがあります。長い予算では安定性も重要です。
  3. seed を増やすと平均とばらつきを見られます。1 回だけの良い結果に引っ張られにくくなります。
  4. 次の実験は具体的に書きます。例: 0.03 から 0.3 の間を細かく調べ、各設定を 2 seed で走らせる。
  5. 1 回の実験で 1 つの問いに答えると、結果の原因を追いやすく、記録も再現しやすくなります。
  • 調整は制御された実験設計であり、勘ではありません。
  • Learning rate は多くの場合、最初に試す knob です。
  • 判断は validation の evidence で行います。
  • Log があれば、実験は再現しやすく解釈しやすくなります。
  • まず広く調整し、あとで局所的に詰めます。