<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          pytorch優(yōu)化器與學(xué)習(xí)率設(shè)置詳解

          共 9086字,需瀏覽 19分鐘

           ·

          2021-12-28 23:49

          ↑ 點(diǎn)擊藍(lán)字?關(guān)注極市平臺(tái)

          作者 | 小新
          來(lái)源 |?https://a.3durl.cn/YrcZbc
          編輯丨極市平臺(tái)
          本文僅作學(xué)術(shù)分享,版權(quán)屬于原作者,侵權(quán)請(qǐng)聯(lián)系刪文。

          極市導(dǎo)讀

          ?

          在很多學(xué)習(xí)過(guò)程中,都會(huì)采用動(dòng)態(tài)調(diào)整學(xué)習(xí)率的方法。剛開始訓(xùn)練的時(shí)候,學(xué)習(xí)率設(shè)置大一點(diǎn),以加快學(xué)習(xí)速度;之后逐漸減小學(xué)習(xí)率,來(lái)尋找最優(yōu)解。那么在Pytorch中,如在訓(xùn)練過(guò)程中動(dòng)態(tài)地調(diào)整學(xué)習(xí)率呢??>>加入極市CV技術(shù)交流群,走在計(jì)算機(jī)視覺(jué)的最前沿

          學(xué)習(xí)率設(shè)置對(duì)于學(xué)習(xí)過(guò)程來(lái)說(shuō)相當(dāng)重要。學(xué)習(xí)率過(guò)低會(huì)導(dǎo)致學(xué)習(xí)速度太慢,學(xué)習(xí)率過(guò)高又容易導(dǎo)致難以收斂。在很多學(xué)習(xí)過(guò)程中,都會(huì)采用動(dòng)態(tài)調(diào)整學(xué)習(xí)率的方法。剛開始訓(xùn)練的時(shí)候,學(xué)習(xí)率設(shè)置大一點(diǎn),以加快學(xué)習(xí)速度;之后逐漸減小學(xué)習(xí)率,來(lái)尋找最優(yōu)解。

          那么在Pytorch中,如在訓(xùn)練過(guò)程中動(dòng)態(tài)地調(diào)整學(xué)習(xí)率呢?

          目錄

          • 優(yōu)化器Optimizer
            • 只訓(xùn)練模型的一部分參數(shù)
            • 不同部分的參數(shù)設(shè)置不同的學(xué)習(xí)率(以及其他屬性)
            • Optimizer基本屬性
            • optimizer基本方法
          • 動(dòng)態(tài)更新learning rate
            • torch.optim.lr_scheduler
            • torch.optim.lr_scheduler.LambdaLr
            • torch.optim.lr_scheduler.StepLR
            • torch.optim.lr_scheduler.MultiStepLR
            • torch.optim.lr_scheduler.ExponentialLR
            • torch.optim.lr_scheduler.CosineAnnealingLR
            • torch.optim.lr_scheduler.ReduceLROnPlateau
            • 手動(dòng)修改lr

          優(yōu)化器Optimizer

          在說(shuō)學(xué)習(xí)率調(diào)整方法之前,先來(lái)了解一下Pytorch中的優(yōu)化器Optimizer機(jī)制。

          用過(guò)Pytorch的都知道,模型訓(xùn)練時(shí)的固定搭配。

          loss.backward()
          optimizer.step()
          optimizer.zero_grad()
          ...

          簡(jiǎn)單來(lái)說(shuō),loss.backward()就是反向計(jì)算出各參數(shù)的梯度,然后optimizer.step()就是更新網(wǎng)絡(luò)中的參數(shù),optimizer.zero_grad()將這一輪的梯度清零,防止這一輪的梯度影響下一輪的更新。

          常用優(yōu)化器都在torch.optim包中,因此需要先導(dǎo)入包:

          import?torch.optim.Adam
          import?torch.optim.SGD

          這里以常用的Adam優(yōu)化器和SGD優(yōu)化器為例,介紹一下Pytorch中的優(yōu)化器使用方法。

          假設(shè)我們有一個(gè)網(wǎng)絡(luò)如下,下面的例子都以此網(wǎng)絡(luò)作為例子:

          class?Net(nn.Module):
          ????def?__init__(self):
          ????????super(Net,?self).__init__()
          ????????self.layer?=?nn.Linear(10,?2)
          ????????self.layer2?=?nn.Linear(2,?10)

          ????def?forward(self,?input):
          ????????return?self.layer(input)???????

          # Optimizer基本屬性

          所有Optimizer公有的一些基本屬性:

          • lr: learning rate,學(xué)習(xí)率
          • eps: 學(xué)習(xí)率最小值,在動(dòng)態(tài)更新學(xué)習(xí)率時(shí),學(xué)習(xí)率最小不會(huì)小于該值。
          • weight_decay: 權(quán)值衰減。相當(dāng)于對(duì)參數(shù)進(jìn)行L2正則化(使模型復(fù)雜度盡可能低,防止過(guò)擬合),該值可以理解為正則化項(xiàng)的系數(shù)。
          • betas: (待研究)
          • amsgrad: (bool)(待研究)

          每個(gè)Optimizer都維護(hù)一個(gè)param_groups的list。該list中維護(hù)需要優(yōu)化的參數(shù)以及對(duì)應(yīng)的屬性設(shè)置。

          optimizer基本方法

          • add_param_group(param_group): 為optimizer的param_groups增加一個(gè)參數(shù)組。這在微調(diào)預(yù)先訓(xùn)練的網(wǎng)絡(luò)時(shí)非常有用,因?yàn)閮鼋Y(jié)層可以訓(xùn)練并隨著訓(xùn)練的進(jìn)行添加到優(yōu)化器中。
          • load_state_dict(state_dict): 加載optimizer state。參數(shù)必須是optimizer.state_dict()返回的對(duì)象。
          • state_dict(): 返回一個(gè)dict,包含optimizer的狀態(tài):state和param_groups。
          • step(closure): 執(zhí)行一次參數(shù)更新過(guò)程。
          • zero_grad(): 清除所有已經(jīng)更新的參數(shù)的梯度。

          我們?cè)跇?gòu)造優(yōu)化器時(shí),最簡(jiǎn)單的方法通常如下:

          model?=?Net()
          optimizer_Adam?=?torch.optim.Adam(model.parameters(),?lr=0.1)

          model.parameters()返回網(wǎng)絡(luò)model的全部參數(shù)。

          將model的全部參數(shù)傳入Adam中構(gòu)造出一個(gè)Adam優(yōu)化器,并設(shè)置 learning rate=0.1。因此該 Adam 優(yōu)化器的 param_groups 維護(hù)的就是模型 model 的全部參數(shù),并且學(xué)習(xí)率為0.1。這樣在調(diào)用optimizer_Adam.step()時(shí),就會(huì)對(duì)model的全部參數(shù)進(jìn)行更新。

          Optimizer的param_groups是一個(gè)list,其中的每個(gè)元素都是一組獨(dú)立的參數(shù),以dict的方式存儲(chǔ)。結(jié)構(gòu)如下:

          -param_groups
          ????-0(dict)??#?第一組參數(shù)
          ????????params:??#?維護(hù)要更新的參數(shù)
          ????????lr:??#?該組參數(shù)的學(xué)習(xí)率
          ????????betas:
          ????????eps:??#?該組參數(shù)的學(xué)習(xí)率最小值
          ????????weight_decay:??#?該組參數(shù)的權(quán)重衰減系數(shù)
          ????????amsgrad:??
          ????-1(dict)??#?第二組參數(shù)
          ????-2(dict)??#?第三組參數(shù)
          ????...
          ????...

          這樣可以實(shí)現(xiàn)很多靈活的操作,比如以下。

          只訓(xùn)練模型的一部分參數(shù)

          例如,只想訓(xùn)練上面的model中的layer參數(shù),而保持layer2的參數(shù)不動(dòng)。可以如下設(shè)置Optimizer:

          model?=?Net()
          optimizer_Adam?=?torch.optim.Adam(model.layer.parameters(),?lr=0.1)??#?只傳入layer層的參數(shù),就可以只更新layer層的參數(shù)而不影響其他參數(shù)。

          不同部分的參數(shù)設(shè)置不同的學(xué)習(xí)率(以及其他屬性)

          例如,要想使model的layer參數(shù)學(xué)習(xí)率為0.1,layer2的參數(shù)學(xué)習(xí)率為0.2,可以如下設(shè)置Optimizer:

          model?=?Net()
          params_dict?=?[{'params':?model.layer.parameters(),?'lr':?0.1},
          ???????????????????{'params':?model.layer2.parameters(),?'lr':?0.2}]
          optimizer_Adam?=?torch.optim.Adam(params_dict)

          這種方法更為靈活,手動(dòng)構(gòu)造一個(gè)params_dict列表來(lái)初始化Optimizer。注意,字典中的參數(shù)部分的 key 必須為 ‘params’。

          這樣就可以靈活的設(shè)置Optimizer啦。

          動(dòng)態(tài)更新learning rate

          了解了Optimizer的基本結(jié)構(gòu)和使用方法,接下來(lái)就可以看一下,如何在訓(xùn)練過(guò)程中動(dòng)態(tài)更新learning rate。

          手動(dòng)修改lr

          上面我們了解到,Optimizer的每一組參數(shù)維護(hù)一個(gè)lr,因此,最直接的方法就是我們?cè)谟?xùn)練過(guò)程中手動(dòng)修改Optimizer中對(duì)應(yīng)的lr的值:

          model?=?Net()??#?生成網(wǎng)絡(luò)
          optimizer_Adam?=?torch.optim.Adam(model.parameters(),?lr=0.1)??#?生成優(yōu)化器

          lr_list?=?[]
          for?epoch?in?range(100):??#?假設(shè)迭代100次
          ????if?epoch?%?5?==?0:??#?每迭代5次,更新一次學(xué)習(xí)率
          ????????for?params?in?optimizer_Adam.param_groups:??#?遍歷Optimizer中的每一組參數(shù)
          ????????????params['lr']?*=?0.9??#?將該組參數(shù)的學(xué)習(xí)率?*?0.9
          ????????????#?params['weight_decay']?=?0.5??#?當(dāng)然也可以修改其他屬性
          ????lr_list.append(optimizer_Adam.state_dict()['param_groups'][0]['lr'])
          plt.plot(range(100),?lr_list,?color='r')
          plt.show()
          手動(dòng)修改lr

          torch.optim.lr_scheduler

          torch.optim.lr_scheduler包中提供了一些類,用于動(dòng)態(tài)修改lr。

          • torch.optim.lr_scheduler.LambdaLr
          • torch.optim.lr_scheduler.StepLR
          • torch.optim.lr_scheduler.MultiStepLR
          • torch.optim.lr_scheduler.ExponentialLR
          • torch.optim.lr_sheduler.CosineAnneaingLR
          • torch.optim.lr_scheduler.ReduceLROnPlateau

          注意: pytorch 1.1.0版本之后,在創(chuàng)建了lr_scheduler對(duì)象之后,會(huì)自動(dòng)執(zhí)行第一次lr更新(可以理解為執(zhí)行一次scheduler.step())。因此,在使用的時(shí)候,需要先調(diào)用optimizer.step(),再調(diào)用scheduler.step()。如果創(chuàng)建了lr_scheduler對(duì)象之后,先調(diào)用scheduler.step(),再調(diào)用optimizer.step(),則會(huì)跳過(guò)了第一個(gè)學(xué)習(xí)率的值。

          #?調(diào)用順序
          loss.backward()
          optimizer.step()
          scheduler.step()
          ...

          注意: 創(chuàng)建scheduler時(shí),所傳入的Optimizer的param_groups必須有一個(gè)initial_lr鍵作為初始學(xué)習(xí)率。如果last_epoch=-1,則用于初始化的Optimizer可以沒(méi)有initial_lr鍵,以 lr 鍵初始化為initial_lr。

          torch.optim.lr_scheduler.LambdaLr

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

          • Optimizer:優(yōu)化器實(shí)例
          • lr_lambda:是一個(gè)函數(shù)(常用lambda表達(dá)式)或函數(shù)列表,該函數(shù)接收一個(gè)int參數(shù)(epoch),然后計(jì)算出一個(gè)系數(shù),最后學(xué)習(xí)率更新為
            。其中l(wèi)r_lambda如果傳入多個(gè)函數(shù)的list的話,則對(duì)應(yīng)每組param_groups的學(xué)習(xí)率調(diào)整策略。
          • last_epoch:(int)上一個(gè)epoch數(shù)。默認(rèn)為-1,且當(dāng)last_epoch=-1時(shí),將lr設(shè)置為initial_lr。第一次更新lr時(shí),就按照epoch = last_epoch + 1更新。(比如last_epoch = 1,則第一次lr更新時(shí),就將epoch=2傳入上面的lr_lambda函數(shù),得出系數(shù)

          需要注意的是,該scheduler每次lr更新,是用initial_lr 乘以系數(shù) ? ,而不是用上一次的lr 乘以系數(shù) ,即

          Lambda_lr

          torch.optim.lr_scheduler.StepLR

          torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)
          每迭代step_size次,學(xué)習(xí)率乘以gamma。

          model?=?Net()
          optimizer_Adam?=?torch.optim.Adam(model.parameters(),?lr=0.1)
          #?創(chuàng)建scheduler,每迭代5次,學(xué)習(xí)率衰減一半
          scheduler?=?torch.optim.lr_scheduler.StepLR(optimizer_Adam,?step_size=5,?gamma=0.5,?last_epoch=-1)

          lr_list_1?=?[]
          for?epoch?in?range(100):
          ????scheduler.step()
          ????lr_list_1.append(optimizer_Adam.state_dict()['param_groups'][0]['lr'])
          plt.plot(range(100),?lr_list_1,?color='r',?label='lr')
          plt.legend()
          plt.show()
          StepLR

          torch.optim.lr_scheduler.MultiStepLR

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

          多段衰減法。milestones傳入一個(gè)list,指定多個(gè)epoch數(shù),每迭代到指定的epoch次數(shù)時(shí),lr乘以gamma。
          例子:

          model?=?Net()
          optimizer_Adam?=?torch.optim.Adam(model.parameters(),?lr=0.1)??#?初始?lr=0.1
          #?lr?變化
          #?0?-?20?epoch:?0.1
          #?21?-?40?epoch:?0.05
          #?41?-?60?epoch:?0.025
          #?60?-?80?epoch:?0.0125
          #?80?-?end?epoch:?0.01125
          scheduler?=?torch.optim.lr_scheduler.MultiStepLR(optimizer_Adam,?milestones=[20,?40,?60,?80],?gamma=0.5,?last_epoch=-1)

          lr_list_1?=?[]
          for?epoch?in?range(100):
          ????scheduler.step()
          ????lr_list_1.append(optimizer_Adam.state_dict()['param_groups'][0]['lr'])
          plt.plot(range(100),?lr_list_1,?color='r',?label='lr')
          plt.legend()
          plt.show()
          MultiStepLR

          torch.optim.lr_scheduler.ExponentialLR

          torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=-1)

          每個(gè)epoch按指數(shù)衰減 lr。

          model?=?Net()
          optimizer_Adam?=?torch.optim.Adam(model.parameters(),?lr=0.1)
          #?指數(shù)衰減學(xué)習(xí)率,衰減率為?gamma=0.9
          scheduler?=?torch.optim.lr_scheduler.ExponentialLR(optimizer_Adam,?gamma=0.9,?last_epoch=-1)
          lr_list_1?=?[]
          for?epoch?in?range(100):
          ????scheduler.step()?
          ????lr_list_1.append(optimizer_Adam.state_dict()['param_groups'][0]['lr'])
          plt.plot(range(100),?lr_list_1,?color='r',?label='lr')
          plt.legend()
          plt.show()
          ExponentialLR

          torch.optim.lr_scheduler.CosineAnnealingLR

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

          按照三角函數(shù)規(guī)則來(lái)更新學(xué)習(xí)率。

          • 表示最小學(xué)習(xí)率, 即正弦函數(shù)最低點(diǎn)
          • 表示最大學(xué)習(xí)率, 設(shè)置為initial_Ir (在last_epoch=-1 時(shí), 即為Ir)。
          • 表示當(dāng)前epoch數(shù)
          • 表示 個(gè) 周期所對(duì)應(yīng)的epoch數(shù)值
          model?=?Net()
          optimizer_Adam?=?torch.optim.Adam(model.parameters(),?lr=0.1)
          #?周期為50epoch,lr最小值為0(默認(rèn))
          scheduler?=?torch.optim.lr_scheduler.CosineAnnealingLR(optimizer_Adam,?eta_min=0,?T_max=25,?last_epoch=-1)
          lr_list_1?=?[]
          for?epoch?in?range(100):
          ????scheduler.step()
          ????lr_list_1.append(optimizer_Adam.state_dict()['param_groups'][0]['lr'])
          plt.plot(range(100),?lr_list_1,?color='r',?label='lr')
          plt.legend()
          plt.show()
          CosineAnnealingLR

          torch.optim.lr_scheduler.ReduceLROnPlateau

          torch.optim.lr_scheduler.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)

          根據(jù)指定的指標(biāo)量來(lái)調(diào)整學(xué)習(xí)率。如果指標(biāo)量停止變化時(shí),就減小學(xué)習(xí)率。
          參數(shù):

          • mode:(str),從(min, max)中選擇。
            • min:如果指定量不再下降,就減小lr
            • max:如果指定量不再上升,就減小lr
          • factor:(float),衰減因子,每次更新lr = lr * factor
          • patience:(int),容忍度,如果經(jīng)過(guò)patience次迭代后,指標(biāo)沒(méi)有變化(上升或下降),就更新lr。
          • verbose:(bool),每次更新lr,是否向std輸出。
          • threshold:(float),閾值,對(duì)于制定的指標(biāo)只有超過(guò)閾值才算有變化
          • threshold_mode:(str),從(rel,abs)總選擇。性能衡量方式。
            • max模式下:dynamic_threshold = best + threshold
            • min模式下:dynamic_threshold = best - threshold
            • max模式下:dynamic_threshold = best * ( 1 + threshold )
            • min模式下:dynamic_threshold = best * ( 1 - threshold )
            • rel:
            • abs:
          • cooldown:(int),每次調(diào)整lr之后,冷卻cooldown個(gè)epoch,避免lr下降過(guò)快
          • min_lr:(float or list),學(xué)習(xí)率最小值。如果給定一個(gè)標(biāo)量值,就param_groups中所有組都設(shè)置該最小值;也可以用一個(gè)list為每組指定一個(gè)最小值。
          • eps:(float),lr變化最小值,如果lr的兩次變化差距小于eps,則忽略這次變化。
          optimizer?=?torch.optim.SGD(model.parameters(),?lr=0.1,?momentum=0.9)
          scheduler?=?ReduceLROnPlateau(optimizer,?'min')
          for?epoch?in?range(10):
          ????train(...)
          ????val_loss?=?validate(...)
          ????#?Note?that?step?should?be?called?after?validate()
          ????scheduler.step(val_loss)

          如果覺(jué)得有用,就請(qǐng)分享到朋友圈吧!

          △點(diǎn)擊卡片關(guān)注極市平臺(tái),獲取最新CV干貨

          公眾號(hào)后臺(tái)回復(fù)“transformer”獲取最新Transformer綜述論文下載~


          極市干貨
          課程/比賽:珠港澳人工智能算法大賽保姆級(jí)零基礎(chǔ)人工智能教程
          算法trick目標(biāo)檢測(cè)比賽中的tricks集錦從39個(gè)kaggle競(jìng)賽中總結(jié)出來(lái)的圖像分割的Tips和Tricks
          技術(shù)綜述:一文弄懂各種loss function工業(yè)圖像異常檢測(cè)最新研究總結(jié)(2019-2020)


          #?CV技術(shù)社群邀請(qǐng)函?#

          △長(zhǎng)按添加極市小助手
          添加極市小助手微信(ID : cvmart4)

          備注:姓名-學(xué)校/公司-研究方向-城市(如:小極-北大-目標(biāo)檢測(cè)-深圳)


          即可申請(qǐng)加入極市目標(biāo)檢測(cè)/圖像分割/工業(yè)檢測(cè)/人臉/醫(yī)學(xué)影像/3D/SLAM/自動(dòng)駕駛/超分辨率/姿態(tài)估計(jì)/ReID/GAN/圖像增強(qiáng)/OCR/視頻理解等技術(shù)交流群


          每月大咖直播分享、真實(shí)項(xiàng)目需求對(duì)接、求職內(nèi)推、算法競(jìng)賽、干貨資訊匯總、與?10000+來(lái)自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺(jué)開發(fā)者互動(dòng)交流~


          覺(jué)得有用麻煩給個(gè)在看啦~??
          瀏覽 76
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美一区三区 | 色色丁香网| 天堂一区二区三区18 | 日韩无码 波多野结衣 | 啊啊啊操在线观看 |