使用autograd來自動(dòng)求導(dǎo)
在機(jī)器學(xué)習(xí)中闹司,我們通常使用梯度下降來更新模型參數(shù)從而求解。損失函數(shù)關(guān)于模型參數(shù)的梯度指向一個(gè)可以降低損失函數(shù)值的方向灰嫉,我們不斷地沿著梯度的方向更新模型從而最小化損失函數(shù)扼倘。雖然梯度計(jì)算比較直觀,但對(duì)于復(fù)雜的模型需五,例如多達(dá)數(shù)十層的神經(jīng)網(wǎng)絡(luò)鹉动,手動(dòng)計(jì)算梯度非常困難。
PyTorch使用autograd
程序包提供自動(dòng)求導(dǎo)宏邮。
Variable
autograd.Variable()
是這個(gè)程序包的核心類泽示。封裝了一個(gè)Tensor和它上的所有運(yùn)算。一旦完成計(jì)算可以調(diào)用.backward()
自動(dòng)計(jì)算所有梯度蜜氨。
屬性.data
訪問tensor
屬性.grad
變量的梯度
我們先導(dǎo)入
autograd
械筛。
import torch
form torch.autograd import Variable
創(chuàng)建一個(gè)變量:
x = Variable(torch.arange(1, 5).resize_(2, 2), requires_grad=True)
print(x)
Variable containing:
1 2
3 4
[torch.FloatTensor of size 2x2]
變量上運(yùn)算:
y = x * 2
z = y * x
print(z)
Variable containing:
2 8
18 32
[torch.FloatTensor of size 2x2]
接下來我們可以通過z.backward()
來進(jìn)行求導(dǎo),這里z不是一個(gè)標(biāo)量飒炎,所以使用torch.sum(z).backward()
torch.sum(z).backward()
print(x.grad)
Variable containing:
4 8
12 16
[torch.FloatTensor of size 2x2]
對(duì)控制流求導(dǎo)
命令式的編程的一個(gè)便利之處是幾乎可以對(duì)任意的可導(dǎo)程序進(jìn)行求導(dǎo)埋哟,即使里面包含了Python的控制流±赏簦考慮下面程序赤赊,里面包含控制流for和if闯狱,但循環(huán)迭代的次數(shù)和判斷語句的執(zhí)行都是取決于輸入的值。不同的輸入會(huì)導(dǎo)致這個(gè)程序的執(zhí)行不一樣砍鸠。(對(duì)于計(jì)算圖框架來說扩氢,這個(gè)對(duì)應(yīng)于動(dòng)態(tài)圖,就是圖的結(jié)構(gòu)會(huì)根據(jù)輸入數(shù)據(jù)不同而改變)爷辱。
def f(a):
b = a * 2
while torch.norm(b.data) < 1000:
b = b * 2
if torch.sum(b.data) > 0:
c = b
else:
c = 100 * b
return c
x = Variable(torch.randn(3), requires_grad=True)
c = f(x)
torch.sum(c).backward()
print(x.grad == c/x)
Variable containing:
1
1
1
[torch.ByteTensor of size 3]