https://blog.csdn.net/PanYHHH/article/details/107361827
一、
第一個是將梯度清零,因為訓練的過程通常使用mini-batch方法,所以如果不將梯度清零的話,梯度會與上一個batch的數據相關,因此該函數要寫在反向傳播和梯度下降之前。(訓練的時候要分為多個batch)
optimizer.zero_grad()函數會遍歷模型的所有參數,通過p.grad.detach_()方法截斷反向傳播的梯度流,再通過p.grad.zero_()函數將每個參數的梯度值設為0,即上一次的梯度記錄被清空。
二、
PyTorch的反向傳播(即tensor.backward())是通過autograd包來實現的,autograd包會根據tensor進行過的數學運算來自動計算其對應的梯度。
具體來說,torch.tensor是autograd包的基礎類,如果你設置tensor的requires_grads為True,就會開始跟蹤這個tensor上面的所有運算,如果你做完運算后使用tensor.backward(),所有的梯度就會自動運算,tensor的梯度將會累加到它的.grad屬性里面去。
更具體地說,損失函數loss是由模型的所有權重w經過一系列運算得到的,若某個w的requires_grads為True,則w的所有上層參數(后面層的權重w)的.grad_fn屬性中就保存了對應的運算,然后在使用loss.backward()后,會一層層的反向傳播計算每個w的梯度值,並保存到該w的.grad屬性中。
如果沒有進行tensor.backward()的話,梯度值將會是None,因此loss.backward()要寫在optimizer.step()之前。
三、
step()函數的作用是執行一次優化步驟,通過梯度下降法來更新參數的值。因為梯度下降是基於梯度的,所以在執行optimizer.step()函數前應先執行loss.backward()函數來計算梯度。
注意:optimizer只負責通過梯度下降進行優化,而不負責產生梯度,梯度是tensor.backward()方法產生的。