Pytorch中的optimizer.zero_grad和loss和net.backward和optimizer.step的理解

引言

一般訓練神經網絡,總是逃不開optimizer.zero_grad之後是loss(後面有的時候還會寫forward,看你網絡怎麼寫了)之後是是net.backward之後是optimizer.step的這個過程。

real_a, real_b = batch[0].to(device), batch[1].to(device)

fake_b = net_g(real_a)
optimizer_d.zero_grad()

# 判別器對虛假數據進行訓練
fake_ab = torch.cat((real_a, fake_b), 1)
pred_fake = net_d.forward(fake_ab.detach())
loss_d_fake = criterionGAN(pred_fake, False)

# 判別器對真實數據進行訓練
real_ab = torch.cat((real_a, real_b), 1)
pred_real = net_d.forward(real_ab)
loss_d_real = criterionGAN(pred_real, True)

# 判別器損失
loss_d = (loss_d_fake + loss_d_real) * 0.5

loss_d.backward()
optimizer_d.step()

上面這是一段cGAN的判別器訓練過程。標題中所涉及到的這些方法,其實整個神經網絡的參數更新過程(特別是反向傳播),具體是怎麼操作的,我們一起來探討一下。

參數更新和反向傳播

在這裏插入圖片描述
上圖爲一個簡單的梯度下降示意圖。比如以SGD爲例,是算一個batch計算一次梯度,然後進行一次梯度更新。這裏梯度值就是對應偏導數的計算結果。顯然,我們進行下一次batch梯度計算的時候,前一個batch的梯度計算結果,沒有保留的必要了。所以在下一次梯度更新的時候,先使用optimizer.zero_grad把梯度信息設置爲0。

我們使用loss來定義損失函數,是要確定優化的目標是什麼,然後以目標爲頭,纔可以進行鏈式法則和反向傳播。

調用loss.backward方法時候,Pytorch的autograd就會自動沿着計算圖反向傳播,計算每一個葉子節點的梯度(如果某一個變量是由用戶創建的,則它爲葉子節點)。使用該方法,可以計算鏈式法則求導之後計算的結果值。

optimizer.step用來更新參數,就是圖片中下半部分的w和b的參數更新操作。

參考

[1Pytorch optimizer.step() 和loss.backward()和scheduler.step()的關係與區別
[2]torch代碼解析 爲什麼要使用optimizer.zero_grad()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章