您好,登錄后才能下訂單哦!
基礎知識
tensors:
tensor在pytorch里面是一個n維數組。我們可以通過指定參數reuqires_grad=True來建立一個反向傳播圖,從而能夠計算梯度。在pytorch中一般叫做dynamic computation graph(DCG)——即動態計算圖。
import torch import numpy as np # 方式一 x = torch.randn(2,2, requires_grad=True) # 方式二 x = torch.autograd.Variable(torch.Tensor([2,3]), requires_grad=True) #方式三 x = torch.tensor([2,3], requires_grad=True, dtype=torch.float64) # 方式四 x = np.array([1,2,3] ,dtype=np.float64) x = torch.from_numpy(x) x.requires_grad = True # 或者 x.requires_grad_(True)
note1:在pytorch中,只有浮點類型的數才有梯度,故在方法四中指定np數組的類型為float類型。為什么torch.Tensor中不需要呢,可以通過以下代碼驗證
import torch import numpy as np a = torch.Tensor([2,3]) print(a.dtype) # torch.floaat32 b = torch.tensor([2,3]) print(b.dtype) # torch.int64 c = np.array(2,3) print(c.dtype) # int64
note2pytorch中tensor與Tensor的區別是什么?這兩個看起來如此相似。
首先,torch.Tensor是一個類,所有的tensor都是Tensor的一個實例;而torch.tensor是一個函數。這也說明了為什么使用torch.Tensor()沒有問題而torch.tensor()卻有問題。
其次,torch.tensor主要是將一個data封裝成tensor,并且可以指定requires_grad。
torch.tensor(data,dtype=None,device=None,requires_grad=False) - > Tensor
最后,我們更多地使用torch.tensor,我們可以通過使用torch.tensor(())來達到與torch.Tensor()同樣的效果。
具體可參考torch.tensor與torch.Tensor的區別
Dynamic Computational graph
我們來看一個計算圖
我們 來看一個計算圖 解釋一下各個屬性的含義,
data: 變量中存儲的值,如x中存儲著1,y中存儲著2,z中存儲著3
requires_grad:該變量有兩個值,True 或者 False,如果為True,則加入到反向傳播圖中參與計算。
grad:該屬性存儲著相關的梯度值。當requires_grad為False時,該屬性為None。即使requires_grad為True,也必須在調用其他節點的backward()之后,該變量的grad才會保存相關的梯度值。否則為None
grad_fn:表示用于計算梯度的函數。
is_leaf:為True或者False,表示該節點是否為葉子節點。
當調用backward函數時,只有requires_grad為true以及is_leaf為true的節點才會被計算梯度,即grad屬性才會被賦予值。
梯度計算
examples
運算結果變量的requires_grad取決于輸入變量。例如:當變量z的requires_grad屬性為True時,為了求得z的梯度,那么變量b的requires_grad就必須為true了,而變量x,y,a的requires_grad屬性都為False。
將事先創建的變量,如x、y、z稱為創建變量;像a、b這樣由其他變量運算得到的稱為結果變量。
from torch.autograd import Variable x = Variable(torch.randn(2,2)) y = Variable(torch.randn(2,2)) z = Variable(torch.randn(2,2), requires_grad=True) a = x+y b = a+z print(x.requires_grad, y.requires_grad, z.requires_grad) # False, False, True print(a.requires_grad, b.requires_grad) # False, True print(x.requires_grad) # True print(a.requires_grad) # True
調用backward()計算梯度
import torch as t from torch.autograd import Variable as v a = v(t.FloatTensor([2, 3]), requires_grad=True) b = a + 3 c = b * b * 3 out = c.mean() out.backward(retain_graph=True) # 這里可以不帶參數,默認值為‘1',由于下面我們還要求導,故加上retain_graph=True選項 print(a.grad) # tensor([15., 18.])
backward中的gradient參數使用
a. 最后的結果變量為標量(scalar)
如第二個例子,通過調用out.backward()實現對a的求導,這里默認調用了out.backward(gradient=None)或者指定為out.backward(gradient=torch.Tensor([1.0])
b. 最后的結果變量為向量(vector)
import torch from torch.autograd import Variable as V m = V(torch.FloatTensor([2, 3]), requires_grad=True) # 注意這里有兩層括號,非標量 n = V(torch.zeros(2)) n[0] = m[0] ** 2 n[1] = m[1] ** 3 n.backward(gradient=torch.Tensor([1,1]), retain_graph=True) print(m.grad)
結果為:
tensor([ 4., 27.])
如果使用n.backward()的話,那么就會報如下的錯:RuntimeError: grad can be implicitly created only for scalar outputs
注意:這里的gradient的維度必須與n的維度相同。其中的原理如下:
在執行z.backward(gradient)的時候,如果z不是一個標量,那么先構造一個標量的值:L = torch.sum(z*gradient),再計算關于L對各個leaf Variable的梯度。
以上這篇pytorch的梯度計算以及backward方法詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。