1. 程式人生 > >PyTorch 深度學習:60分鐘快速入門(2) ----Autograd: 自動求導

PyTorch 深度學習:60分鐘快速入門(2) ----Autograd: 自動求導

PyTorch 中所有神經網路的核心是autograd包.我們首先簡單介紹一下這個包,然後訓練我們的第一個神經網路.

autograd包為張量上的所有操作提供了自動求導.它是一個執行時定義的框架,這意味著反向傳播是根據你的程式碼如何執行來定義,並且每次迭代可以不同.

接下來我們用一些簡單的示例來看這個包

Tensor

torch.Tensor是包的核心類。如果將其屬性設定 .requires_gradTrue,則會開始跟蹤其上的所有操作。完成計算後,您可以呼叫.backward()並自動計算所有梯度。該張量的梯度將累積到.grad屬性中。

要阻止張量跟蹤歷史記錄,您可以呼叫.detach()

將其與計算曆史記錄分離,並防止將來的計算被跟蹤。

要防止跟蹤歷史記錄(和使用記憶體),您還可以用with torch.no_grad():將程式碼塊包裝起來。在評估模型時,這可能特別有用,因為模型可能具有requires_grad = True的可訓練引數,但我們不需要梯度。

對自動求導的實現還有一個非常重要的類,即Function

TensorFunction是相互聯絡的,並形成一個非迴圈圖來構建一個完整的計算過程.每個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

稍後閱讀:

關於autogradFunction的文件在 http://pytorch.org/docs/autograd.