一辣吃、autograd自動微分
假如我們有一個向量x=(1,1)當(dāng)成input,經(jīng)過一系列運(yùn)算得到了output變量y芬探,如下圖所示:
我們想要求y關(guān)于x的微分時羡玛,pytorch會幫我們自動求解稼稿。
>>>from torch.autograd import Variable
>>>import torch
>>>x = Variable(torch.ones(2), requires_grad = True) #vairable是tensor的一個外包裝
>>>z=4*x*x
>>>y=z.norm()
>>>y
Variable containing:
5.6569
[torch.FloatTensor of size 1]
我們可以看到y(tǒng)的值與我們上圖計(jì)算的結(jié)果一致。
>>>y.backward() ? #backward()函數(shù)表示backprop
>>>x.grad ? ?#返回y關(guān)于x的梯度向量
Variable containing:
5.6569
5.6569
[torch.FloatTensor of size 2]
我們可以看到x.grad也與我們上圖計(jì)算結(jié)果一致。
需要注意:autograd是專門為了BP算法設(shè)計(jì)的倚评,所以這autograd只對輸出值為標(biāo)量的有用,因?yàn)閾p失函數(shù)的輸出是一個標(biāo)量呢岗。如果y是一個向量,那么backward()函數(shù)就會失效挫酿。不知道BP算法是什么的同學(xué),估計(jì)也不知道什么是深度學(xué)習(xí)葱弟,建議先看Zen君提供的教材。
二妖混、autograd的內(nèi)部機(jī)理
我們之所以可以實(shí)現(xiàn)autograd多虧了Variable和Function這兩種數(shù)據(jù)類型的功勞。要進(jìn)行autograd必需先將tensor數(shù)據(jù)包成Variable祥楣。Varibale和tensor基本一致碾褂,所區(qū)別在于多了下面幾個屬性正塌。
variable和function它們是彼此不分開的,先上圖:
如圖,假設(shè)我們有一個輸入變量input(數(shù)據(jù)類型為Variable)input是用戶輸入的,所以其創(chuàng)造者creator為null值周偎,input經(jīng)過第一個數(shù)據(jù)操作operation1(比如加減乘除運(yùn)算)得到output1變量(數(shù)據(jù)類型仍為Variable)澳眷,這個過程中會自動生成一個function1的變量(數(shù)據(jù)類型為Function的一個實(shí)例),而output1的創(chuàng)造者就是這個function1拓瞪。隨后,output1再經(jīng)過一個數(shù)據(jù)操作生成output2沟堡,這個過程也會生成另外一個實(shí)例function2屁药,output2的創(chuàng)造者creator為function2复亏。
在這個向前傳播的過程中,function1和function2記錄了數(shù)據(jù)input的所有操作歷史,當(dāng)output2運(yùn)行其backward函數(shù)時眷茁,會使得function2和function1自動反向計(jì)算input的導(dǎo)數(shù)值并存儲在grad屬性中上祈。
creator為null的變量才能被返回導(dǎo)數(shù),比如input节仿,若把整個操作流看成是一張圖(Graph),那么像input這種creator為null的被稱之為圖的葉子(graph leaf)矾瘾。而creator非null的變量比如output1和output2,是不能被返回導(dǎo)數(shù)的北救,它們的grad均為0。所以只有葉子節(jié)點(diǎn)才能被autograd攘宙。