PyTorch自動求導:Autograd

PyTorch自動求導:Autograd

PyTorch中,所有神經網絡的核心是 autograd 包。autograd 包為張量上的所有操作提供了自動求導機制。它是一個在運行時定義(define-by-run)的框架,這意味著反向傳播是根據代碼如何運行來決定的,並且每次迭代可以是不同的。


張量

PyTorch自動求導:Autograd

張量:n維向量

torch.Tensor 是這個包的核心類。如果設置它的屬性 .requires_grad True,那麼它將會追蹤對於該張量的所有操作。當完成計算後可以通過調用 .backward(),來自動計算所有的梯度。這個張量的所有梯度將會自動累加到.grad屬性。

<code>x = torch.ones(2, 2, requires_grad=True #創建一個張量並設置requires_grad=True用來追蹤其計算歷史
print(x)/<code>
PyTorch自動求導:Autograd

要阻止一個張量被跟蹤歷史,可以調用 .detach() 方法將其與計算歷史分離,並阻止它未來的計算記錄被跟蹤。

PyTorch自動求導:Autograd

為了防止跟蹤歷史記錄(和使用內存),可以將代碼塊包裝在 with torch.no_grad(): 中。在評估模型時特別有用,因為模型可能具有 requires_grad = True 的可訓練的參數,但是我們不需要在此過程中對他們進行梯度計算。

還有一個類對於autograd的實現非常重要:Function

Tensor Function 互相連接生成了一個無圈圖(acyclic graph),它編碼了完整的計算歷史。每個張量都有一個 .grad_fn 屬性,該屬性引用了創建 Tensor 自身的Function(除非這個張量是用戶手動創建的,即這個張量的 grad_fn None )。

PyTorch自動求導:Autograd

如果需要計算導數,可以在 Tensor 上調用 .backward()。如果 Tensor 是一個標量(即它包含一個元素的數據),則不需要為 backward() 指定任何參數,但是如果它有更多的元素,則需要指定一個 gradient 參數,該參數是形狀匹配的張量。

<code>y = x + 2  # 對這個張量做一次運算/<code>
PyTorch自動求導:Autograd

y是計算的結果,所以它有grad_fn屬性。

PyTorch自動求導:Autograd

<code>z = y * y * 3  # 對y進行更多操作
out = z.mean()#
print(z, out)/<code>
PyTorch自動求導:Autograd

.requires_grad_(...) 原地改變了現有張量的 requires_grad 標誌。如果沒有指定的話,默認輸入的這個標誌是 False

<code>a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)/<code>
PyTorch自動求導:Autograd

梯度

PyTorch自動求導:Autograd

梯度:方向導數,函數在該點處沿著該方向(此梯度的方向)變化最快,變化率最大(為該梯度的模)。

現在開始進行反向傳播,因為 out 是一個標量,因此 out.backward() out.backward(torch.tensor(1.)) 等價。

<code>out.backward()/<code>

輸出導數 d(out)/dx

<code>print(x.grad)/<code>
PyTorch自動求導:Autograd

我們的得到的是一個數取值全部為4.5矩陣

計算步驟:

PyTorch自動求導:Autograd

PyTorch自動求導:Autograd

PyTorch自動求導:Autograd

PyTorch自動求導:Autograd

數學上,若有向量值函數 y =f(x ),那麼 y 相對於 x 的梯度是一個雅可比矩陣:


PyTorch自動求導:Autograd

通常來說,torch.autograd 是計算雅可比向量積的一個“引擎”。根據鏈式法則,雅可比向量積:


PyTorch自動求導:Autograd

雅可比向量積的這一特性使得將外部梯度輸入到具有非標量輸出的模型中變得非常方便。

現在我們來看一個雅可比向量積的例子:

<code>x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)/<code>
PyTorch自動求導:Autograd

在這種情況下,y 不再是標量。torch.autograd 不能直接計算完整的雅可比矩陣,但是如果我們只想要雅可比向量積,只需將這個向量作為參數傳給 backward

<code>v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)/<code>
PyTorch自動求導:Autograd

也可以通過將代碼塊包裝在 with torch.no_grad(): 中,來阻止

autograd跟蹤設置了 .requires_grad=True 的張量的歷史記錄。

<code>print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)/<code>
PyTorch自動求導:Autograd


分享到:


相關文章: