[PyTorch 學(xué)習(xí)筆記] 1.4 計(jì)算圖與動(dòng)態(tài)圖機(jī)制

本章代碼:https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson1/computational_graph.py

計(jì)算圖

深度學(xué)習(xí)就是對(duì)張量進(jìn)行一系列的操作离唐,隨著操作種類和數(shù)量的增多问窃,會(huì)出現(xiàn)各種值得思考的問題。比如多個(gè)操作之間是否可以并行贮竟,如何協(xié)同底層的不同設(shè)備咕别,如何避免冗余的操作写穴,以實(shí)現(xiàn)最高效的計(jì)算效率,同時(shí)避免一些 bug啊送。因此產(chǎn)生了計(jì)算圖 (Computational Graph)。

計(jì)算圖是用來描述運(yùn)算的有向無環(huán)圖昔逗,有兩個(gè)主要元素:節(jié)點(diǎn) (Node) 和邊 (Edge)勾怒。節(jié)點(diǎn)表示數(shù)據(jù),如向量笔链、矩陣腮猖、張量。邊表示運(yùn)算澈缺,如加減乘除卷積等。

用計(jì)算圖表示:y=(x+w)*(w+1)姐赡,如下所示:

<div align="center"><img src="https://image.zhangxiann.com/20200515221509.png"/></div>

可以看作, y=a \times b 锁施,其中 a=x+wb=w+1肩狂。

計(jì)算圖與梯度求導(dǎo)

這里求 y 對(duì) w 的導(dǎo)數(shù)姥饰。根復(fù)合函數(shù)的求導(dǎo)法則列粪,可以得到如下過程。

\begin{aligned} \frac{\partial y}{\partial w} &=\frac{\partial y}{\partial a} \frac{\partial a}{\partial w}+\frac{\partial y}{\partial b} \frac{\partial b}{\partial w} \\ &=b * 1+a * 1 \\ &=b+a \\ &=(w+1)+(x+w) \\ &=2 * w+x+1 \\ &=2 * 1+2+1=5\end{aligned}

體現(xiàn)到計(jì)算圖中态蒂,就是根節(jié)點(diǎn) y 到葉子節(jié)點(diǎn) w 有兩條路徑 y -> a -> wy ->b -> w钾恢。根節(jié)點(diǎn)依次對(duì)每條路徑的孩子節(jié)點(diǎn)求導(dǎo)鸳址,一直到葉子節(jié)點(diǎn)w,最后把每條路徑的導(dǎo)數(shù)相加即可疹瘦。

<div align="center"><img src="https://image.zhangxiann.com/20200515221816.png"/></div>

代碼如下:

import torch
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
# y=(x+w)*(w+1)
a = torch.add(w, x)     # retain_grad()
b = torch.add(w, 1)
y = torch.mul(a, b)
# y 求導(dǎo)
y.backward()
# 打印 w 的梯度巡球,就是 y 對(duì) w 的導(dǎo)數(shù)
print(w.grad)

結(jié)果為tensor([5.])辕漂。

我們回顧前面說過的 Tensor 中有一個(gè)屬性is_leaf標(biāo)記是否為葉子節(jié)點(diǎn)吴超。

<div align="center"><img src="https://image.zhangxiann.com/20200515145801.png"/></div>

在上面的例子中,xw 是葉子節(jié)點(diǎn)跋涣,其他所有節(jié)點(diǎn)都依賴于葉子節(jié)點(diǎn)鸟悴。葉子節(jié)點(diǎn)的概念主要是為了節(jié)省內(nèi)存细诸,在計(jì)算圖中的一輪反向傳播結(jié)束之后,非葉子節(jié)點(diǎn)的梯度是會(huì)被釋放的利赋。

代碼示例:

# 查看葉子結(jié)點(diǎn)
print("is_leaf:\n", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)

# 查看梯度
print("gradient:\n", w.grad, x.grad, a.grad, b.grad, y.grad)

結(jié)果為:

is_leaf:
 True True False False False
gradient:
 tensor([5.]) tensor([2.]) None None None

非葉子節(jié)點(diǎn)的梯度為空,如果在反向傳播結(jié)束之后仍然需要保留非葉子節(jié)點(diǎn)的梯度中燥,可以對(duì)節(jié)點(diǎn)使用retain_grad()方法塘偎。

而 Tensor 中的 grad_fn 屬性記錄的是創(chuàng)建該張量時(shí)所用的方法 (函數(shù))。而在反向傳播求導(dǎo)梯度時(shí)需要用到該屬性咱扣。

