欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Pytorch中的學(xué)習(xí)率衰減及其用法詳解

 更新時(shí)間:2021年06月05日 09:55:03   作者:西北小生_  
這篇文章主要介紹了Pytorch中的學(xué)習(xí)率衰減及其用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Pytorch 學(xué)習(xí)率衰減及其用法

學(xué)習(xí)率衰減是一個(gè)非常有效的煉丹技巧之一,在神經(jīng)網(wǎng)絡(luò)的訓(xùn)練過(guò)程中,當(dāng)accuracy出現(xiàn)震蕩或loss不再下降時(shí),進(jìn)行適當(dāng)?shù)膶W(xué)習(xí)率衰減是一個(gè)行之有效的手段,很多時(shí)候能明顯提高accuracy。

Pytorch中有兩種學(xué)習(xí)率調(diào)整(衰減)方法:

使用庫(kù)函數(shù)進(jìn)行調(diào)整;

手動(dòng)調(diào)整。

1. 使用庫(kù)函數(shù)進(jìn)行調(diào)整:

Pytorch學(xué)習(xí)率調(diào)整策略通過(guò) torch.optim.lr_sheduler 接口實(shí)現(xiàn)。pytorch提供的學(xué)習(xí)率調(diào)整策略分為三大類(lèi),分別是:

(1)有序調(diào)整:等間隔調(diào)整(Step),多間隔調(diào)整(MultiStep),指數(shù)衰減(Exponential),余弦退火(CosineAnnealing);

(2)自適應(yīng)調(diào)整:依訓(xùn)練狀況伺機(jī)而變,通過(guò)監(jiān)測(cè)某個(gè)指標(biāo)的變化情況(loss、accuracy),當(dāng)該指標(biāo)不怎么變化時(shí),就是調(diào)整學(xué)習(xí)率的時(shí)機(jī)(ReduceLROnPlateau);

(3)自定義調(diào)整:通過(guò)自定義關(guān)于epoch的lambda函數(shù)調(diào)整學(xué)習(xí)率(LambdaLR)。

在每個(gè)epoch的訓(xùn)練中,使用scheduler.step()語(yǔ)句進(jìn)行學(xué)習(xí)率更新,此方法類(lèi)似于optimizer.step()更新模型參數(shù),即一次epoch對(duì)應(yīng)一次scheduler.step()。但在mini-batch訓(xùn)練中,每個(gè)mini-bitch對(duì)應(yīng)一個(gè)optimizer.step()。即用法如下:

optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
 
def train(...):
    for i, data in enumerate(train_loader):
        ......
        y_ = model(x)
        loss = criterion(y_,y)
        loss.backward()
        optimizer.step()
        ......
 
for epoch in range(epochs):
    scheduler.step()
    train(...)
    test(...)

(1) 等間隔調(diào)整學(xué)習(xí)率 StepLR

torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)

每訓(xùn)練step_size個(gè)epoch,學(xué)習(xí)率調(diào)整為lr=lr*gamma.

以下內(nèi)容中都將epoch和step對(duì)等,因?yàn)槊總€(gè)epoch中只進(jìn)行一次scheduler.step(),實(shí)則該step指scheduler.step()中的step, 即step_size指scheduler.step()進(jìn)行的次數(shù)。

參數(shù):

optimizer: 神經(jīng)網(wǎng)絡(luò)訓(xùn)練中使用的優(yōu)化器,如optimizer=torch.optim.SGD(...)

step_size(int): 學(xué)習(xí)率下降間隔數(shù),單位是epoch,而不是iteration.

gamma(float): 學(xué)習(xí)率調(diào)整倍數(shù),默認(rèn)為0.1

last_epoch(int): 上一個(gè)epoch數(shù),這個(gè)變量用來(lái)指示學(xué)習(xí)率是否需要調(diào)整。當(dāng)last_epoch符合設(shè)定的間隔時(shí),就會(huì)對(duì)學(xué)習(xí)率進(jìn)行調(diào)整;當(dāng)為-1時(shí),學(xué)習(xí)率設(shè)置為初始值。

(2) 多間隔調(diào)整學(xué)習(xí)率 MultiStepLR

跟(1)類(lèi)似,但學(xué)習(xí)率調(diào)整的間隔并不是相等的,如epoch=10時(shí)調(diào)整一次,epoch=30時(shí)調(diào)整一次,epoch=80時(shí)調(diào)整一次…

