Ch01-02.自動求導(dǎo)(Pytorch入門)

自動求導(dǎo)機(jī)制

PyTorch 中所有神經(jīng)網(wǎng)絡(luò)的核心是 autograd 包柒凉。 我們先簡單介紹一下這個包动雹,然后訓(xùn)練第一個簡單的神經(jīng)網(wǎng)絡(luò)塞琼。
autograd包為張量上的所有操作提供了自動求導(dǎo)叠洗。 它是一個在運(yùn)行時定義的框架凫海,這意味著反向傳播是根據(jù)你的代碼來確定如何運(yùn)行呛凶,并且每次迭代可以是不同的。

張量(Tensor)

torch.Tensor是這個包的核心類行贪,如果設(shè)置.requires_grad為True, 那么就會追蹤所有對于該張量的操作漾稀。當(dāng)完成計算后通過調(diào)用.backward(),自動計算所有梯度建瘫,這個張量的所有梯度都會自動累計到.grad屬性崭捍。
要阻止張量跟蹤歷史記錄,可以調(diào)用.detach()方法將其與計算歷史記錄分離啰脚,并禁止跟蹤它將來的計算記錄殷蛇。

推斷時 為了防止跟蹤歷史記錄(和使用內(nèi)存),可以將代碼塊包裝在with torch.no_grad():中。 在評估模型時特別有用粒梦,因?yàn)槟P涂赡芫哂衦equires_grad = True的可訓(xùn)練參數(shù)亮航,但是我們不需要梯度計算。
在自動梯度計算中還有另外一個重要的類Function.
Tensor和Function互相連接并生成一個非循環(huán)圖匀们,它表示和存儲了完整的計算歷史缴淋,每個張量都由.grad_fn屬性,這個屬性引用了一個創(chuàng)建了Tensor的Function(除非這個Tensor是由用戶手動創(chuàng)建昼蛀,即宴猾,該張量的.grad_fn是None)
如果需要計算導(dǎo)數(shù),你可以再Tensor上調(diào)用.backward()叼旋。如果Tensor是一個標(biāo)量(即它包含一個元素數(shù)據(jù))則不需要為backward()指定任何參數(shù),但是如果有更多元素沦辙,你需要指定一個gradient參數(shù)來匹配張量形狀夫植。

import torch
x = torch.ones(2,2,requires_grad=True)
print(x)
# tensor([[1., 1.],
#        [1., 1.]], requires_grad=True)
y = x+2
print(y)
#tensor([[3., 3.],
#        [3., 3.]], grad_fn=<AddBackward0>)
x.requires_grad_(True)
# 可以用于改變requires_grad屬性

梯度

反向傳播因?yàn)閛ut是一個純量(scalar), out.backward()等于out.backward(torch.tensor(1))

out.backward()
# 打印 d(out)/dx 梯度
print(x.grad)

如果.requires_grad = True但是又不希望進(jìn)行autograd計算,可以將變量包裹在with torch.no_grad()中

總結(jié)流程:

  1. 當(dāng)我們執(zhí)行z.backward()的時候油讯,這個操作將調(diào)用z里面的grad_fn屬性详民,執(zhí)行求導(dǎo)的操作
  2. 這個操作將遍歷grad_fn的next_functions, 然后分別取出里面的Function(AccumulateGrad)陌兑, 執(zhí)行求導(dǎo)操作沈跨,這個部分是一個遞歸的過程直到最后類型為葉子節(jié)點(diǎn)。
  3. 計算出結(jié)果以后兔综,將結(jié)果保存在他們對應(yīng)的variable這個變量所引用的對象(x和y)的grad這個屬性里面
  4. 求導(dǎo)結(jié)束饿凛。所有葉節(jié)點(diǎn)的grad變量都得到相應(yīng)的更新
    最終當(dāng)我們執(zhí)行完c.backward()之后,a和b里面的grad值就得到了更新软驰。

擴(kuò)展Autograd

如果需要自定義autograd擴(kuò)展新的功能涧窒,需要擴(kuò)展Function類,因?yàn)镕unction使用autograd來計算結(jié)果和梯度锭亏,并對操作歷史進(jìn)行編碼纠吴。在Function類中最主要的方法是forward()和backward()他們分別代表前向傳播和后向傳播。
一個自定義的Function需要以下三個方法:
init(optional):如果該操作需要額外的參數(shù)慧瘤,則需要定義該function的構(gòu)造函數(shù)戴已,不需要可以省略
forward(): 執(zhí)行前向傳播的計算代碼
backward():執(zhí)行后向傳播的計算代碼

# 引入Function便于擴(kuò)展
from torch.autograd.function import Function
# 定義一個乘以常數(shù)的操作(輸入?yún)?shù)是張量)
# 方法必須是靜態(tài)方法,所以要加上@staticmethod 
class MulConstant(Function):
    @staticmethod 
    def forward(ctx, tensor, constant):
        # ctx 用來保存信息這里類似self锅减,并且ctx的屬性可以在backward中調(diào)用
        ctx.constant=constant
        return tensor *constant
    @staticmethod
    def backward(ctx, grad_output):
        # 返回的參數(shù)要與輸入的參數(shù)一樣.
        # 第一個輸入為3x3的張量糖儡,第二個為一個常數(shù)
        # 常數(shù)的梯度必須是 None.
        return grad_output, None 
# 測試定義的Function
a=torch.rand(3,3,requires_grad=True)
b=MulConstant.apply(a,5)
print("a:"+str(a))
print("b:"+str(b)) # b為a的元素乘以5
#a:tensor([[0.0118, 0.1434, 0.8669],
#        [0.1817, 0.8904, 0.5852],
#        [0.7364, 0.5234, 0.9677]], #requires_grad=True)
#b:tensor([[0.0588, 0.7169, 4.3347],
#        [0.9084, 4.4520, 2.9259],
#        [3.6820, 2.6171, 4.8386]], grad_fn=<MulConstantBackward>)

# 反向傳播,返回值不是標(biāo)量上煤,所以backward要參數(shù)
b.backward(torch.ones_like(a))
a.grad
#tensor([[1., 1., 1.],
#        [1., 1., 1.],
#        [1., 1., 1.]])
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末休玩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拴疤,老刑警劉巖永部,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異呐矾,居然都是意外死亡苔埋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門蜒犯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來组橄,“玉大人,你說我怎么就攤上這事罚随∮窆ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵淘菩,是天一觀的道長遵班。 經(jīng)常有香客問我,道長潮改,這世上最難降的妖魔是什么狭郑? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任缀磕,我火速辦了婚禮祝迂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丢间。我一直安慰自己糕殉,他們只是感情好亩鬼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著糙麦,像睡著了一般辛孵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赡磅,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天魄缚,我揣著相機(jī)與錄音,去河邊找鬼焚廊。 笑死冶匹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咆瘟。 我是一名探鬼主播嚼隘,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼袒餐!你這毒婦竟也來了飞蛹?” 一聲冷哼從身側(cè)響起谤狡,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卧檐,沒想到半個月后墓懂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡霉囚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年捕仔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盈罐。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡榜跌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盅粪,到底是詐尸還是另有隱情钓葫,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布票顾,位于F島的核電站瓤逼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏库物。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一贷帮、第九天 我趴在偏房一處隱蔽的房頂上張望戚揭。 院中可真熱鬧,春花似錦撵枢、人聲如沸民晒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潜必。三九已至,卻和暖如春沃但,著一層夾襖步出監(jiān)牢的瞬間磁滚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工宵晚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留垂攘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓淤刃,卻偏偏與公主長得像晒他,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逸贾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355