丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開(kāi)發(fā)者 正文
發(fā)私信給AI研習(xí)社
發(fā)送

1

以靜制動(dòng)的TensorFlow Fold

本文作者: AI研習(xí)社 2017-02-18 19:04
導(dǎo)語(yǔ):近日各種深度學(xué)習(xí)框架們交鋒的戰(zhàn)場(chǎng)就是動(dòng)態(tài)計(jì)算圖,誰(shuí)能在這場(chǎng)戰(zhàn)爭(zhēng)中取得優(yōu)勢(shì),誰(shuí)就把握住了未來(lái)用戶的流向。

隨著深度學(xué)習(xí)的發(fā)展,深度學(xué)習(xí)框架之間競(jìng)爭(zhēng)也日益激烈,新老框架紛紛各顯神通,想要在廣大DeepLearner的服務(wù)器上占據(jù)一席之地。近日它們交鋒的戰(zhàn)場(chǎng)就是動(dòng)態(tài)計(jì)算圖,誰(shuí)能在這場(chǎng)戰(zhàn)爭(zhēng)中取得優(yōu)勢(shì),誰(shuí)就把握住了未來(lái)用戶的流向。作為一名DeepLearner,如果能選中最適合的框架,就能在學(xué)習(xí)、研究和生產(chǎn)中提高自己的效率,步步領(lǐng)先。但要是上錯(cuò)了船,文檔、性能、靈活性四處漏水,跳船之后還得游一段時(shí)間,這段時(shí)間可能都?jí)騽e人開(kāi)到新大陸了。所以說(shuō)了解框架發(fā)展,掌握最新形式,可謂是每個(gè)不甘人后的DeepLearner的必修課。

近期各大框架發(fā)展的趨勢(shì)主要有兩個(gè),一個(gè)是增加對(duì)動(dòng)態(tài)圖計(jì)算的支持,另一個(gè)是在主編程語(yǔ)言上適應(yīng)廣大用戶的需求。最近比較火熱的動(dòng)態(tài)計(jì)算圖相關(guān)的框架主要有DyNet、PyTorch和TensorFlow Fold,就是圍繞著這其中一個(gè)點(diǎn)或兩個(gè)點(diǎn)進(jìn)行的。

目前在這場(chǎng)競(jìng)爭(zhēng)中,TensorFlow Fold以其先進(jìn)的Dynamic Batching算法走在了其他框架的前面。為了方便大家了解TensorFlow Fold的特性,本文將會(huì)為大家厘清有關(guān)動(dòng)態(tài)圖計(jì)算的一些概念,對(duì)比介紹DyNet、PyTorch和TensorFlow等框架的特性,重點(diǎn)講解TensorFlow Fold的核心算法和接口。

本文分為五個(gè)部分:

一、當(dāng)我們說(shuō)動(dòng)態(tài)計(jì)算圖的時(shí)候,我們指的是什么?

二、框架競(jìng)爭(zhēng)的焦點(diǎn):編程語(yǔ)言與動(dòng)態(tài)計(jì)算圖

三、以靜制動(dòng):巧妙的Dynamic Batching算法

四、TensorFlow Fold:封裝在靜態(tài)框架上的動(dòng)態(tài)接口

五、總結(jié)

| 當(dāng)我們說(shuō)動(dòng)態(tài)計(jì)算圖的時(shí)候,我們指的是什么?

首先,我們要搞清楚深度學(xué)習(xí)框架所謂的“動(dòng)態(tài)”和“靜態(tài)”究竟是按照什么標(biāo)準(zhǔn)劃分的。為了大家的直觀理解,我這里要引入一個(gè)系列比喻,房地產(chǎn)商(框架使用者)通過(guò)電子郵件(編程語(yǔ)言代碼)請(qǐng)建筑公司(深度學(xué)習(xí)框架)幫忙建造房子(計(jì)算圖) 。

在靜態(tài)框架使用的是靜態(tài)聲明(static declaration)策略,計(jì)算圖的聲明和執(zhí)行是分開(kāi)的,換成比喻的說(shuō)法就是:建筑設(shè)計(jì)師畫(huà)建筑設(shè)計(jì)圖(聲明)和施工隊(duì)建造房子(執(zhí)行)是分開(kāi)進(jìn)行的。畫(huà)設(shè)計(jì)圖的時(shí)候施工隊(duì)的建筑工人、材料和機(jī)器都還沒(méi)動(dòng),這也就是我們說(shuō)的靜態(tài)。這個(gè)整個(gè)聲明和執(zhí)行的過(guò)程中涉及到兩個(gè)圖,這里我們分別給它們一個(gè)名字,聲明階段構(gòu)建的圖叫虛擬計(jì)算圖,在這個(gè)過(guò)程中框架需要將用戶的代碼轉(zhuǎn)化為可以一份詳細(xì)的計(jì)算圖,這份計(jì)算圖一般會(huì)包含計(jì)算執(zhí)行順序和內(nèi)存空間分配的策略,這些策略的制定一般是這個(gè)過(guò)程最消耗時(shí)間的部分;執(zhí)行階段構(gòu)建的圖叫實(shí)體計(jì)算圖,這個(gè)過(guò)程包括為參數(shù)和中間結(jié)果實(shí)際分配內(nèi)存空間,并按照當(dāng)前需求進(jìn)行計(jì)算等,數(shù)據(jù)就在這張實(shí)體計(jì)算圖中計(jì)算和傳遞。不過(guò)這里要注意一點(diǎn)的是,虛擬計(jì)算圖中的部件并不需要在每一次執(zhí)行中都轉(zhuǎn)化為實(shí)體計(jì)算圖。像建筑設(shè)計(jì)圖上畫(huà)了三層別墅的規(guī)劃,但建筑隊(duì)可以在按客戶的要求只建下面的兩層。另外一張?jiān)O(shè)計(jì)圖可以用多少次也沒(méi)有規(guī)定死,所以說(shuō)靜態(tài)只是相對(duì)于下面的動(dòng)態(tài)框架而言,并不是說(shuō)靜態(tài)框架就只能按部就班。常見(jiàn)的靜態(tài)框架有TensorFlow、MXNet、Theano等。

而動(dòng)態(tài)框架則不同,使用的是動(dòng)態(tài)聲明(dynamic declaration)策略,聲明和執(zhí)行一起進(jìn)行的。比喻一下就是設(shè)計(jì)師和施工隊(duì)是一起工作的,設(shè)計(jì)師看郵件的第一句如“要有一個(gè)二十平方米的臥室”,馬上畫(huà)出這個(gè)臥室的設(shè)計(jì)圖交給施工隊(duì)建造,然后再去看第二句。這樣虛擬計(jì)算圖和實(shí)體計(jì)算圖的構(gòu)建就是同步進(jìn)行的了。因?yàn)榭梢詫?shí)時(shí)的計(jì)劃,動(dòng)態(tài)框架可以根據(jù)實(shí)時(shí)需求構(gòu)建對(duì)應(yīng)的計(jì)算圖,在靈活性上,動(dòng)態(tài)框架會(huì)更勝一籌。Torch、DyNet、Chainer等就是動(dòng)態(tài)框架。

靈活很好,但也不是沒(méi)有代價(jià)的。不然的話現(xiàn)在流行的框架中,就不會(huì)是靜態(tài)框架占比更高了。靜態(tài)框架將聲明和執(zhí)行分開(kāi)有什么好處呢?最大的好處就是在執(zhí)行前就知道了所有的需要進(jìn)行操作,所以可以對(duì)圖中各節(jié)點(diǎn)計(jì)算順序和內(nèi)存分配進(jìn)行合理的規(guī)劃,這樣就可以就較快的執(zhí)行所需的計(jì)算。就像房地產(chǎn)商郵件里說(shuō),“建一個(gè)棟大樓,樓頂建個(gè)花園,大樓旁邊建一個(gè)游泳館”,但這個(gè)順序并不是最優(yōu)的,設(shè)計(jì)師畫(huà)完圖之后,發(fā)現(xiàn)大樓的選址旁邊要預(yù)留游泳館的空間,游泳館和大樓可以同時(shí)開(kāi)工,并不用等到大樓的樓頂花園建完,就在圖上把這些信息標(biāo)注了出來(lái),施工隊(duì)就可以更高效地施工。這樣一來(lái),靜態(tài)框架的執(zhí)行效率相對(duì)來(lái)說(shuō)就更高一些。這一點(diǎn)是動(dòng)態(tài)框架的劣勢(shì),因?yàn)樗看我?guī)劃、分配內(nèi)存、執(zhí)行的時(shí)候,都只能看到局部的需求,所以并不能做出全局最優(yōu)的規(guī)劃和內(nèi)存分配。

另外的好處是對(duì)于建筑公司的管理層(框架開(kāi)發(fā)者),因?yàn)橐粡堅(jiān)O(shè)計(jì)圖可以被反復(fù)施工,所以設(shè)計(jì)師畫(huà)圖的快慢影響就小地多了,對(duì)于一個(gè)要建幾年的工程設(shè)計(jì)師畫(huà)圖的時(shí)間是三天還是五天影響不大,靜態(tài)建筑公司不用花費(fèi)太多資源去培訓(xùn)設(shè)計(jì)師的畫(huà)圖速度(縮短構(gòu)建虛擬計(jì)算圖的時(shí)間,主要是規(guī)劃計(jì)算順序和分配內(nèi)存空間的時(shí)間)。而動(dòng)態(tài)建筑公司就不同了,因?yàn)槊拷ㄒ惶追孔踊蛞慌欧孔泳鸵匦庐?huà)一遍設(shè)計(jì)圖,對(duì)于一個(gè)幾周的子項(xiàng)目來(lái)說(shuō),花三天畫(huà)圖還是五天就影響比較大了。所以動(dòng)態(tài)框架對(duì)虛擬計(jì)算圖的構(gòu)建速度有較高的要求。當(dāng)然因?yàn)閯?dòng)態(tài)框架每步構(gòu)建和計(jì)算只是虛擬計(jì)算圖的一個(gè)局部,需要策略不會(huì)太復(fù)雜,所以制定策略也快得多。

在過(guò)去的大部分的深度學(xué)習(xí)項(xiàng)目中,不管使用的是靜態(tài)框架還是動(dòng)態(tài)框架,我們實(shí)際上都只用到了構(gòu)建靜態(tài)實(shí)際計(jì)算圖的能力。為什么這樣說(shuō)呢?因?yàn)樵谝话阍趯?shù)據(jù)投入模型進(jìn)行訓(xùn)練或預(yù)測(cè)之前,往往會(huì)有一個(gè)預(yù)處理的步奏。在預(yù)處理的時(shí)候,我們會(huì)將圖片縮放裁剪,將句子拼接截?cái)啵顾麄冏優(yōu)橥瑯拥男螤畲笮?,然后將集成一個(gè)個(gè)批次(min-batch),等待批次訓(xùn)練或預(yù)測(cè)。這些不同的輸入到模型中其實(shí)運(yùn)行的是同一個(gè)計(jì)算圖。換成房地產(chǎn)的說(shuō)法,就是說(shuō)用戶的需求雖然略有區(qū)別,但經(jīng)過(guò)房地產(chǎn)商的努力,他們都同意要同一款房子。不管是房地產(chǎn)商選的是靜態(tài)建筑公司還是動(dòng)態(tài)建筑公司,建造的房子都是統(tǒng)一的小區(qū)樣式。

這樣作的好處是可以充分利用GPU和多核CPU的并行計(jì)算能力。這種能力可以怎么理解呢?建筑施工隊(duì)里面有很多的砌墻工人,100個(gè)人取砌一堵1米的墻并不會(huì)比10個(gè)人快上10倍(能實(shí)際工作的可能還是只有10個(gè)人),而讓他們同時(shí)砌十堵1米的墻,可能所花的時(shí)間可能和砌一堵墻幾乎一樣快。如果有很多可以通過(guò)這樣并行來(lái)加速的工作,那整個(gè)工程所需要的時(shí)間也就可以大大縮短。GPU能夠幾十倍上百倍地提高計(jì)算速度是現(xiàn)代深度學(xué)習(xí)發(fā)展的一個(gè)關(guān)鍵,畢竟現(xiàn)在的深度模型很大程度上還是很依賴調(diào)參,需要快速地迭代。能否利用這種加速能力常常就是一次訓(xùn)練幾個(gè)小時(shí)還是幾周的區(qū)別,也是決定一個(gè)項(xiàng)目能不能做的關(guān)鍵。

然而,并不是所有項(xiàng)目的數(shù)據(jù)都可以預(yù)處理成相同的形狀和尺寸。例如自然語(yǔ)言處理中的語(yǔ)法解析樹(shù),源代碼中的抽象語(yǔ)法樹(shù),以及網(wǎng)頁(yè)中的DOM樹(shù)等,形狀的不同本身就是非常重要的特征,不可剝離。這些數(shù)據(jù)就像充滿個(gè)性的藝術(shù)家,每個(gè)人對(duì)房子該是什么樣的都有自己的想法,買(mǎi)房的主要目的就是想彰顯個(gè)性,你想讓他們買(mǎi)一樣的房子,對(duì)不起,做不到。

這樣一來(lái),對(duì)于每一個(gè)樣例,我們都需要一個(gè)新的計(jì)算圖,這種問(wèn)題我們需要使用構(gòu)建動(dòng)態(tài)計(jì)算圖的能力才能夠解決。這種問(wèn)題我們可以叫它多結(jié)構(gòu)輸入問(wèn)題,因?yàn)檫@個(gè)問(wèn)題中計(jì)算圖的動(dòng)態(tài)需求是輸入帶來(lái)的。不同框架這個(gè)問(wèn)題的求解能力可以分為三個(gè)程度:第一層,無(wú)法計(jì)算,對(duì)于所有樣本都要求同樣的結(jié)構(gòu),在TensorFlow Fold出來(lái)之前所有正常使用的靜態(tài)框架處于這個(gè)層次。第二層,能計(jì)算但不夠高效,不同批次的樣本之間可以有不同的結(jié)構(gòu),但同一個(gè)批次樣本都是同一個(gè)結(jié)構(gòu),因?yàn)闊o(wú)法利用GPU和多核CPU的并行計(jì)算能力,不能高效計(jì)算,目前所有的動(dòng)態(tài)框架屬于這個(gè)層次。第三層,能高效計(jì)算,能夠在同一個(gè)批次里包含不同結(jié)構(gòu)的樣本,這個(gè)層次的多結(jié)構(gòu)輸入問(wèn)題有些論壇上也叫Dynamic Batching問(wèn)題, TensorFlow Fold的核心算法Dynamic Batching算法剛好同名,TensorFlow Fold和以后實(shí)現(xiàn)Dynamic Batching算法的框架處于這個(gè)層次。

多結(jié)構(gòu)輸入問(wèn)題早已存在,可用的模型諸如遞歸神經(jīng)網(wǎng)絡(luò)(Recursive Neural Networks)也提出許久,但因?yàn)闆](méi)有辦法高效實(shí)現(xiàn),研究和使用者寥寥無(wú)幾。因此,當(dāng)我們說(shuō)各大框架的動(dòng)態(tài)計(jì)算圖的時(shí)候,我們關(guān)心的不僅僅是他們誰(shuí)更容易做到,更重要的是能不能高效地做到。動(dòng)態(tài)計(jì)算圖問(wèn)題之一的多結(jié)構(gòu)輸入問(wèn)題的高效計(jì)算問(wèn)題一旦解決,就會(huì)大大促進(jìn)樹(shù)狀網(wǎng)絡(luò)甚至更復(fù)雜模型和數(shù)據(jù)集的發(fā)展。

但多結(jié)構(gòu)輸入問(wèn)題并不是唯一的動(dòng)態(tài)圖計(jì)算問(wèn)題,這里給大家舉另外一個(gè)例子,即計(jì)算圖的結(jié)構(gòu)要依賴于自身的計(jì)算結(jié)果的情況,類比就是后面房子怎么建要看前面建得怎么樣,這種問(wèn)題更加復(fù)雜,所有的動(dòng)態(tài)框架都可以輕松解決,而靜態(tài)框架目前是做不到,不過(guò)目前還沒(méi)發(fā)現(xiàn)有具體問(wèn)題需要這樣操作,我們這里不作仔細(xì)討論。

| 框架競(jìng)爭(zhēng)的焦點(diǎn):編程語(yǔ)言與動(dòng)態(tài)計(jì)算圖

在動(dòng)態(tài)計(jì)算圖爭(zhēng)鋒下面,還隱含著另外一重較量,編程語(yǔ)言的支持。上文我們將代碼比作電子郵件,那編程語(yǔ)言就是像英語(yǔ)、中文這樣的語(yǔ)言。當(dāng)前深度學(xué)習(xí)界最受歡迎的語(yǔ)言莫過(guò)于Python了,此外C++也因?yàn)槠浔旧淼母咝г诠I(yè)界頗得青睞?,F(xiàn)在大多主流框架都支持這兩種語(yǔ)言,他們是就像機(jī)器學(xué)習(xí)界的中英文。不過(guò)Torch是一個(gè)例外,它使用的是比較小眾的Lua,這實(shí)際上是它最大一塊短板,因?yàn)槭褂肔ua做一些數(shù)據(jù)處理并不方便,使用者經(jīng)常要使用Python之類的語(yǔ)言進(jìn)行數(shù)據(jù)清洗等操作,然后在轉(zhuǎn)化為L(zhǎng)ua可以讀取的形式。這一點(diǎn)使得無(wú)數(shù)使用者在不同語(yǔ)言的切換中紛紛投向TensorFlow、MXNet的懷抱。即使去年年中Facebook推出TorchNet這個(gè)Torch升級(jí)版也沒(méi)有挽回太多的人氣,因?yàn)門(mén)orchNet用的也是Lua。

在DyNet出現(xiàn)前,Python和C++上還沒(méi)有一個(gè)比較高效的動(dòng)態(tài)計(jì)算框架(如Chainer效率并不高)。這個(gè)由多所大學(xué)和公司的二十多位研究者共同發(fā)布新框架,一下子就找準(zhǔn)了自己的定位,即在深度學(xué)習(xí)框架中語(yǔ)言最好(Python/C++)且動(dòng)態(tài)計(jì)算最強(qiáng)。他們通過(guò)對(duì)動(dòng)態(tài)聲明的圖構(gòu)建流程的優(yōu)化,大大提高了構(gòu)建虛擬計(jì)算圖的速度,也就是說(shuō)他們的建筑設(shè)計(jì)師畫(huà)圖和規(guī)劃做得飛起。該框架在LSTM和BiLSTM等部分測(cè)試中超過(guò)了Chainer、Theano和TensorFlow,并且在當(dāng)時(shí)Theano和TensorFlow難以實(shí)現(xiàn)的樹(shù)狀模型TreeLSTM的測(cè)試中也遠(yuǎn)遠(yuǎn)打敗了Chainer,所以DyNet一出來(lái)吸引住了不少使用者。

然而好景不長(zhǎng),Torch不愧是有Facebook支持的公司,很快就推出了據(jù)說(shuō)內(nèi)部使用已久的PyTorch,將Torch移植到了Python,補(bǔ)足了自己最后一塊短板。這下子就厲害了,不僅挽留住了人氣,借助Python的力量甚至有機(jī)會(huì)從TensorFlow這位老大手里奪下一塊蛋糕。

但是不管是DyNet還是PyTorch,沒(méi)有解決多結(jié)構(gòu)輸入問(wèn)題的高效計(jì)算。它們雖然對(duì)不同的批次(mini-batch)可以給出不同的計(jì)算圖。但同一個(gè)批次內(nèi)部的樣本的形狀還是要求一致,并沒(méi)有一個(gè)成熟的解決方案來(lái)應(yīng)對(duì)這種情況。就是說(shuō)他們每建一棟樓或一批樓的可以重新設(shè)計(jì),但同時(shí)開(kāi)工的同一批樓的樣式一定是一樣的。

面對(duì)新老對(duì)手的挑戰(zhàn),TensorFlow作為深度學(xué)習(xí)框架界的霸主也不能無(wú)動(dòng)于衷,終于給出了自己關(guān)于動(dòng)態(tài)計(jì)算圖高效計(jì)算的答案——TensorFlow Fold,也就是我們今天要講的主角。這主角出場(chǎng)瞬時(shí)就hold住了場(chǎng)面,在Reddit上就有人立馬評(píng)論“... pip uninstall pytorch!”。從上一部分我們知道,TensorFlow其實(shí)是一個(gè)靜態(tài)框架,天生在解決動(dòng)態(tài)計(jì)算圖問(wèn)題上處于劣勢(shì)。你說(shuō)它一個(gè)靜態(tài)的框架,怎么就解決了動(dòng)態(tài)計(jì)算圖的問(wèn)題呢?(其實(shí)只是解決了多結(jié)構(gòu)輸入的問(wèn)題)這中間究竟有什么奧秘,讓筆者為大家娓娓道來(lái)。

| 以靜制動(dòng):巧妙的Dynamic Batching算法

TensorFlow Fold解決問(wèn)題的核心技術(shù)叫Dynamic Batching,這個(gè)技術(shù)能夠構(gòu)建一個(gè)能夠模擬任意形狀和大小的動(dòng)態(tài)計(jì)算圖的靜態(tài)圖,原本不同樣本的動(dòng)態(tài)計(jì)算圖都會(huì)被重寫(xiě)成能夠被這個(gè)計(jì)算圖高效計(jì)算的形式。這樣就巧妙地解決了動(dòng)態(tài)計(jì)算圖的高效計(jì)算問(wèn)題。打比喻就是,建筑公司請(qǐng)了一位計(jì)算機(jī)科學(xué)家寫(xiě)了一個(gè)自動(dòng)化辦公軟件,每當(dāng)房地產(chǎn)商提出一個(gè)個(gè)性社區(qū)問(wèn)題的時(shí)候,這個(gè)軟件就會(huì)把一張通用的設(shè)計(jì)圖告訴設(shè)計(jì)師去設(shè)計(jì);然后對(duì)于每一批樓的需求這個(gè)軟件都會(huì)生成對(duì)應(yīng)的施工指南,只要按照這個(gè)指南的指示,施工就可以通過(guò)多次建造通用設(shè)計(jì)圖中的一部分來(lái)完成這批樓的建造;在施工指南中軟件已經(jīng)合并每次建造時(shí)重復(fù)的工作,這樣施工隊(duì)可以并行施工,高效地完成工程。

