五月综合激情婷婷六月,日韩欧美国产一区不卡,他扒开我内裤强吻我下面视频 ,无套内射无矿码免费看黄,天天躁,日日躁,狠狠躁

新聞動態(tài)

聊聊pytorch中Optimizer與optimizer.step()的用法

發(fā)布日期:2022-03-29 15:07 | 文章來源:源碼中國

當我們想指定每一層的學(xué)習(xí)率時:

optim.SGD([
  {'params': model.base.parameters()},
  {'params': model.classifier.parameters(), 'lr': 1e-3}
 ], lr=1e-2, momentum=0.9)

這意味著model.base的參數(shù)將會使用1e-2的學(xué)習(xí)率,model.classifier的參數(shù)將會使用1e-3的學(xué)習(xí)率,并且0.9的momentum將會被用于所有的參數(shù)。

進行單次優(yōu)化

所有的optimizer都實現(xiàn)了step()方法,這個方法會更新所有的參數(shù)。它能按兩種方式來使用:

optimizer.step()

這是大多數(shù)optimizer所支持的簡化版本。一旦梯度被如backward()之類的函數(shù)計算好后,我們就可以調(diào)用這個函數(shù)。

例子

for input, target in dataset:
  optimizer.zero_grad()
  output = model(input)
  loss = loss_fn(output, target)
  loss.backward()
  optimizer.step()
optimizer.step(closure)

一些優(yōu)化算法例如Conjugate Gradient和LBFGS需要重復(fù)多次計算函數(shù),因此你需要傳入一個閉包去允許它們重新計算你的模型。這個閉包應(yīng)當清空梯度,計算損失,然后返回。

例子:

for input, target in dataset:
 def closure():
  optimizer.zero_grad()
  output = model(input)
  loss = loss_fn(output, target)
  loss.backward()
  return loss
 optimizer.step(closure)

補充:Pytorch optimizer.step() 和loss.backward()和scheduler.step()的關(guān)系與區(qū)別

首先需要明確optimzier優(yōu)化器的作用, 形象地來說,優(yōu)化器就是需要根據(jù)網(wǎng)絡(luò)反向傳播的梯度信息來更新網(wǎng)絡(luò)的參數(shù),以起到降低loss函數(shù)計算值的作用,這也是機器學(xué)習(xí)里面最一般的方法論。

從優(yōu)化器的作用出發(fā),要使得優(yōu)化器能夠起作用,需要主要兩個東西:

1. 優(yōu)化器需要知道當前的網(wǎng)絡(luò)或者別的什么模型的參數(shù)空間

這也就是為什么在訓(xùn)練文件中,正式開始訓(xùn)練之前需要將網(wǎng)絡(luò)的參數(shù)放到優(yōu)化器里面,比如使用pytorch的話總會出現(xiàn)類似如下的代碼:

optimizer_G = Adam(model_G.parameters(), lr=train_c.lr_G)# lr 使用的是初始lr
optimizer_D = Adam(model_D.parameters(), lr=train_c.lr_D)

2. 需要知道反向傳播的梯度信息

我們還是從代碼入手,如下所示是Pytorch 中SGD優(yōu)化算法的step()函數(shù)具體寫法,具體SGD的寫法放在參考部分。

def step(self, closure=None):
"""Performs a single optimization step.
Arguments:
 closure (callable, optional): A closure that reevaluates the model
  and returns the loss.
"""
loss = None
if closure is not None:
 loss = closure()
  
for group in self.param_groups:
 weight_decay = group['weight_decay']
 momentum = group['momentum']
 dampening = group['dampening']
 nesterov = group['nesterov']
  
 for p in group['params']:
  if p.grad is None:continue
  d_p = p.grad.data
  if weight_decay != 0:d_p.add_(weight_decay, p.data)
  if momentum != 0:param_state = self.state[p]if 'momentum_buffer' not in param_state:
buf = param_state['momentum_buffer'] = d_p.clone()else:
buf = param_state['momentum_buffer']
buf.mul_(momentum).add_(1 - dampening, d_p)if nesterov:
d_p = d_p.add(momentum, buf)else:
d_p = buf  
  p.data.add_(-group['lr'], d_p)  
return loss

從上面的代碼可以看到step這個函數(shù)使用的是參數(shù)空間(param_groups)中的grad,也就是當前參數(shù)空間對應(yīng)的梯度,這也就解釋了為什么optimzier使用之前需要zero清零一下,因為如果不清零,那么使用的這個grad就得同上一個mini-batch有關(guān),這不是我們需要的結(jié)果。

再回過頭來看,我們知道optimizer更新參數(shù)空間需要基于反向梯度,因此,當調(diào)用optimizer.step()的時候應(yīng)當是loss.backward()的時候,這也就是經(jīng)常會碰到,如下情況

total_loss.backward()
optimizer_G.step()

loss.backward()在前,然后跟一個step。

那么為什么optimizer.step()需要放在每一個batch訓(xùn)練中,而不是epoch訓(xùn)練中,這是因為現(xiàn)在的mini-batch訓(xùn)練模式是假定每一個訓(xùn)練集就只有mini-batch這樣大,因此實際上可以將每一次mini-batch看做是一次訓(xùn)練,一次訓(xùn)練更新一次參數(shù)空間,因而optimizer.step()放在這里。

scheduler.step()按照Pytorch的定義是用來更新優(yōu)化器的學(xué)習(xí)率的,一般是按照epoch為單位進行更換,即多少個epoch后更換一次學(xué)習(xí)率,因而scheduler.step()放在epoch這個大循環(huán)下。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持本站。

美國服務(wù)器租用

版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部