%matplotlib inline
PyTorch 中全部神經網絡的核心是 autograd
包。
咱們先簡單介紹一下這個包,而後訓練第一個簡單的神經網絡。html
autograd
包爲張量上的全部操做提供了自動求導。
它是一個在運行時定義的框架,這意味着反向傳播是根據你的代碼來肯定如何運行,而且每次迭代能夠是不一樣的。python
示例網絡
torch.Tensor
是這個包的核心類。若是設置
.requires_grad
爲 True
,那麼將會追蹤全部對於該張量的操做。
當完成計算後經過調用 .backward()
,自動計算全部的梯度,
這個張量的全部梯度將會自動積累到 .grad
屬性。框架
要阻止張量跟蹤歷史記錄,能夠調用.detach()
方法將其與計算曆史記錄分離,並禁止跟蹤它未來的計算記錄。ui
爲了防止跟蹤歷史記錄(和使用內存),能夠將代碼塊包裝在with torch.no_grad():
中。
在評估模型時特別有用,由於模型可能具備requires_grad = True
的可訓練參數,可是咱們不須要梯度計算。spa
在自動梯度計算中還有另一個重要的類Function
.scala
Tensor
and Function
are interconnected and build up an acyclic
graph, that encodes a complete history of computation. Each tensor has
a .grad_fn
attribute that references a Function
that has created
the Tensor
(except for Tensors created by the user - their
grad_fn is None
).code
Tensor
和 Function
互相鏈接並生成一個非循環圖,它表示和存儲了完整的計算曆史。
每一個張量都有一個.grad_fn
屬性,這個屬性引用了一個建立了Tensor
的Function
(除非這個張量是用戶手動建立的,即,這個張量的
grad_fn
是 None
)。orm
若是須要計算導數,你能夠在Tensor
上調用.backward()
。
若是Tensor
是一個標量(即它包含一個元素數據)則不須要爲backward()
指定任何參數,
可是若是它有更多的元素,你須要指定一個gradient
參數來匹配張量的形狀。htm
譯者注:在其餘的文章中你可能會看到說將Tensor包裹到Variable中提供自動梯度計算,Variable 這個在0.41版中已經被標註爲過時了,如今能夠直接使用Tensor,官方文檔在這裏:
(https://pytorch.org/docs/stable/autograd.html#variable-deprecated)
具體的後面會有詳細說明
import torch
建立一個張量並設置 requires_grad=True 用來追蹤他的計算曆史
x = torch.ones(2, 2, requires_grad=True) print(x)
tensor([[1., 1.], [1., 1.]], requires_grad=True)
對張量進行操做:
y = x + 2 print(y)
tensor([[3., 3.], [3., 3.]], grad_fn=<AddBackward>)
結果y
已經被計算出來了,因此,grad_fn
已經被自動生成了。
print(y.grad_fn)
<AddBackward object at 0x00000232535FD860>
對y進行一個操做
z = y * y * 3 out = z.mean() print(z, out)
tensor([[27., 27.], [27., 27.]], grad_fn=<MulBackward>) tensor(27., grad_fn=<MeanBackward1>)
.requires_grad_( ... )
能夠改變現有張量的 requires_grad
屬性。
若是沒有指定的話,默認輸入的flag是 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 0x000002325360B438>
反向傳播
由於 out
是一個純量(scalar),out.backward()
等於out.backward(torch.tensor(1))
。
out.backward()
print gradients d(out)/dx
print(x.grad)
tensor([[4.5000, 4.5000], [4.5000, 4.5000]])
獲得矩陣 4.5
.調用 out
Tensor 「\(o\)」.
獲得 \(o = \frac{1}{4}\sum_i z_i\),
\(z_i = 3(x_i+2)^2\) and \(z_i\bigr\rvert_{x_i=1} = 27\).
所以,
\(\frac{\partial o}{\partial x_i} = \frac{3}{2}(x_i+2)\), hence
\(\frac{\partial o}{\partial x_i}\bigr\rvert_{x_i=1} = \frac{9}{2} = 4.5\).
可使用 autograd 作更多的操做
x = torch.randn(3, requires_grad=True) y = x * 2 while y.data.norm() < 1000: y = y * 2 print(y)
tensor([-920.6895, -115.7301, -867.6995], grad_fn=<MulBackward>)
gradients = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float) y.backward(gradients) print(x.grad)
tensor([ 51.2000, 512.0000, 0.0512])
若是.requires_grad=True
可是你又不但願進行autograd的計算,
那麼能夠將變量包裹在 with torch.no_grad()
中:
print(x.requires_grad) print((x ** 2).requires_grad) with torch.no_grad(): print((x ** 2).requires_grad)
True True False
稍後閱讀:
autograd
和 Function
的官方文檔 https://pytorch.org/docs/autograd