W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
原文:?https://///pytorch.org/tutorials/beginner/blitz/tensor_tutorial.html
譯者:?bat67
驗證者:?FontTian
作者:??Soumith Chintala
PyTorch中,所有神經(jīng)網(wǎng)絡(luò)的核心是autograd
包。先簡單介紹一下這個包,然后訓(xùn)練我們的第一個的神經(jīng)網(wǎng)絡(luò)。
autograd
包為張量上的所有操作提供了自動求導(dǎo)機(jī)制。它是一個在運(yùn)行時定義(define-by-run)的框架,這意味著反向傳播是根據(jù)代碼如何運(yùn)行來決定的,并且每次迭代可以是不同的.
讓我們用一些簡單的例子來看看吧。
torch.Tensor
是這個包的核心類。如果設(shè)置它的屬性?.requires_grad
為True
,那么它將會追蹤對于該張量的所有操作。當(dāng)完成計算后可以通過調(diào)用.backward()
,來自動計算所有的梯度。這個張量的所有梯度將會自動累加到.grad
屬性.
要阻止一個張量被跟蹤歷史,可以調(diào)用.detach()
方法將其與計算歷史分離,并阻止它未來的計算記錄被跟蹤。
為了防止跟蹤歷史記錄(和使用內(nèi)存),可以將代碼塊包裝在with torch.no_grad():
中。在評估模型時特別有用,因為模型可能具有requires_grad = True
的可訓(xùn)練的參數(shù),但是我們不需要在此過程中對他們進(jìn)行梯度計算。
還有一個類對于autograd的實現(xiàn)非常重要:Function
。
Tensor
和Function
互相連接生成了一個非循環(huán)圖,它編碼了完整的計算歷史。每個張量都有一個.grad_fn
屬性,它引用了一個創(chuàng)建了這個Tensor
的Function
(除非這個張量是用戶手動創(chuàng)建的,即這個張量的grad_fn
是None
)。
如果需要計算導(dǎo)數(shù),可以在Tensor
上調(diào)用.backward()
。如果Tensor
是一個標(biāo)量(即它包含一個元素的數(shù)據(jù)),則不需要為backward()
指定任何參數(shù),但是如果它有更多的元素,則需要指定一個gradient
參數(shù),它是形狀匹配的張量。
import torch
創(chuàng)建一個張量并設(shè)置requires_grad=True
用來追蹤其計算歷史
x = torch.ones(2, 2, requires_grad=True)
print(x)
輸出:
tensor([[1., 1.],
[1., 1.]], requires_grad=True)
對這個張量做一次運(yùn)算:
y = x + 2
print(y)
輸出:
tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward0>)
y
是計算的結(jié)果,所以它有grad_fn
屬性。
print(y.grad_fn)
輸出:
<AddBackward0 object at 0x7f1b248453c8>
對y進(jìn)行更多操作
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_(...)
?原地改變了現(xiàn)有張量的?requires_grad
?標(biāo)志。如果沒有指定的話,默認(rèn)輸入的這個標(biāo)志是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 0x7f1b24845f98>
因為out
是一個標(biāo)量。所以讓我們直接進(jìn)行反向傳播,out.backward()
和out.backward(torch.tensor(1.))
等價
out.backward()
輸出導(dǎo)數(shù)d(out)/dx
print(x.grad)
輸出:
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
計算過程如下,實質(zhì)就是一個標(biāo)量函數(shù)對于各個分量求偏導(dǎo)數(shù)
數(shù)學(xué)上,若有向量值函數(shù)y=f(x),那么y相對于x的梯度是一個雅各比矩陣:
通常來說,torch.autograd是計算雅各比向量積的一個“引擎”。也就是說,給定任意向量V=
計算乘積J.v。如果v恰好是一個標(biāo)量函數(shù)
即V=
根據(jù)鏈?zhǔn)椒▌t,雅克比向量積應(yīng)該是l對x的導(dǎo)數(shù)
雅可比向量積的這一特性使得將外部梯度輸入到具有非標(biāo)量輸出的模型中變得非常方便。 現(xiàn)在我們來看一個雅可比向量積的例子:
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)
輸出:
tensor([-278.6740, 935.4016, 439.6572], grad_fn=<MulBackward0>)
在這種情況下,y
不再是標(biāo)量。torch.autograd
不能直接計算完整的雅可比矩陣,但是如果我們只想要雅可比向量積,只需將這個向量作為參數(shù)傳給backward
:
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
輸出:
tensor([4.0960e+02, 4.0960e+03, 4.0960e-01])
為了防止跟蹤歷史記錄(和使用內(nèi)存),可以將代碼塊包裝在with torch.no_grad():
中。在評估模型時特別有用,因為模型可能具有requires_grad = True
的可訓(xùn)練的參數(shù),但是我們不需要在此過程中對他們進(jìn)行梯度計算。
也可以通過將代碼塊包裝在?with torch.no_grad():
?中,來阻止autograd跟蹤設(shè)置了?.requires_grad=True
?的張量的歷史記錄。
print(x.requires_grad)
print((x ** 2).requires_grad)
with torch.no_grad():
print((x ** 2).requires_grad)
輸出:
True
True
False
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: