深度學(xué)習(xí)框架 の 動(dòng)態(tài)圖 vs 靜態(tài)圖

Date: 2020/08/03

Author: CW

Foreword:

各位煉丹者應(yīng)該都會(huì)有自己常用的一種或幾種深度學(xué)習(xí)框架鹤啡,如 MxNet、Caffe清蚀、Tensorflow、Pytorch爹谭、PaddlePaddle(百度)枷邪,甚至是國(guó)產(chǎn)新興框架 MegEngine(曠視)、MindSpore(華為)等诺凡,在涉及介紹這些框架的時(shí)候东揣,都會(huì)提及動(dòng)態(tài)圖和靜態(tài)圖這樣的概念,那么它們究竟是什么意思呢腹泌?在框架中又是如何體現(xiàn)與使用的呢嘶卧?本文會(huì)結(jié)合 Tensorflow、Pytorch 以及小鮮肉 MegEngine 的例子來(lái)為諸位揭開這神秘的面紗凉袱。


計(jì)算圖

不論是動(dòng)態(tài)圖還是靜態(tài)圖芥吟,它們都屬于計(jì)算圖侦铜。計(jì)算圖是用來(lái)描述運(yùn)算的有向無(wú)環(huán)圖,它有兩個(gè)主要元素:結(jié)點(diǎn)(Node)和邊(Edge)钟鸵。結(jié)點(diǎn)表示數(shù)據(jù)钉稍,如向量、矩陣棺耍、張量贡未,而邊表示運(yùn)算,如加減乘除卷積等蒙袍。

采用計(jì)算圖來(lái)描述運(yùn)算的好處不僅是讓運(yùn)算流的表達(dá)更加簡(jiǎn)潔清晰俊卤,還有一個(gè)更重要的原因是方便求導(dǎo)計(jì)算梯度

計(jì)算圖

上圖表示的是 y = (w + x) * (w + 1) 代表的計(jì)算圖害幅,若要計(jì)算y對(duì)w的導(dǎo)數(shù)消恍,那么結(jié)合鏈?zhǔn)角髮?dǎo)法則,就在計(jì)算圖中反向從y找到所有到w的路徑矫限,每條路徑上各段的導(dǎo)數(shù)相乘就是該路徑的偏導(dǎo)哺哼,最后再將所有路徑獲得的偏導(dǎo)求和即可。

葉子節(jié)點(diǎn)是用戶創(chuàng)建的變量叼风,如上圖的x與w取董,在Pytorch的實(shí)現(xiàn)中,為了節(jié)省內(nèi)存无宿,在梯度反向傳播結(jié)束后茵汰,非葉子節(jié)點(diǎn)的梯度都會(huì)被釋放掉。


動(dòng)態(tài)圖

動(dòng)態(tài)圖意味著計(jì)算圖的構(gòu)建和計(jì)算同時(shí)發(fā)生(define by run)孽鸡。這種機(jī)制由于能夠?qū)崟r(shí)得到中間結(jié)果的值蹂午,使得調(diào)試更加容易,同時(shí)我們將大腦中的想法轉(zhuǎn)化為代碼方案也變得更加容易彬碱,對(duì)于編程實(shí)現(xiàn)來(lái)說更友好豆胸。Pytorch使用的就是動(dòng)態(tài)圖機(jī)制,因此它更易上手巷疼,風(fēng)格更加pythonic晚胡,大受科研人員的喜愛。


靜態(tài)圖

靜態(tài)圖則意味著計(jì)算圖的構(gòu)建和實(shí)際計(jì)算是分開(define and run)的嚼沿。在靜態(tài)圖中估盘,會(huì)事先了解和定義好整個(gè)運(yùn)算流,這樣之后再次運(yùn)行的時(shí)候就不再需要重新構(gòu)建計(jì)算圖了(可理解為編譯)骡尽,因此速度會(huì)比動(dòng)態(tài)圖更快遣妥,從性能上來(lái)說更加高效,但這也意味著你所期望的程序與編譯器實(shí)際執(zhí)行之間存在著更多的代溝攀细,代碼中的錯(cuò)誤將難以發(fā)現(xiàn)箫踩,無(wú)法像動(dòng)態(tài)圖一樣隨時(shí)拿到中間計(jì)算結(jié)果爱态。Tensorflow默認(rèn)使用的是靜態(tài)圖機(jī)制,這也是其名稱的由來(lái),先定義好整個(gè)計(jì)算流(flow),然后再對(duì)數(shù)據(jù)(tensor)進(jìn)行計(jì)算哆键。


動(dòng)態(tài)圖 vs 靜態(tài)圖

通過一個(gè)例子來(lái)對(duì)比下動(dòng)態(tài)圖和靜態(tài)圖機(jī)制在編程實(shí)現(xiàn)上的差異凡傅,分別基于Pytorch和Tensorflow實(shí)現(xiàn),先來(lái)看看Pytorch的動(dòng)態(tài)圖機(jī)制:

import torch


first_counter = torch.Tensor([0])

second_counter = torch.Tensor([10])


while (first_counter < second_counter)[0]:

? ? first_counter += 2

? ? second_counter += 1


print(first_counter)

print(second_counter)

可以看到,這與普通的Python編程無(wú)異。

再來(lái)看看在基于Tensorflow的靜態(tài)圖機(jī)制下是如何實(shí)現(xiàn)上述程序的:

import tensorflow as tf

first_counter = tf.constant(0)

second_counter = tf.constant(10)

# tensorflow

import tensorflow as tf


first_counter = tf.constant(0)

second_counter = tf.constant(10)


def cond(first_counter, second_counter, *args):

? ? return first_counter < second_counter


def body(first_counter, second_counter):

? ? first_counter = tf.add(first_counter, 2)

? ? second_counter = tf.add(second_counter, 1)

? ? return first_counter, second_counter


c1, c2 = tf.while_loop(cond, body, [first_counter, second_counter])


with tf.Session() as sess:

? ? counter_1_res, counter_2_res = sess.run([c1, c2])


print(counter_1_res)

print(counter_2_res)

(⊙o⊙)… 對(duì)Tensorflow不熟悉的童鞋來(lái)說,第一反應(yīng)可能會(huì)是:這什么鬼6幻骸?確實(shí)猿规,看上去會(huì)有點(diǎn)難受..

Tensorflow在靜態(tài)圖的模式下衷快,每次運(yùn)算使用的計(jì)算圖都是同一個(gè),因此不能直接使用 Python 的 while 循環(huán)語(yǔ)句姨俩,而是要使用其內(nèi)置的輔助函數(shù) tf.while_loop蘸拔,而且還要tf.Session().run()之類的亂七八糟..

而Pytorch是動(dòng)態(tài)圖的模式,每次運(yùn)算會(huì)構(gòu)建新的計(jì)算圖环葵,在編程實(shí)現(xiàn)上不需要額外的學(xué)習(xí)成本(當(dāng)然首先你得會(huì)Python)调窍。


動(dòng)靜結(jié)合

在最近開源的框架MegEngine中,集成了兩種圖模式张遭,并且可以進(jìn)行相互切換邓萨,下面舉例說明將動(dòng)態(tài)圖轉(zhuǎn)換為靜態(tài)圖編譯過程中進(jìn)行的內(nèi)存和計(jì)算優(yōu)化

y = w*x + b 的動(dòng)態(tài)計(jì)算圖如下:

動(dòng)態(tài)圖

可以看到,中間的運(yùn)算結(jié)果是被保留下來(lái)的菊卷,如p=w*x缔恳,這樣就一共需要5個(gè)變量的存儲(chǔ)空間。若切換為靜態(tài)圖洁闰,由于事先了解了整個(gè)計(jì)算流歉甚,因此可以讓y復(fù)用p的內(nèi)存空間,這樣一共就只需要4個(gè)變量的存儲(chǔ)空間扑眉。

另外铃芦,MegEngine 還使用了 算子融合 (Operator Fuse)的機(jī)制,用于減少計(jì)算開銷襟雷。對(duì)于上面的動(dòng)態(tài)計(jì)算圖,切換為靜態(tài)圖后可以將乘法和加法融合為一個(gè)三元操作(假設(shè)硬件支持):乘加(如下圖所示)仁烹,從而降低計(jì)算量耸弄。

靜態(tài)圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者卓缰。
  • 序言:七十年代末计呈,一起剝皮案震驚了整個(gè)濱河市砰诵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捌显,老刑警劉巖茁彭,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異扶歪,居然都是意外死亡理肺,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門善镰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)妹萨,“玉大人,你說我怎么就攤上這事炫欺『跬辏” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵品洛,是天一觀的道長(zhǎng)树姨。 經(jīng)常有香客問我,道長(zhǎng)桥状,這世上最難降的妖魔是什么帽揪? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮岛宦,結(jié)果婚禮上台丛,老公的妹妹穿的比我還像新娘。我一直安慰自己砾肺,他們只是感情好挽霉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著变汪,像睡著了一般侠坎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裙盾,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天实胸,我揣著相機(jī)與錄音,去河邊找鬼番官。 笑死庐完,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徘熔。 我是一名探鬼主播门躯,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼酷师!你這毒婦竟也來(lái)了讶凉?” 一聲冷哼從身側(cè)響起染乌,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎懂讯,沒想到半個(gè)月后荷憋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褐望,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年勒庄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片譬挚。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锅铅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出减宣,到底是詐尸還是另有隱情盐须,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布漆腌,位于F島的核電站贼邓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏闷尿。R本人自食惡果不足惜塑径,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望填具。 院中可真熱鬧统舀,春花似錦、人聲如沸劳景。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盟广。三九已至闷串,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筋量,已是汗流浹背烹吵。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桨武,地道東北人肋拔。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像呀酸,于是被迫代替她去往敵國(guó)和親只损。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355