示例代碼:

# 查看梯度
print("w.grad_fn = ", w.grad_fn)
print("x.grad_fn = ", x.grad_fn)
print("a.grad_fn = ", a.grad_fn)
print("b.grad_fn = ", b.grad_fn)
print("y.grad_fn = ", y.grad_fn)

結(jié)果為

w.grad_fn =  None
x.grad_fn =  None
a.grad_fn =  <AddBackward0 object at 0x000001D8DDD20588>
b.grad_fn =  <AddBackward0 object at 0x000001D8DDD20588>
y.grad_fn =  <MulBackward0 object at 0x000001D8DDD20588>

PyTorch 的動(dòng)態(tài)圖機(jī)制

PyTorch 采用的是動(dòng)態(tài)圖機(jī)制 (Dynamic Computational Graph)偏窝,而 Tensorflow 采用的是靜態(tài)圖機(jī)制 (Static Computational Graph)。

動(dòng)態(tài)圖是運(yùn)算和搭建同時(shí)進(jìn)行祭往,也就是可以先計(jì)算前面的節(jié)點(diǎn)的值,再根據(jù)這些值搭建后面的計(jì)算圖硼补。優(yōu)點(diǎn)是靈活熏矿,易調(diào)節(jié),易調(diào)試褪储。PyTorch 里的很多寫法跟其他 Python 庫的代碼的使用方法是完全一致的鲤竹,沒有任何額外的學(xué)習(xí)成本昔榴。

靜態(tài)圖是先搭建圖,然后再輸入數(shù)據(jù)進(jìn)行運(yùn)算吱肌。優(yōu)點(diǎn)是高效仰禽,因?yàn)殪o態(tài)計(jì)算是通過先定義后運(yùn)行的方式,之后再次運(yùn)行的時(shí)候就不再需要重新構(gòu)建計(jì)算圖规揪,所以速度會(huì)比動(dòng)態(tài)圖更快粒褒。但是不靈活。TensorFlow 每次運(yùn)行的時(shí)候圖都是一樣的祥款,是不能夠改變的月杉,所以不能直接使用 Python 的 while 循環(huán)語句,需要使用輔助函數(shù) tf.while_loop 寫成 TensorFlow 內(nèi)部的形式桨昙。

參考資料


如果你覺得這篇文章對(duì)你有幫助蛙酪,不妨點(diǎn)個(gè)贊,讓我有更多動(dòng)力寫出好文章翘盖。

我的文章會(huì)首發(fā)在公眾號(hào)上桂塞,歡迎掃碼關(guān)注我的公眾號(hào)張賢同學(xué)

<div align="center"><img src="https://image.zhangxiann.com/QRcode_8cm.jpg"/></div>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末馍驯,一起剝皮案震驚了整個(gè)濱河市阁危,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌汰瘫,老刑警劉巖狂打,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異混弥,居然都是意外死亡趴乡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門剑逃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浙宜,“玉大人官辽,你說我怎么就攤上這事同仆∷谆颍” “怎么了辛慰?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵驰弄,是天一觀的道長。 經(jīng)常有香客問我岔擂,道長,這世上最難降的妖魔是什么阔蛉? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮颠区,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朋截。我一直安慰自己部服,他們只是感情好奉芦,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布宠叼。 她就那樣靜靜地躺著筹裕,像睡著了一般朝卒。 火紅的嫁衣襯著肌膚如雪抗斤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音徒像,去河邊找鬼锯蛀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛劈愚,可吹牛的內(nèi)容都是我干的菌羽。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了靴庆?” 一聲冷哼從身側(cè)響起炉抒,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤塞茅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后飒泻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衰猛,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徐鹤。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖涛目,靈堂內(nèi)的尸體忽然破棺而出霹肝,到底是詐尸還是另有隱情沫换,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布识樱,位于F島的核電站,受9級(jí)特大地震影響割疾,放射性物質(zhì)發(fā)生泄漏侵佃。R本人自食惡果不足惜抚芦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一褥民、第九天 我趴在偏房一處隱蔽的房頂上張望轴捎。 院中可真熱鬧,春花似錦驼鞭、人聲如沸译隘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽深啤。三九已至,卻和暖如春访诱,著一層夾襖步出監(jiān)牢的瞬間触菜,已是汗流浹背哲泊。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工先朦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喳魏,地道東北人枝恋。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓十电,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摆出。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爷恳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361