更妙的是,這個(gè)技術(shù)并不僅在TensorFlow上能夠使用,對(duì)于其他深度學(xué)習(xí)框架完全能夠適用??梢灶A(yù)見(jiàn)的是,如果短期內(nèi)沒(méi)有更好的解決方案,這個(gè)技術(shù)很可能會(huì)被其他框架的開(kāi)發(fā)者移植到他們自己的框架上,變成MXNet Fold,PyTorch Fold等。

那為什么用靜態(tài)計(jì)算圖模擬動(dòng)態(tài)計(jì)算圖是可能的?因?yàn)殡m然動(dòng)態(tài)計(jì)算圖的形狀和大小千變?nèi)f化,但對(duì)于一個(gè)模型來(lái)說(shuō)它們的基本組件卻可以簡(jiǎn)單劃分為兩種:Tensor(張量)和Operation(操作)。

Tensor,可以看做各種各樣的數(shù)據(jù)塊,主要包括輸入的樣本和計(jì)算結(jié)果,Tensor的類型可以按照shape(形狀)和data type(數(shù)據(jù)類型)劃分,具有相同shape和data type的Tensor可以被劃分為一類,就像相同大小和材質(zhì)的磚頭;這里的shape并不包括batch size,它就像磚頭的個(gè)數(shù),一疊不管是十塊還是五塊,只要磚頭的大小材質(zhì)一樣,我們認(rèn)為是同一個(gè)類。

Operation,并不是是指加減乘除這樣最底層的操作,而是指一塊小的計(jì)算子圖,一塊計(jì)算子圖接受某種確定類型的Tensor作為輸入,并輸出某種確定類型的Tensor。這塊計(jì)算子圖在動(dòng)態(tài)構(gòu)建圖的過(guò)程中并不會(huì)被拆開(kāi),而是作為一個(gè)整體被適用,比如RNN的Cell或其他用戶自己定義的一些固定的操作組合。

對(duì)于某一個(gè)模型如樹(shù)狀RNN來(lái)說(shuō),但它只會(huì)有限種Operation和Tensor類型,當(dāng)我們將這些Operation和Tensor類型放到一起,我們就有了一個(gè)通用子圖,這時(shí)候只需要一些控制部件控制這個(gè)每次子圖執(zhí)行的部分(上文有提到每次執(zhí)行的實(shí)體計(jì)算圖可以只是虛擬計(jì)算圖的一部分)以及組合方式,我們就可以模擬對(duì)應(yīng)模型所有可能的計(jì)算圖。達(dá)成這種控制只需TensorFlow的三個(gè)部件:tf.gather、tf.concat和tf.while_loop。

說(shuō)完通用子圖的組成,我們?cè)僬f(shuō)說(shuō)Dynamic Batching怎么將不同結(jié)構(gòu)的計(jì)算圖重寫(xiě)成可以用通用子圖計(jì)算的形式。Dynamic Batching是一個(gè)貪婪(greedy)的算法,它接受一個(gè)有向無(wú)環(huán)計(jì)算圖作為輸入:

  • 給圖中的每一個(gè)節(jié)點(diǎn)(操作)標(biāo)注一個(gè)深度,所有沒(méi)有任何依賴的節(jié)點(diǎn)標(biāo)注為深度0,依賴的節(jié)點(diǎn)深度最大為d的節(jié)點(diǎn)的深度標(biāo)注為d+1;

  • 在圖中插入pass-through(直通)的操作,使得第d+1層只依賴于第d層;

  • 將同一深度涉及相同操作的節(jié)點(diǎn)合并到一起,方便并行計(jì)算;

  • 將同一深度的計(jì)算結(jié)果按Tensor類型(包括Tensor的形狀和數(shù)值類型)有序拼接在一起;

  • 將輸入原始計(jì)算圖中的每條邊標(biāo)記上(深度,數(shù)據(jù)類型,序號(hào)),對(duì)應(yīng)它們可以獲取上一層計(jì)算結(jié)果的位置。