torch.optim.lr_sheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1)

參數(shù):

milestone(list): 一個(gè)列表參數(shù),表示多個(gè)學(xué)習(xí)率需要調(diào)整的epoch值,如milestones=[10, 30, 80].

其它參數(shù)同(1)。

(3) 指數(shù)衰減調(diào)整學(xué)習(xí)率 ExponentialLR

學(xué)習(xí)率呈指數(shù)型衰減,每訓(xùn)練一個(gè)epoch,lr=lrgamma*epoch,即

torch.optim.lr_sheduler.ExponentialLR(optimizer, gamma, last_epoch)

參數(shù):

gamma(float):學(xué)習(xí)率調(diào)整倍數(shù)的底數(shù),指數(shù)為epoch,初始值我lr, 倍數(shù)為

其它參數(shù)同上。

(4) 余弦退火函數(shù)調(diào)整學(xué)習(xí)率:

學(xué)習(xí)率呈余弦函數(shù)型衰減,并以2*T_max為余弦函數(shù)周期,epoch=0對(duì)應(yīng)余弦型學(xué)習(xí)率調(diào)整曲線的,epoch=T_max對(duì)應(yīng)余弦型學(xué)習(xí)率調(diào)整曲線的eta_min處,隨著epoch>T_max,學(xué)習(xí)率隨epoch增加逐漸上升,整個(gè)走勢(shì)同cos(x)。

torch.optim.lr_sheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1)

參數(shù):

T_max(int): 學(xué)習(xí)率下降到最小值時(shí)的epoch數(shù),即當(dāng)epoch=T_max時(shí),學(xué)習(xí)率下降到余弦函數(shù)最小值,當(dāng)epoch>T_max時(shí),學(xué)習(xí)率將增大;

eta_min: 學(xué)習(xí)率調(diào)整的最小值,即epoch=T_max時(shí),eta_min, 默認(rèn)為0.

其它參數(shù)同上。

(5) 根據(jù)指標(biāo)調(diào)整學(xué)習(xí)率 ReduceLROnPlateau

當(dāng)某指標(biāo)(loss或accuracy)在最近幾個(gè)epoch中都沒(méi)有變化(下降或升高超過(guò)給定閾值)時(shí),調(diào)整學(xué)習(xí)率。

如當(dāng)驗(yàn)證集的loss不再下降是,調(diào)整學(xué)習(xí)率;或監(jiān)察驗(yàn)證集的accuracy不再升高時(shí),調(diào)整學(xué)習(xí)率。

torch.optim.lr_sheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10,
 verbose=False, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08)

參數(shù):

mode(str): 模式選擇,有min和max兩種模式,min表示當(dāng)指標(biāo)不再降低(如監(jiān)測(cè)loss),max表示當(dāng)指標(biāo)不再升高(如監(jiān)測(cè)accuracy)。

factor(float): 學(xué)習(xí)率調(diào)整倍數(shù),同前面的gamma,當(dāng)監(jiān)測(cè)指標(biāo)達(dá)到要求時(shí),lr=lr×factor。

patience(int): 忍受該指標(biāo)多少個(gè)epoch不變化,當(dāng)忍無(wú)可忍時(shí),調(diào)整學(xué)習(xí)率。

