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