對(duì)于一批不同結(jié)構(gòu)的計(jì)算圖,我們可以把它們看做不連通的大圖同樣處理。上面算法的第三步會(huì)將這批圖中同一深度的相同操作進(jìn)行合并,方便并行計(jì)算。說(shuō)完圖的構(gòu)建,我們?cè)僬f(shuō)說(shuō)怎么執(zhí)行:算法在每次迭代中執(zhí)行一個(gè)深度的計(jì)算,使用tf.while_loop從深度0一直執(zhí)行到最大深度。在每一個(gè)深度中,tf.gather根據(jù)上面第五步的標(biāo)記為各個(gè)Operation獲取當(dāng)前深度各條輸入邊的Tensor,如果某個(gè)Operation沒(méi)有獲取到任何Tensor,說(shuō)明當(dāng)前深度這個(gè)Operation不需要執(zhí)行計(jì)算。Operation執(zhí)行完后tf.concat將相同Tensor類型的計(jì)算結(jié)果拼接在一起,提供給下一個(gè)深度的計(jì)算。

以靜制動(dòng)的TensorFlow Fold

上面這一幅圖來(lái)著官方論文,左邊是Dynamic Batching為二叉TreeRNN構(gòu)建的通用計(jì)算圖。右邊是一顆簡(jiǎn)單的語(yǔ)法解析樹(shù)。通用計(jì)算圖中有兩種Tensor,代表單詞的編碼整數(shù)、詞向量/hidden向量的128維向量。Operation也只有兩個(gè)一個(gè)詞向量查表操作(embed lookup)和一個(gè)RNN的Cell。圖中g(shù)ather和concat之間的直連表示直通(pass-through)操作。右邊的語(yǔ)法解析樹(shù)可以分為三層計(jì)算被執(zhí)行:第一層,將1、3、5通過(guò)詞向量查表操作,輸出3個(gè)128維的詞向量;第二層,1和3對(duì)應(yīng)的詞向量通過(guò)RNN Cell輸出一個(gè)128維的隱含層向量,5對(duì)應(yīng)的詞向量直通輸出;第三層,上一層計(jì)算的隱含層向量和5對(duì)應(yīng)的詞向量通過(guò)RNN Cell,輸出一個(gè)128維的隱含層向量。計(jì)算完畢。

那這個(gè)算法的效果怎么樣呢?它在TreeLSTM的實(shí)驗(yàn)中,8核英特爾CPU的可以加速20多倍,而英偉達(dá)GTX-1080上可以加速100倍左右。這個(gè)加速比是采用Dynamic Batching算法批處理中平均每個(gè)樣本執(zhí)行的平均時(shí)間和單個(gè)樣本不作批處理的執(zhí)行時(shí)間之比。這里不包含構(gòu)建虛擬圖所需要的時(shí)間。

| TensorFlow Fold:封裝在靜態(tài)框架上的動(dòng)態(tài)接口

上面的Dynamic Batching的算法很繁瑣,但不用當(dāng)心,這個(gè)過(guò)程是由框架自動(dòng)完成的,作為框架的使用者,我們只要知道怎么調(diào)用官方給出來(lái)的接口就可以了。新推出的TensorFlow Fold就是一個(gè)TensorFlow的封裝,設(shè)計(jì)參考了函數(shù)式編程的一些思想,目的就是方便用戶快速地構(gòu)建動(dòng)態(tài)計(jì)算圖。下面我們來(lái)簡(jiǎn)單地瀏覽一下,要進(jìn)一步了解可以去看官方的教學(xué)文檔。

TensorFlow Fold提供了一些函數(shù)專門(mén)用來(lái)處理序列(x1,...,xn):

  • Map(f):計(jì)算[f(x1) ,...,f(xn)]將函數(shù)f應(yīng)用到每一個(gè)序列的元素,比如將句子中的每一個(gè)詞轉(zhuǎn)化為詞向量;

  • Fold(g, z):計(jì)算g(...,g(z, x1), x2), ...,xn ),比如說(shuō)展開(kāi)一個(gè)RNN(循環(huán)神經(jīng)網(wǎng)絡(luò));

  • Reduce ():計(jì)算g(Reduce(g)[x,...,xn/2],Reduce(g)[xn/2 ,...,xn],將函數(shù)g應(yīng)用到一顆平衡二叉樹(shù)上,比如對(duì)序列中的元素作max或sum-pooling。

由于TensorFlow原本的基本單元Tensor不適合用于構(gòu)建動(dòng)態(tài)圖,所以Fold引入新的基本組件Block。Block有明確的一個(gè)輸入類型和一個(gè)輸出類型,包括:

  1. Input:來(lái)著編程語(yǔ)言如Python中元素,比如字典等;

  2. Tensor:擁有數(shù)據(jù)類型和形狀的TensorFlow基本模塊;

  3. Tuple (t1 ,...,t):括號(hào)中的每一個(gè)t表示對(duì)應(yīng)位置的類型;

  4. Sequence ():一個(gè)不定長(zhǎng)的擁有類型為t的元素的序列;

  5. Void:?jiǎn)卧愋汀_@些基本類型可以相互嵌套,比如一個(gè)Block的輸入類型可以是Input類型的Tuple。