verbose(bool): 是否打印學(xué)習(xí)率信息,print( 'Epoch {:5d} reducing learning rate of group {} to {:.4e}.'.format(epoch, i, new_lr), 默認(rèn)為False, 即不打印該信息。

threshold_mode (str): 選擇判斷指標(biāo)是否達(dá)最優(yōu)的模式,有兩種模式:rel 和 abs.

當(dāng)threshold_mode == rel, 并且 mode == max時(shí),dynamic_threshold = best * (1 + threshold);

當(dāng)threshold_mode == rel, 并且 mode == min時(shí),dynamic_threshold = best * (1 - threshold);

當(dāng)threshold_mode == abs, 并且 mode == max時(shí),dynamic_threshold = best + threshold;

當(dāng)threshold_mode == abs, 并且 mode == min時(shí),dynamic_threshold = best - threshold;

threshold(float): 配合threshold_mode使用。

cooldown(int): “冷卻時(shí)間”,當(dāng)調(diào)整學(xué)習(xí)率之后,讓學(xué)習(xí)率調(diào)整策略冷靜一下,讓模型在訓(xùn)練一段時(shí)間,再重啟監(jiān)測(cè)模式。

min_lr(float or list): 學(xué)習(xí)率下限,可為float,或者list,當(dāng)有多個(gè)參數(shù)組時(shí),可用list進(jìn)行設(shè)置。

eps(float): 學(xué)習(xí)率衰減的最小值,當(dāng)學(xué)習(xí)率的變化值小于eps時(shí),則不調(diào)整學(xué)習(xí)率。

optimizer = torch.optim.SGD(model.parameters(), args.lr,
 momentum=args.momentum, weight_decay=args.weight_decay)
scheduler = ReducelROnPlateau(optimizer,'min')
for epoch in range( args.start epoch, args.epochs ):
    train(train_loader , model, criterion, optimizer, epoch )
    result_avg, loss_val = validate(val_loader, model, criterion, epoch)
    # Note that step should be called after validate()
    scheduler.step(loss_val )

(6) 自定義調(diào)整學(xué)習(xí)率 LambdaLR

為不同參數(shù)組設(shè)定不同學(xué)習(xí)率調(diào)整策略。調(diào)整規(guī)則為:

lr = base_lr * lambda(self.last_epoch)

在fine-tune中特別有用,我們不僅可以為不同層設(shè)置不同的學(xué)習(xí)率,還可以為不同層設(shè)置不同的學(xué)習(xí)率調(diào)整策略。

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1)

參數(shù):

lr_lambda(function or list): 自定義計(jì)算學(xué)習(xí)率調(diào)整倍數(shù)的函數(shù),通常時(shí)epoch的函數(shù),當(dāng)有多個(gè)參數(shù)組時(shí),設(shè)為list.

其它參數(shù)同上。

例:

ignored_params = list(map(id, net.fc3.parameters()))
base_params = filter(lambda p: id(p) not in ignored_params, net.parameters())
optimizer = optim.SGD([
        {'params': base_params},
        {'params': net.fc3.parameters(), 'lr': 0.001*100}], 0.001,          momentum=0.9,weight_decay=1e-4)
 # Assuming optimizer has two groups.
lambda1 = lambda epoch: epoch // 3
lambda2 = lambda epoch: 0.95 ** epoch
scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()
    print('epoch: ', i, 'lr: ', scheduler.get_lr())
    
