一、autograd自動(dòng)微分
假如我們有一個(gè)向量x=(1,1)當(dāng)成input,經(jīng)過一系列運(yùn)算得到了output變量y,如下圖所示:

我們想要求y關(guān)于x的微分時(shí),pytorch會(huì)幫我們自動(dòng)求解。
>>>from torch.autograd import Variable
>>>import torch
>>>x = Variable(torch.ones(2), requires_grad = True) #vairable是tensor的一個(gè)外包裝
>>>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只對(duì)輸出值為標(biāo)量的有用,因?yàn)閾p失函數(shù)的輸出是一個(gè)標(biāo)量。如果y是一個(gè)向量,那么backward()函數(shù)就會(huì)失效。不知道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ū)別在于多了下面幾個(gè)屬性。

variable和function它們是彼此不分開的,先上圖:

如圖,假設(shè)我們有一個(gè)輸入變量input(數(shù)據(jù)類型為Variable)input是用戶輸入的,所以其創(chuàng)造者creator為null值,input經(jīng)過第一個(gè)數(shù)據(jù)操作operation1(比如加減乘除運(yùn)算)得到output1變量(數(shù)據(jù)類型仍為Variable),這個(gè)過程中會(huì)自動(dòng)生成一個(gè)function1的變量(數(shù)據(jù)類型為Function的一個(gè)實(shí)例),而output1的創(chuàng)造者就是這個(gè)function1。隨后,output1再經(jīng)過一個(gè)數(shù)據(jù)操作生成output2,這個(gè)過程也會(huì)生成另外一個(gè)實(shí)例function2,output2的創(chuàng)造者creator為function2。
在這個(gè)向前傳播的過程中,function1和function2記錄了數(shù)據(jù)input的所有操作歷史,當(dāng)output2運(yùn)行其backward函數(shù)時(shí),會(huì)使得function2和function1自動(dòng)反向計(jì)算input的導(dǎo)數(shù)值并存儲(chǔ)在grad屬性中。
creator為null的變量才能被返回導(dǎo)數(shù),比如input,若把整個(gè)操作流看成是一張圖(Graph),那么像input這種creator為null的被稱之為圖的葉子(graph leaf)。而creator非null的變量比如output1和output2,是不能被返回導(dǎo)數(shù)的,它們的grad均為0。所以只有葉子節(jié)點(diǎn)才能被autograd。