用來(lái)創(chuàng)建Block的基本函數(shù)有:

  1. Scalar:將Python標(biāo)量轉(zhuǎn)化為T(mén)ensor;

  2. Tensor:將Numpy數(shù)組轉(zhuǎn)化為T(mén)ensor;

  3. Function ():創(chuàng)建一個(gè)Operation;

  4. InputTransform ():用于預(yù)處理Python類型。

用來(lái)組合Block的基本函數(shù)有:

  1. b1>>b2,流水線(pipeline):將b的輸出作為b的輸入;

  2. Record({l1b1,..., lnbn}): 接受一個(gè)Python字典為輸入,對(duì)字典中key值為l的value應(yīng)用;

  3. OneOf (b1,...,bn):根據(jù)輸入條件應(yīng)用b1,...bn中的一個(gè);

  4. Optional (b):OneOf的特例,如果輸入不為None,應(yīng)用b;

  5. AllOf (b1,...,bn):輸入應(yīng)用中的每一個(gè)。

用來(lái)組合Block的高級(jí)函數(shù)有:

  1. Composition():流水線的升級(jí)版,流水線只能處理串行的流程,Composition()創(chuàng)建一個(gè)Scope對(duì)象,在這個(gè)Scope的縮進(jìn)范圍內(nèi),采用b.reads(b1,...,bn )來(lái)讀取多個(gè)數(shù)據(jù)流,可以用于構(gòu)建多分支結(jié)構(gòu);

  2. ForwardDeclaration():用來(lái)創(chuàng)建遞歸結(jié)構(gòu),這個(gè)函數(shù)可以先定義一個(gè)預(yù)先占位的表達(dá)式expr,等這個(gè)表達(dá)式定義完再用expr.resolve_to(expr_def),將表達(dá)式遞歸地代入,這是用來(lái)創(chuàng)建樹(shù)結(jié)構(gòu)計(jì)算圖必不可少的工具。

| 總結(jié)

在動(dòng)態(tài)圖計(jì)算領(lǐng)域TensorFlow Fold目前領(lǐng)先一步,卻也不是高枕無(wú)憂,只要MXNet, PyTorch等競(jìng)爭(zhēng)對(duì)手抓緊把Dynamic Batching算法實(shí)現(xiàn)出來(lái),或進(jìn)一步想出更好的解決方案,就能很快趕上。而且TensorFlow Fold目前只支持TensorFlow 1.0版本,但只有盡快支持所有版本,才能讓更多的用戶使用上。另外工具的發(fā)展也會(huì)帶動(dòng)學(xué)科的進(jìn)步,隨著動(dòng)態(tài)計(jì)算圖的實(shí)現(xiàn)難度的下降和計(jì)算效率的提高,研究者們會(huì)越來(lái)越多地進(jìn)入這個(gè)領(lǐng)域,可以預(yù)期的是接下來(lái)一段時(shí)間肯定會(huì)有更多復(fù)雜結(jié)構(gòu)的模型和數(shù)據(jù)集涌現(xiàn)出來(lái)。未來(lái)將會(huì)如何,諸君盡請(qǐng)期待。

雷鋒網(wǎng)按:本文原作者劉思聰,首發(fā)于知乎專欄AI帶路黨

雷鋒網(wǎng)

相關(guān)文章:

TensorFlow 全網(wǎng)最全學(xué)習(xí)資料匯總之TensorFlow的技術(shù)應(yīng)用【4】

Tensorflow 全網(wǎng)最全學(xué)習(xí)資料匯總之框架平臺(tái)的綜合對(duì)比【3】

Tensorflow 全網(wǎng)最全學(xué)習(xí)資料匯總之Tensorflow 的入門(mén)與安裝【2】

Tensorflow 全網(wǎng)最全學(xué)習(xí)資料匯總之Tensorflow的迭代更新【1】

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。

以靜制動(dòng)的TensorFlow Fold

分享:
相關(guān)文章

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開(kāi)發(fā)者。更多精彩內(nèi)容,請(qǐng)?jiān)L問(wèn):yanxishe.com
當(dāng)月熱門(mén)文章
最新文章
請(qǐng)?zhí)顚?xiě)申請(qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡(jiǎn)介
為了您的賬戶安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說(shuō)