最近對pytorch的梯度計算產生了一點興趣,然後現在就總結一下,我看到的幾篇講得挺好的博客。
創建帶有grad的tensor
input = torch.tensor([1., 2., 3., 4.,], requires_grad=True)
參看tensor,是否帶有grad
print(input.requires_grad)
參看tensor中的grad值
print(input.grad)
不過模型的輸入tensor一般不使用grad,而是將模型參數空間輸入到優化器中,然後通過loss.backward()去根據模型參數空間中的梯度,自動更新模型參數。
optimizer = Adam(model.parameters(), lr=LR) # 輸入參數空間,定義優化器
然後就是常用的
loss.backward()
optimizer.step()
這便是更新模型參數空間中的參數。一般這兩行代碼是放在batch裏面的,爲的是將每一個batch的訓練都看做獨立的一次訓練。
另外,在執行這兩行代碼之前,需要將參數空間中的梯度清零,防止上次的留存梯度,對本次的訓練產生影響。
optimizer.zero_grad()
組合起來的順序是
optimizer = Adam(model.parameters(), lr=LR) #定義優化器
optimizer.zero_grad()#將梯度初始化爲零
outputs = net(inputs)#前向傳播求出預測值
loss = criterion(outputs, labels)#求損失值
loss.backward()#反向傳播求梯度
optimizer.step()#更新所有參數
此外,如果你希望能夠查看模型中參數的梯度可以
loss.backward()
for name_1, param_1 in self.manhattan_lstm.named_parameters():
print(name_1,param_1.grad)
記住,在反向傳播後面,否則輸出爲None,原因是loss.backward()之前,都還沒有計算,自然是沒有的。
如果想看參數的值可以
for name_1, param_1 in self.manhattan_lstm.named_parameters():
print(name_1,param_1.data)
參考博客
深入Pytorch中的Tensor,梯度以及權重
torch代碼解析 爲什麼要使用optimizer.zero_grad()
Pytorch optimizer.step() 和loss.backward()和scheduler.step()的關係與區別 (Pytorch 代碼講解)