「Pytorch:LearningRate」の版間の差分
(→準備) |
(→解答例) |
||
| 57行目: | 57行目: | ||
これで実装完了です.エポック数が予定の1/2を過ぎたあたりで loss の値がガクッと落ちていることが確認できると思います. | これで実装完了です.エポック数が予定の1/2を過ぎたあたりで loss の値がガクッと落ちていることが確認できると思います. | ||
=これも調べてみましょう= | |||
warmup | |||
= 解答例 = | = 解答例 = | ||
[//vrl.sys.wakayama-u.ac.jp/class/pytorch_tutorial/exersise_learningrate/exersise_learningrate_answer.py 解答例] | [//vrl.sys.wakayama-u.ac.jp/class/pytorch_tutorial/exersise_learningrate/exersise_learningrate_answer.py 解答例] | ||
2025年3月27日 (木) 04:39時点における最新版
学習率をスケジューリングする機能を扱う練習をします.
準備
まず,作業用ディレクトリに移動した後に,以下のコマンドを実行して,プログラムをダウンロードしてください.
wget https://vrl.sys.wakayama-u.ac.jp/class/pytorch_tutorial/exersise_learningrate/exersise_learningrate.py
データセットはCIFAR-10を用います.(他の演習でダウンロード済みの場合は,以下を実行しなくても構いません.ただし,データセットへのパスを適宜修正してください.)
wget -P ./data -r https://vrl.sys.wakayama-u.ac.jp/class/pytorch_tutorial/datasets/cifar-10-batches-py/
ダウンロードしたら,exersise_learningrate.pyをそのまま実行してください.おそらく,テストデータに対する精度は80%くらいになったと思います.
学習途中での学習率の変更
DNNの学習においては,学習率が小さすぎると学習がなかなか進まず,一方で学習率を大きくすると,重みの更新も大雑把になり,なかなか収束してくれません.そこで,初期学習率を高く設定し,学習が進むにつれて徐々に落としていくのが一般的です.なお,具体的に学習率どの値にすればよいのかは,タスク,データセット,モデルアーキテクチャ,オプティマイザ,その他多くの要因が絡むので,一概には言えません.
現在の学習率は
learning_rate = 1e-1
となっており,学習中は完全に固定されています.
Pytorchでは,オプティマイザ(SGDなど,学習対象の重みをアップデートする役割を持つ)を生成する際に,学習率(learning_rate)を指定します.
optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum, weight_decay=weight_decay)
学習途中で学習率を変更する場合は,オプティマイザを再生成しても構いませんが(かつてはそのようにしていた),コードが煩雑になります.最近は,torch.optim に lr_scheduler なるものが実装されているので,これを用いて簡単に学習率のスケジューリングができます.
では,実装してみましょう.以下のように書いてください.(細字は初めから書いてあるコード,太字は書き足すコード.)
# モデル、損失関数、オプティマイザの設定
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = models.resnet18()
model.fc.__init__(512,10)
model = model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum, weight_decay=weight_decay)
scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=[num_epochs//2], gamma=0.1)
ここで,optim.lr_scheduler.MultiStepLR はある決められたエポック数に達すると学習率を gamma 倍してくれる機能を実装したもので,引数の milestones は,何エポックで学習率を落とすか,をリストで指定するためのものです.
この時点ではまだスケジューラを定義しただけであり,プログラムを実行しても結果は変わりません.スケジューラに仕事をさせるには,以下のように書いてください.
# 学習ループ
def train_model():
model.train()
for epoch in range(num_epochs):
total_loss = 0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss/len(train_loader):.4f}")
scheduler.step()
これで実装完了です.エポック数が予定の1/2を過ぎたあたりで loss の値がガクッと落ちていることが確認できると思います.
これも調べてみましょう
warmup