optimizer.step(), scheduler.step()


lr_scheduler

PyTorch中torch.optim.lr_scheduler封裝的API:

  • lr_scheduler.LambdaLR

  • lr_scheduler.MultiplicativeLR

  • lr_scheduler.StepLR

  • lr_scheduler.MultiStepLR

  • lr_scheduler.ExponentialLR

  • lr_scheduler.CosineAnnealingLR

  • lr_scheduler.ReduceLROnPlateau

  • lr_scheduler.CyclicLR

  • lr_scheduler.OneCycleLR

  • lr_scheduler.CosineAnnealingWarmRestarts

optimizer_1.zero_grad()
optimizer_1.step()
print("第%d個epoch的學習率:%f" % (epoch, optimizer_1.param_groups[0]['lr']))
# 需要在優化器參數更新后再調整學習率
scheduler_1.step()
  • optimizer:根據反向傳播的梯度信息來更新網絡參數,以降低loss
  • scheduler.step(): 更新優化器的學習率,一般按照epoch為單位進行更新
  • 兩個屬性:
  1. optimizer.defaults(dict): 繼承自torch.optim.Optimizer父類,存放優化器的初始參數。
    dict.keys(): lr, betas, eps, weight_decay, amsgrad
  2. optimizer.param_groups(list): 每個元素都是一個字典,每個元素包含的key:params, lr, betas, eps, weight_decay, amsgradparams類是各個網絡的參數放在了一起。這個屬性也繼承自torch.optim.Optimizer父類。
  3. 將網絡參數放入優化器
import torch
import torch.nn as nn
from torch.optim.lr_scheduler import LambdaLR

initial_lr = 0.1

class model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=3, kernel_size=3)

    def forward(self, x):
        pass
# 實例化
net_1 = model()
# 實例化一個Adam優化器
optimizer_1 = torch.optim.Adam(net_1.parameters(), lr = initial_lr)
# 實例化LambdaLR對象,lr_lambda是更新函數
scheduler_1 = LambdaLR(optimizer_1, lr_lambda=lambda epoch: 1/(epoch+1))
# 初始lr。optimizer_1.defaults保存了初始參數
print("初始化的學習率:", optimizer_1.defaults['lr'])
lr_list = []
for epoch in range(1, 11):
    # train
    optimizer_1.zero_grad()
    optimizer_1.step()
    # 由於只給optimizer傳了一個網絡,所以optimizer_1.param_groups長度為1
    print("第%d個epoch的學習率:%f" % (epoch, optimizer_1.param_groups[0]['lr']))
    lr_list.append(optimizer_1.param_groups[0]['lr'])
    # 更新學習率
    scheduler_1.step()

# 畫出lr的變化
plt.plot(list(range(1, 11)), lr_list)
plt.xlabel("epoch")
plt.ylabel("lr")
plt.title("learning rate's curve changes as epoch goes on!")
plt.show()
output:
初始化的學習率: 0.1
第1個epoch的學習率:0.100000
第2個epoch的學習率:0.050000
第3個epoch的學習率:0.033333
第4個epoch的學習率:0.025000
第5個epoch的學習率:0.020000
第6個epoch的學習率:0.016667
第7個epoch的學習率:0.014286
第8個epoch的學習率:0.012500
第9個epoch的學習率:0.011111
第10個epoch的學習率:0.010000

Scheduler

torch.optim.lr_scheduler提供了根據epoch訓練次數調整學習率的方法。

Sets the learning rate of each parameter group to the initial lr times a given function. When last_epoch=-1, sets initial lr as lr.

將每個參數組的學習率設置為初始 lr 乘以給定函數。當 last_epoch=-1 時,設置初始 lr 為 lr。

  • 更新策略:$ updated _ {lr}\ =\ \lambda\ \times \ initial _ {lr} $
  • 其中,$ updated _ {lr} $ 是更新后的學習率,$ initial _ {lr} $是初始學習率, $ \lambda $ 是通過參數$lr _ {lambda} $ 和epoch得到的。

參數

  • optimizer(Optimizer): 優化器
  • lr_lambda(function or list): 給定函數
  • last_epoch: last epoch 的 index, 默認:-1
  • verbose(bool): True-每次更新輸出一條信息; 默認:False
  • Example
>>> # Assuming optimizer has two groups.
>>> lambda1 = lambda epoch: epoch // 30
>>> lambda2 = lambda epoch: 0.95 ** epoch
>>> scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)
>>>     scheduler.step()
  • 將optimizer傳給scheduler后,scheduler類會在optimizer.param_groups列表中增加一個key='initial_lr'表示初始學習率,value=optimizer.defaults['lr']

get_lr()

def get_lr(self):
        if not self._get_lr_called_within_step:
            warnings.warn("To get the last learning rate computed by the scheduler, "
                          "please use `get_last_lr()`.")
        # 更新學習率
        return [base_lr * lmbda(self.last_epoch)
                for lmbda, base_lr in zip(self.lr_lambdas, self.base_lrs)]

自定義scheduler

若API中沒有實踐中需要的調整策略,則可自定義adjust_learning_rate方法來改變param_grouplr的值。

假設實驗需要學習率每30 epoch下降原來的1/10,且API中沒有符合要求的方法,則通過自定義函數來動態調整學習率。

def adjust_learning_rate(optimizer, epoch):
    lr = initial_lr * (0.1 ** (epoch // 30))
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr
for epoch in range(1, 91):
    # train
    optimizer_1.zero_grad()
    optimizer_1.step()
    lr_list.append(optimizer_1.param_groups[0]['lr'])
    # 更新學習率
    # scheduler_1.step()
    adjust_learning_rate(optimizer_1,epoch)


參考:
https://blog.csdn.net/qyhaill/article/details/103043637


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM