torch.optim.lr_scheduler.ReduceLROnPlateau
是 PyTorch 中的一種學習率調度器,主要用于在模型訓練過程中根據某些指標(如驗證損失)動態調整學習率。它是一種基于性能指標動態調整學習率的策略,而不是預定義的固定時間調整。
主要功能
ReduceLROnPlateau
會監控某個指標(如驗證損失),當該指標在若干個 epoch 中停止改善時(即進入"平臺"期),將學習率按一定的比例降低,從而幫助模型更好地收斂。
常用參數
初始化 ReduceLROnPlateau
時,可以設置以下參數:
-
optimizer
:- 目標優化器(如 SGD, Adam),學習率調度器會更新此優化器中的學習率。
-
mode
:- 決定監控指標是否需要"最小化"或"最大化"。
'min'
:監控指標越小越好(例如驗證損失)。'max'
:監控指標越大越好(例如驗證精度)。
-
factor
:- 學習率降低的比例,新的學習率為
lr = lr * factor
。 - 默認值:
0.1
(學習率每次降低為原來的 10%)。
- 學習率降低的比例,新的學習率為
-
patience
:- 容忍的連續 epoch 數,在這段時間內監控指標沒有改善,但不會立即降低學習率。
- 默認值:
10
。
-
threshold
:- 判斷監控指標是否改善的閾值。
- 默認值:
1e-4
(小于這個值的變化會被認為沒有改善)。
-
threshold_mode
:'rel'
:相對變化(即與前一個值相比的比例變化)。'abs'
:絕對變化。
-
cooldown
:- 每次調整學習率后等待的 epoch 數,在此期間不會檢測指標改善。
- 默認值:
0
。
-
min_lr
:- 學習率的下限,確保學習率不會被降低到此值以下。
- 默認值:
0
。
-
eps
:- 學習率變化的最小值,防止浮點數精度問題導致學習率更新失敗。
- 默認值:
1e-8
。
常見用法
以下是使用 ReduceLROnPlateau
的典型步驟:
-
初始化優化器和調度器:
import torch import torch.nn as nn import torch.optim as optim# 假設有一個模型和一個損失函數 model = nn.Linear(10, 1) criterion = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=0.01)# 初始化調度器 scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10)
-
在訓練循環中調用:
每個 epoch 完成后,使用驗證集的性能指標來調用調度器:for epoch in range(50):# 訓練過程model.train()for data, target in train_loader:optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()# 驗證過程model.eval()val_loss = 0with torch.no_grad():for data, target in val_loader:output = model(data)val_loss += criterion(output, target).item()# 調度器監控驗證損失scheduler.step(val_loss)# 打印當前學習率print(f"Epoch {epoch+1}: Learning rate: {optimizer.param_groups[0]['lr']}")
工作原理
-
監控指標:
- 每次調用
scheduler.step(metric)
,都會檢查傳入的metric
(如驗證損失或驗證精度)是否在過去patience
個 epoch 中有所改善。
- 每次調用
-
判斷是否降低學習率:
- 根據
mode
和threshold
,決定當前指標是否"足夠好"。 - 如果監控指標在
patience
個 epoch 內未改善,則將學習率乘以factor
。
- 根據
-
冷卻期:
- 調整學習率后,進入
cooldown
冷卻期,冷卻期內不會監控指標。
- 調整學習率后,進入
-
最小學習率限制:
- 如果新的學習率低于
min_lr
,則不再繼續降低。
- 如果新的學習率低于
代碼示例
假設驗證損失在第 15 個 epoch 開始停滯:
Epoch 10: val_loss = 0.50, lr = 0.01
Epoch 11: val_loss = 0.49, lr = 0.01
...
Epoch 15: val_loss = 0.48, lr = 0.01 (No significant improvement for 10 epochs)
Epoch 16: val_loss = 0.47, lr = 0.001 (Reduce learning rate by factor of 0.1)
...
Epoch 25: val_loss = 0.46, lr = 0.001 (No significant improvement for 10 epochs)
Epoch 26: val_loss = 0.45, lr = 0.0001 (Reduce learning rate again)
注意事項
-
適用場景:
- 常用于訓練到一定階段后,指標改善速度減慢時,動態調整學習率有助于提高模型性能。
- 尤其適合學習率對訓練敏感的優化器(如 SGD)。
-
與其他調度器對比:
StepLR
和CosineAnnealingLR
是預定義的固定時間調整學習率。ReduceLROnPlateau
是基于性能指標的動態調整,更加靈活。
-
使用正確的監控指標:
- 確保傳入的指標與訓練目標一致(如驗證損失應與
mode='min'
一起使用)。
- 確保傳入的指標與訓練目標一致(如驗證損失應與
通過動態調整學習率,ReduceLROnPlateau
可以幫助優化訓練過程,特別是在模型性能進入瓶頸階段時,非常有效。