輸出:
epoch: 0 lr: [0.0, 0.1]
epoch: 1 lr: [0.0, 0.095]
epoch: 2 lr: [0.0, 0.09025]
epoch: 3 lr: [0.001, 0.0857375]
epoch: 4 lr: [0.001, 0.081450625]
epoch: 5 lr: [0.001, 0.07737809374999999]
epoch: 6 lr: [0.002, 0.07350918906249998]
epoch: 7 lr: [0.002, 0.06983372960937498]
epoch: 8 lr: [0.002, 0.06634204312890622]
epoch: 9 lr: [0.003, 0.0630249409724609]
為什么第一個(gè)參數(shù)組的學(xué)習(xí)率會(huì)是 0 呢? 來(lái)看看學(xué)習(xí)率是如何計(jì)算的。
第一個(gè)參數(shù)組的初始學(xué)習(xí)率設(shè)置為 0.001, 
lambda1 = lambda epoch: epoch // 3,
第 1 個(gè) epoch 時(shí),由 lr = base_lr * lmbda(self.last_epoch),
可知道 lr = 0.001 *(0//3) ,又因?yàn)?1//3 等于 0,所以導(dǎo)致學(xué)習(xí)率為 0。
第二個(gè)參數(shù)組的學(xué)習(xí)率變化,就很容易看啦,初始為 0.1, lr = 0.1 * 0.95^epoch ,當(dāng)
epoch 為 0 時(shí), lr=0.1 , epoch 為 1 時(shí), lr=0.1*0.95。
# -*- coding:utf-8 -*-
'''本文件用于測(cè)試pytorch學(xué)習(xí)率調(diào)整策略'''
__author__ = 'puxitong from UESTC'
 
import torch
import torch.optim as optim
from torch.optim import lr_scheduler
from torchvision.models import AlexNet
import matplotlib.pyplot as plt 
 
model = AlexNet(num_classes=2)
optimizer = optim.SGD(params=model.parameters(), lr=0.1)
 
# 等間隔調(diào)整學(xué)習(xí)率,每訓(xùn)練step_size個(gè)epoch,lr*gamma
# scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
 
# 多間隔調(diào)整學(xué)習(xí)率,每訓(xùn)練至milestones中的epoch,lr*gamma
# scheduler = lr_scheduler.MultiStepLR(optimizer, milestones=[10, 30, 80], gamma=0.1)
 
# 指數(shù)學(xué)習(xí)率衰減,lr*gamma**epoch
# scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
 
# 余弦退火學(xué)習(xí)率衰減,T_max表示半個(gè)周期,lr的初始值作為余弦函數(shù)0處的極大值逐漸開(kāi)始下降,
# 在epoch=T_max時(shí)lr降至最小值,即pi/2處,然后進(jìn)入后半個(gè)周期,lr增大
# scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=100, eta_min=0)
 
plt.figure()
x = list(range(100))
y = []
for epoch in range(100):
    scheduler.step()
    y.append(scheduler.get_lr()[0])
 
plt.plot(x, y)
plt.show()

2. 手動(dòng)調(diào)整學(xué)習(xí)率:

def adjust_learning_rate(optimizer, epoch):
    """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
    lr = args.lr * (0.1 ** (epoch // 30))
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr
def adjust_learning_rate(epoch, lr):
    if epoch <= 81:  # 32k iterations
      return lr
    elif epoch <= 122:  # 48k iterations
      return lr/10
    else:
      return lr/100
for epoch in range(epochs):
    lr = adjust_learning_rate(optimizer, epoch)  # 調(diào)整學(xué)習(xí)率
    optimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9, weight_decay=5e-4)
    ......
    optimizer.step()  # 采用新的學(xué)習(xí)率進(jìn)行參數(shù)更新

什么是param_groups?

optimizer通過(guò)param_group來(lái)管理參數(shù)組.param_group中保存了參數(shù)組及其對(duì)應(yīng)的學(xué)習(xí)率,動(dòng)量等等.所以我們可以通過(guò)更改param_group['lr']的值來(lái)更改對(duì)應(yīng)參數(shù)組的學(xué)習(xí)率

# 例1:有兩個(gè)`param_group`即,len(optim.param_groups)==2
optim.SGD([
                {'params': model.base.parameters()},
                {'params': model.classifier.parameters(), 'lr': 1e-3}
            ], lr=1e-2, momentum=0.9)
 
# 例2:一個(gè)參數(shù)組
optim.SGD(model.parameters(), lr=1e-2, momentum=.9)

上面第一個(gè)例子中,我們分別為 model.base 和 model.classifier 的參數(shù)設(shè)置了不同的學(xué)習(xí)率,即此時(shí) optimizer.param_grops 中有兩個(gè)不同的param_group:

param_groups[0]: {'params': model.base.parameters()},
param_groups[1]: {'params': model.classifier.parameters(), 'lr': 1e-3}

每一個(gè)param_group都是一個(gè)字典,它們共同構(gòu)成了param_groups,所以此時(shí)len(optimizer.param_grops)==2,aijust_learning_rate() 函數(shù)就是通過(guò)for循環(huán)遍歷取出每一個(gè)param_group,然后修改其中的鍵 'lr' 的值,稱(chēng)之為手動(dòng)調(diào)整學(xué)習(xí)率。

第二個(gè)例子中l(wèi)en(optimizer.param_grops)==1,利用for循環(huán)進(jìn)行修改同樣成立。

如果想要每次迭代都實(shí)時(shí)打印學(xué)習(xí)率,這樣可以每次step都能知道更新的最新學(xué)習(xí)率,可以使用

scheduler.get_lr()

它返回一個(gè)學(xué)習(xí)率列表,由參數(shù)組中的不同學(xué)習(xí)率組成,可通過(guò)列表索引來(lái)得到不同參數(shù)組中的學(xué)習(xí)率。

如何在 PyTorch 中設(shè)定學(xué)習(xí)率衰減(learning rate decay)

在這里插入圖片描述

很多時(shí)候我們要對(duì)學(xué)習(xí)率(learning rate)進(jìn)行衰減,下面的代碼示范了如何每30個(gè)epoch按10%的速率衰減:

很多時(shí)候我們要對(duì)學(xué)習(xí)率(learning rate)進(jìn)行衰減,下面的代碼示范了如何每30個(gè)epoch按10%的速率衰減:

def adjust_learning_rate(optimizer, epoch):
    """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
    lr = args.lr * (0.1 ** (epoch // 30))
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

什么是param_groups?

optimizer通過(guò)param_group來(lái)管理參數(shù)組.param_group中保存了參數(shù)組及其對(duì)應(yīng)的學(xué)習(xí)率,動(dòng)量等等.所以我們可以通過(guò)更改param_group[‘lr']的值來(lái)更改對(duì)應(yīng)參數(shù)組的學(xué)習(xí)率。

# 有兩個(gè)`param_group`即,len(optim.param_groups)==2
optim.SGD([
                {'params': model.base.parameters()},
                {'params': model.classifier.parameters(), 'lr': 1e-3}
          ], lr=1e-2, momentum=0.9)
 
#一個(gè)參數(shù)組
optim.SGD(model.parameters(), lr=1e-2, momentum=.9)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python OpenCV實(shí)現(xiàn)裁剪并保存圖片

    Python OpenCV實(shí)現(xiàn)裁剪并保存圖片

    這篇文章主要為大家詳細(xì)介紹了Python OpenCV實(shí)現(xiàn)裁剪并保存圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • 使用C++擴(kuò)展Python的功能詳解

    使用C++擴(kuò)展Python的功能詳解

    這篇文章主要介紹了使用C++擴(kuò)展Python的功能詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Django 外鍵查詢(xún)的實(shí)現(xiàn)

    Django 外鍵查詢(xún)的實(shí)現(xiàn)

    今天學(xué)習(xí)了一下外鍵查詢(xún)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • 用Python實(shí)現(xiàn)協(xié)同過(guò)濾的教程

    用Python實(shí)現(xiàn)協(xié)同過(guò)濾的教程

    這篇文章主要介紹了用Python實(shí)現(xiàn)協(xié)同過(guò)濾的教程,主要用于從大數(shù)據(jù)中抽取用戶(hù)信息偏好等等,需要的朋友可以參考下
    2015-04-04
  • 講解Python?中的?with?關(guān)鍵字

    講解Python?中的?with?關(guān)鍵字

    這篇文章主要介紹了講解Python?中的with關(guān)鍵字,文章基于python的相關(guān)資料展開(kāi)?with?語(yǔ)句的一些基本概念和用法及其底層工作原理,下文更多內(nèi)容感興趣的小伙伴可以參考一下
    2022-05-05
  • Python實(shí)現(xiàn)輕松識(shí)別數(shù)百個(gè)快遞單號(hào)

    Python實(shí)現(xiàn)輕松識(shí)別數(shù)百個(gè)快遞單號(hào)

    當(dāng)我們要寄出很多快遞時(shí),為了及時(shí)反饋物流信息,需要盡快將快遞單號(hào)提取出來(lái)。這時(shí)用手動(dòng)去識(shí)別真的太麻煩,所以本文將用Python實(shí)現(xiàn)輕松識(shí)別數(shù)百個(gè)快遞單號(hào),需要的可以參考一下
    2022-06-06
  • python中利用Future對(duì)象回調(diào)別的函數(shù)示例代碼

    python中利用Future對(duì)象回調(diào)別的函數(shù)示例代碼

    最近在學(xué)習(xí)python,所以這篇文章主要給大家介紹了關(guān)于在python中利用Future對(duì)象回調(diào)別的函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)下吧。
    2017-09-09
  • python使用difflib實(shí)現(xiàn)自動(dòng)查重

    python使用difflib實(shí)現(xiàn)自動(dòng)查重

    Python中有許多現(xiàn)成的庫(kù)和工具,可以方便地實(shí)現(xiàn)自動(dòng)查重的功能,其中,difflib庫(kù)就是一個(gè)專(zhuān)門(mén)用于比較文件和字符串差異的庫(kù),下面我們就來(lái)看看如何利用difflib實(shí)現(xiàn)自動(dòng)查重吧
    2023-11-11
  • python從gbff文件中直接提取cds序列

    python從gbff文件中直接提取cds序列

    這篇文章主要為大家介紹了python從gbff文件中直接提取cds序列示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 如何用 Python 處理不平衡數(shù)據(jù)集

    如何用 Python 處理不平衡數(shù)據(jù)集

    這篇文章主要介紹了如何用 Python 處理不平衡數(shù)據(jù)集,幫助大家更好的利用python進(jìn)行數(shù)據(jù)分析,感興趣的朋友可以了解下
    2021-01-01

最新評(píng)論