PyTorch 深度學習:60分鐘快速入門(2) ----Autograd: 自動求導
PyTorch 中所有神經網路的核心是autograd
包.我們首先簡單介紹一下這個包,然後訓練我們的第一個神經網路.
autograd
包為張量上的所有操作提供了自動求導.它是一個執行時定義的框架,這意味著反向傳播是根據你的程式碼如何執行來定義,並且每次迭代可以不同.
接下來我們用一些簡單的示例來看這個包
Tensor
torch.Tensor
是包的核心類。如果將其屬性設定 .requires_grad
為True
,則會開始跟蹤其上的所有操作。完成計算後,您可以呼叫.backward()
並自動計算所有梯度。該張量的梯度將累積到.grad
屬性中。
要阻止張量跟蹤歷史記錄,您可以呼叫.detach()
要防止跟蹤歷史記錄(和使用記憶體),您還可以用with torch.no_grad():
將程式碼塊包裝起來。在評估模型時,這可能特別有用,因為模型可能具有requires_grad = True
的可訓練引數,但我們不需要梯度。
對自動求導的實現還有一個非常重要的類,即Function
Tensor
和Function
是相互聯絡的,並形成一個非迴圈圖來構建一個完整的計算過程.每個tensor
有一個.grad_fn
屬性,它指向建立該變數的一個Function
,使用者自己建立的tensor
除外,它的grad_fn
屬性為None
.
如果你想計算導數,可以在一個tensor
.backward()
.如果一個tensor
是一個標量(它只有一個元素值),你不必給該方法指定任何的引數,但是如果該tensor
有多個值,你需要指定一個和該tensor
相同形狀的gradient
引數去匹配
import torch
建立一個變數並設定requires_grad=True
去跟蹤計算
x = torch.ones(2, 2, requires_grad=True)
print(x)
輸出:
tensor([[1., 1.],
[1., 1.]], requires_grad=True)
在tensor上執行操作:
y = x + 2 print(y)
輸出:
tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward0>)
因為y
是通過一個操作建立的,所以它有grad_fn
print(y.grad_fn)
輸出:
<AddBackward0 object at 0x7fe1db427470>
在y上執行更多的操作
z = y * y * 3
out = z.mean()
print(z, out)
輸出:
tensor([[27., 27.],
[27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)
.requires_grad_( ... )
會原地改變一個已存在tensor的 requires_grad
標誌.如果沒提供的話,預設是False
.
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)
輸出:
False
True
<SumBackward0 object at 0x7fe1db427dd8>
梯度
現在我們來執行反向傳播,out.backward()
相當於執行out.backward(torch.tensor(1.))
out.backward()
計算d(out)/dx的梯度
print(x.grad)
輸出:
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
這段就不翻譯了,主要是他的那些數學表示式複製不下來,具體就是一個雅克比矩陣,想了解的可以google一下
現在讓我們來看一個雅可比向量積的例子:
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)
輸出:
tensor([ -444.6791, 762.9810, -1690.0941], grad_fn=<MulBackward0>)
現在在這種情況下y
不再是標量。torch.autograd
無法直接計算完整雅可比行列式,但如果我們只想要雅可比向量乘積,只需將向量傳遞給 backward
引數
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
輸出:
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])
你還可以通過將程式碼塊包裝在以下內容autograd :with torch.no_grad()
來停止在Tensors上跟蹤歷史記錄
print(x.requires_grad)
print((x ** 2).requires_grad)
with torch.no_grad():
print((x ** 2).requires_grad)
輸出:
True
True
False
稍後閱讀:
關於
autograd
和Function
的文件在 http://pytorch.org/docs/autograd.