Pytorch autograd 自動求導

2022-09-17 04:00:12 字數 2767 閱讀 6400

神經網路離不開大量的梯度求導,若是交給人為計算,這將是十分耗時的一件事情。在pytorch中,autograd自動求導系統能有效解決這一問題。

torch.autograd.backward()

(標量或向量的backward()方法實則也是呼叫了autograd.backward()方法)

功能:自動求取梯度

tensors:用於求導的張量,如loss

retain_graph:儲存計算圖(pytorch採用的是動態圖機制,所以在一次反向傳播結束時會釋放掉計算圖的記憶體,如果需要繼續使用計算圖,也即需要再次執行反向傳播,需使retain_graph為true,否則再次執行時會報錯)

create_graph:建立導數計算圖,用於高階求導

grad_tensors:多梯度權重(當使用多個損失函式作為loss時,即loss不是標量,而是向量,需要給每個函式設定一定的權重比例)

舉例grad_tensors:(注意,這裡為張量的backward(),其 gradient 對應傳入 torch.autograd.backward()中的grad_tensors)

w = torch.tensor([1.], requires_grad=true)

x = torch.tensor([2.], requires_grad=true)

a = torch.add(w, x) # retain_grad()

b = torch.add(w, 1)

y0 = torch.mul(a, b) # y0 = (x+w) * (w+1)

y1 = torch.add(a, b) # y1 = (x+w) + (w+1) dy1/dw = 2

loss = torch.cat([y0, y1], dim=0) # [y0, y1]

grad_tensors = torch.tensor([1., 2.])

loss.backward(gradient=grad_tensors) # gradient 傳入 torch.autograd.backward()中的grad_tensors

print(w.grad) #執行結果為 tensor([9.]) 大家可以自己演算驗證一下

torch.autograd.grad()

功能: 求取梯度

outputs:用於求導的張量,如loss,即導數分式的分子

inputs:需要梯度的張量,如w,即導數分式的分母

retain_graph:儲存計算圖

create_graph:建立導數計算圖,用於高階求導

grad_tensors:多梯度權重

下為乙個二階求導的例子:(因為需要再次求導,所以create_graph需為true)

x = torch.tensor([3.], requires_grad=true)

y = torch.pow(x, 2) # y = x**2

grad_1 = torch.autograd.grad(y, x, create_graph=true) # grad_1 = dy/dx = 2x = 2 * 3 = 6

print(grad_1)

grad_2 = torch.autograd.grad(grad_1[0], x) # grad_2 = d(dy/dx)/dx = d(2x)/dx = 2

print(grad_2)

關於autograd的一些注意的地方:

1.梯度不會自動清零,換句話說,梯度會預設進行累加

簡單見解:

由於pytorch的動態圖和autograd機制使得其非常靈活,這也意味著你可以得到對乙個張量的梯度,然後再次用該梯度進行計算,然後又可重新計算對新操作的梯度,對於何時停止前向操作並沒有乙個確定的點。所以自動設定梯度為0比較棘手,因為你不知道什麼時候乙個計算會結束以及什麼時候又會有乙個新的開始。

預設累加的好處是當在多工中對前面共享部分的tensor進行了多次計算操作後,呼叫不同任務loss的backward,那些tensor的梯度會自動累加,缺點是當你不想先前的梯度影響到當前梯度的計算時需要手動清零。

具體解釋可以參考另一篇文章:

所以需要手動清零,使用w.grad.zero_()即可清零 

2.依賴與葉子結點的結點,require_grad預設為true

3.葉子結點不可執行in-place操作

in-place表示在原記憶體上修改資料的操作,可以通過下面的例子簡單了解一下

a = torch.ones((1, ))    #  結果   2079242876320 tensor([1.])

print(id(a), a)

# a = a + torch.ones((1, )) # 結果 2079241269080 tensor([2.])

# print(id(a), a)

a += torch.ones((1, )) # 結果 2079242876320 tensor([2.])

print(id(a), a)

可見a=a+1的賦值方式不是in-place,而a+=1為in-place方式

葉子結點為什麼不能in-place就是因為葉子結點的值在反向傳播時需要被用於相關聯張量的梯度求導,改變值會在反向傳播時引起歧義衝突。改變可以用w.data.add_()

pytorch中Variable的自動求導

pytorch中variable這個變數具有自動求導功能,只需要在引數列表中加入 requires grad true 舉個例子 我們如下定義 我們對矩陣進行簡單的求導var 12 34 var begin 1 2 3 4 end var 1 3 24 我們對該矩陣平方的均值進行求導,從而有如下的表...

PyTorch學習筆記 自動求梯度

在深度學習中,我們經常需要對函式求梯度 gradient pytorch提供的autograd包能夠根據輸 和前向傳播過程自動構建計算圖,並執 反向傳播。本節將介紹如何使用autograd包來進 自動求梯度的有關操作。建立 個tensor並設定requires grad屬性為true x torch...

動手深度學習 自動求梯度 3

在深度學習中,我們經常需要對函式求梯度 gradient 本節將介紹如何使用mxnet提供的autograd模組來自動求梯度。通過下面的 匯入autograd模組 from mxnet import autograd我們先來看乙個簡單的例子,如何使用mxnet來求解y 2 xt xy 2x t x ...