神經網絡在進行參數優化的過程中,經常需要對學習率進行動態調整。那么PyTorch的torch.optim.lr_scheduler接口提供了很多策略實現動態調整。我們選取一些常用的進行介紹。
1. torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=- 1, verbose=False)
Sets the learning rate of each parameter group to the initial lr times a given function.
這個策略也比較簡單,就是每次調用scheduler.step()之后,新的lr等于原lr乘lr_lambda。舉例如下,其中network可以換成我們要優化的模型:
optim = torch.optim.Adam(network.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.LambdaLR(optim, lambda epoch: epoch)
for epoch in range(10):
optim.step()
scheduler.step()
print(scheduler.get_last_lr())
輸出結果如下:
[0.001]
[0.002]
[0.003]
[0.004]
[0.005]
[0.006]
[0.007]
[0.008]
[0.009000000000000001]
[0.01]
可以看到每次調用step之后,lr = lr * lr_lambda(epoch)。
2.torch.optim.lr_scheduler.MultiplicativeLR(optimizer, lr_lambda, last_epoch=- 1, verbose=False)
Multiply the learning rate of each parameter group by the factor given in the specified function.
這個方法跟LambdaLR
類似,都是乘lambda_lr,不同的是MultiplicativeLR
是用上一步得到的lr,而LambdaLR
用的始終是初始的lr。
optim = torch.optim.Adam(network.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.MultiplicativeLR(optim, lambda epoch: 0.5)
for epoch in range(10):
optim.step()
scheduler.step()
print(scheduler.get_last_lr())
結果如下:
[0.0005]
[0.00025]
[0.000125]
[6.25e-05]
[3.125e-05]
[1.5625e-05]
[7.8125e-06]
[3.90625e-06]
[1.953125e-06]
[9.765625e-07]
3. torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=- 1, verbose=False)
Decays the learning rate of each parameter group by gamma every step_size epochs.
每間隔step_size個epoch,對lr執行一次乘 gamma操作。
optim = torch.optim.Adam(network.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size=5, gamma=0.1)
for i, epoch in enumerate(range(20)):
optim.step()
scheduler.step()
print(i, scheduler.get_last_lr())
結果如下:
0 [0.001]
1 [0.001]
2 [0.001]
3 [0.001]
4 [0.0001]
5 [0.0001]
6 [0.0001]
7 [0.0001]
8 [0.0001]
9 [1e-05]
10 [1e-05]
11 [1e-05]
12 [1e-05]
13 [1e-05]
14 [1.0000000000000002e-06]
15 [1.0000000000000002e-06]
16 [1.0000000000000002e-06]
17 [1.0000000000000002e-06]
18 [1.0000000000000002e-06]
19 [1.0000000000000002e-07]
4. torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=- 1, verbose=False)
Decays the learning rate of each parameter group by gamma once the number of epoch reaches one of the milestones.
StepLR
是等間隔的調整lr, 而MultiStepLR
是根據指定間隔進行調整,milestones
即為自定義的間隔。
optim = torch.optim.Adam(network.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.MultiStepLR(optim, milestones=[2,6], gamma=0.1)
for i, epoch in enumerate(range(10)):
optim.step()
scheduler.step()
print(i, scheduler.get_last_lr())
結果如下,可以看到分別在第二步和第六步進行了兩次學習率的調整。
0 [0.001]
1 [0.0001]
2 [0.0001]
3 [0.0001]
4 [0.0001]
5 [1e-05]
6 [1e-05]
7 [1e-05]
8 [1e-05]
9 [1e-05]
5.torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=- 1, verbose=False)
Decays the learning rate of each parameter group by gamma every epoch.
簡單講就是按照如下規則進行lr的更新: lr=lr?gamma??epoch
6. torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=- 1, verbose=False)
余弦退火策略。以余弦函數為周期,并在每個周期最大值時重新設置學習率。以初始學習率為最大學習率,以2?Tmax 為周期,在一個周期內先下降,后上升。
其中eta_min指一個周期內的最小學習率。
7. torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08, verbose=False)
這是個超級實用的學習率調整策略。他會監測一個指標,當這個指標不在下降或提高是,進行學習率更新,否則保持學習率不變。每次step需要傳入要監測的指標。
Reduce learning rate when a metric has stopped improving.
val_loss = validate(...)
scheduler.step(val_loss)
這里要注意的是step的參數,如果是越小越好,如loss,需要將mode設置成'min',如果是越大越好的指標,如Accuracy,需要將mode設置成'max'。