摘要:首先是最頂層的抽象,這個(gè)里面最基礎(chǔ)的就是和,記憶中和的抽象是類(lèi)似的,將計(jì)算結(jié)果和偏導(dǎo)結(jié)果用一個(gè)抽象類(lèi)來(lái)表示了。不過(guò),本身并沒(méi)有像其它兩個(gè)庫(kù)一樣提供,等模型的抽象類(lèi),因此往往不會(huì)直接使用去寫(xiě)模型。
本文將從deep learning 相關(guān)工具庫(kù)的使用者角度來(lái)介紹下github上stars數(shù)排在前面的幾個(gè)庫(kù)(tensorflow, keras, torch, theano, skflow, lasagne, blocks)。由于我的主要研究?jī)?nèi)容為文本相關(guān)的工作,所以各個(gè)庫(kù)的分析帶有一定主觀(guān)因素,以RNN模型為主,CNN相關(guān)的內(nèi)容了解得不是特別深入(本文沒(méi)有比較caffe和mxnet,其實(shí)主要原因還是自己C++太久沒(méi)用了......)。
閱讀本文你會(huì)了解:
各個(gè)庫(kù)是如何對(duì)神經(jīng)網(wǎng)絡(luò)中的結(jié)構(gòu)和計(jì)算單元進(jìn)行抽象的;
如何用每個(gè)庫(kù)跑RNN相關(guān)的模型;
各個(gè)庫(kù)學(xué)習(xí)和使用的難以程度對(duì)比;
在各個(gè)庫(kù)基礎(chǔ)之上進(jìn)一步改進(jìn)和開(kāi)發(fā)的難易程度;
本文不會(huì)涉及:
各個(gè)庫(kù)運(yùn)行時(shí)間效率的對(duì)比(我沒(méi)有自己做過(guò)相關(guān)的對(duì)比實(shí)驗(yàn),但是網(wǎng)上有很多數(shù)據(jù)可以查);
CNN相關(guān)模型的構(gòu)建(前面提到了自己最近對(duì)這塊了解得不多);
RNN相關(guān)模型的原理和解釋?zhuān)ňW(wǎng)上很多資料,可以先學(xué)習(xí)后再進(jìn)一步閱讀);
先說(shuō)說(shuō)這幾個(gè)庫(kù)之間的大致關(guān)系
對(duì)于一個(gè)優(yōu)秀的深度學(xué)習(xí)系統(tǒng),或者更廣來(lái)說(shuō)優(yōu)秀的科學(xué)計(jì)算系統(tǒng),最重要的是編程接口的設(shè)計(jì)。他們都采用將一個(gè)領(lǐng)域特定語(yǔ)言(domain specific language)嵌入到一個(gè)主語(yǔ)言中。例如numpy將矩陣運(yùn)算嵌入到python中。這類(lèi)嵌入一般分為兩種,其中一種嵌入的較淺,其中每個(gè)語(yǔ)句都按原來(lái)的意思執(zhí)行,且通常采用命令式編程(imperative programming),其中numpy和Torch就是屬于這種。而另一種則用一種深的嵌入方式,提供一整套針對(duì)具體應(yīng)用的迷你語(yǔ)言。這一種通常使用聲明式語(yǔ)言(declarative programing),既用戶(hù)只需要聲明要做什么,而具體執(zhí)行則由系統(tǒng)完成。這類(lèi)系統(tǒng)包括Caffe,theano和剛公布的TensorFlow。
以上是摘自MXNet設(shè)計(jì)和實(shí)現(xiàn)中的一段話(huà)。理解了這段話(huà)后,對(duì)后面各個(gè)庫(kù)的進(jìn)一步理解很有幫助。MXNet的設(shè)計(jì)者表示融合了這兩種編程模式,我們先拋開(kāi)mxnet,如上所述torch是采用命令式編程,然后theano和tensorflow是采用聲明式編程,skflow對(duì)常用的tensorflow的封裝,lasagne是對(duì)theano的封裝,blocks除了對(duì)theano進(jìn)行封裝之外還提供了額外的處理機(jī)制,keras則是用一套接口同時(shí)封裝了theano和tensorflow。
從theano說(shuō)起
前面說(shuō)theano是聲明式語(yǔ)言,其基本過(guò)程可以描述為以下幾步:
定義輸入變量(x,y),輸出變量(z);
描述變量之間的計(jì)算關(guān)系(z = x + y);
編譯(f = theano.function([x, y], z);
求值(f(1,2));
那么,如果我想用theano寫(xiě)一個(gè)lstm呢?(具體參見(jiàn)這里)
準(zhǔn)備輸入變量x及x_mask(維度為 batch_size * sentence_length * vector_size),目標(biāo)變量target(維度為batch_size)
定義并初始化lstm結(jié)構(gòu)單元中的參數(shù)(i, f, o, c)
定義好一個(gè)scan函數(shù),在scan函數(shù)中完成每個(gè)結(jié)構(gòu)單元的計(jì)算,根據(jù)lstm網(wǎng)絡(luò)的性質(zhì),將結(jié)構(gòu)單元的輸出導(dǎo)入到下一步的輸入。在這里,theano中的scan就是一個(gè)加強(qiáng)版的for循環(huán)
計(jì)算loss,采用某種算法更新參數(shù)
編譯,f = theano.function([x, x_mask, target], loss)
對(duì)每個(gè)batch求值
注意前面加黑的幾個(gè)關(guān)鍵詞,在后我們將反復(fù)看到每個(gè)庫(kù)的設(shè)計(jì)者對(duì)這幾個(gè)概念的不同理解。
接著說(shuō)tensorflow
tensorflow的設(shè)計(jì)思想和theano很接近。但是我感覺(jué),tensorflow似乎更強(qiáng)調(diào)整體性和結(jié)構(gòu)型。二者的明顯區(qū)別在于:
tensorflow默認(rèn)有一個(gè)Graph的結(jié)構(gòu),所有添加的結(jié)點(diǎn)都是在這個(gè)圖結(jié)構(gòu)上,但是theano中并沒(méi)有這個(gè)概念。我的理解是這個(gè)Graph結(jié)構(gòu)對(duì)于變量的管理會(huì)方便點(diǎn)。
tensorflow目前能夠在單機(jī)上多卡并行處理,其機(jī)制是通過(guò)指定gpu來(lái)分配計(jì)算過(guò)程的。因此,可以說(shuō)其并行機(jī)制是數(shù)據(jù)層面的。而theano需要在載入包之前就指定gpu,其余的很多地方都是相似的,只是換了名字而已,比如: tensorflow中的variable對(duì)應(yīng)theano下的共享變量shared variables, tensorflow中的placeholder對(duì)應(yīng)theano中的tensor變量, 另外tensorflow中為了避免變量的來(lái)回復(fù)制,其所用的tensor的概念和theano中不太一樣
然后來(lái)看看tensorflow是怎么實(shí)現(xiàn)一個(gè)LSTM網(wǎng)絡(luò)的,與theano不同,tensorflow已經(jīng)對(duì)rnn_cell和lstm_cell做了封裝,因此寫(xiě)起來(lái)容易了很多。
定義好輸入及中間變量
采用for循環(huán)將每個(gè)lstm_cell的輸入輸出組裝起來(lái)
剩下的也就沒(méi)有新意了,計(jì)算loss,更新state
我們后面再討論這種封裝方式與其他庫(kù)的對(duì)比。
再說(shuō)torch
torch的代碼寫(xiě)起來(lái)有點(diǎn)像寫(xiě)matlab,本身torch是一個(gè)科學(xué)計(jì)算的大集合(我感覺(jué)只是借了lua這個(gè)語(yǔ)言一個(gè)外殼,方便和c及c++交互罷了,從這個(gè)角度來(lái)看,我覺(jué)得julia這門(mén)語(yǔ)言似乎大有潛力),這里我們主要是討論其中的nn和rnn模塊。
我自己對(duì)lua及torch都不是很熟,但是好在語(yǔ)法不復(fù)雜,基本都能看懂,建議大家也能花點(diǎn)時(shí)間學(xué)習(xí)下,這樣下次看到哪篇paper里實(shí)驗(yàn)部分用torch寫(xiě)的時(shí)候,不至于完全看不懂。盡管我對(duì)torch的了解不深,但是不得不說(shuō)torch對(duì)剩下其它幾個(gè)庫(kù)的設(shè)計(jì)影響非常大!
在torch的nn模塊里,首先對(duì)整個(gè)網(wǎng)絡(luò)結(jié)構(gòu)做了分類(lèi)抽象。首先是最頂層的抽象Model,這個(gè)里面最基礎(chǔ)的就是output和grad_output,記憶中和caffe的抽象是類(lèi)似的,將計(jì)算結(jié)果和偏導(dǎo)結(jié)果用一個(gè)抽象類(lèi)來(lái)表示了。然后是Sequential, Parallel 及 Concat這三個(gè)容器。Sequential用于描述網(wǎng)絡(luò)中一層層的序列關(guān)系,典型的就是MLP,Parallel可以用于分別處理輸入的不同維度,而Concat則可以用于合并操作。一般來(lái)說(shuō),我們現(xiàn)在的網(wǎng)絡(luò)結(jié)構(gòu)都可以通過(guò)這三種結(jié)構(gòu)拼接得到。
然后再看看torch的rnn模塊中如何構(gòu)建lstm網(wǎng)絡(luò)的:
和tensorflow一樣,首先是繼承自AbstractRecurrent的一個(gè)抽象,然后是參數(shù)配置和初始化,不同之處在于,其對(duì)LSTM中的門(mén)結(jié)構(gòu)也做了進(jìn)一步抽象,最后,用Sequence代替了for循環(huán)的功能,從而提供一個(gè)完整的網(wǎng)絡(luò)結(jié)構(gòu)。
小結(jié)
通過(guò)上面的簡(jiǎn)單描述,我們對(duì)這三個(gè)基本庫(kù)有了些大致的印象。
torch是最龐大的庫(kù),如果一開(kāi)始就選擇這個(gè)庫(kù)作為工具的話(huà),還算說(shuō)得過(guò)去,否則學(xué)習(xí)的代價(jià)有點(diǎn)大,因?yàn)槠匠W鰧?shí)驗(yàn)涉及的往往不只是跑跑模型這么簡(jiǎn)單,還涉及到數(shù)據(jù)的預(yù)處理與分析,相關(guān)圖表的繪制,對(duì)比實(shí)驗(yàn)等等。這樣一來(lái)要學(xué)習(xí)的東西就比較多了。
theano由于借用了numpy,scipy等python下科學(xué)計(jì)算的庫(kù),相對(duì)torch來(lái)說(shuō)要輕松一些。不過(guò),theano本身并沒(méi)有像其它兩個(gè)庫(kù)一樣提供cnn,rnn等模型的抽象類(lèi),因此往往不會(huì)直接使用theano去寫(xiě)模型。
tensorflow則更像是為神經(jīng)網(wǎng)絡(luò)相關(guān)模型而定制的。從頂層設(shè)計(jì)上就以graph為依托,通過(guò)不同的Session來(lái)控制計(jì)算流。
從庫(kù)的使用者角度來(lái)說(shuō),tensorflow和torch都還不錯(cuò)。但是,如果涉及網(wǎng)絡(luò)結(jié)構(gòu)(這里特指RNN相關(guān)的網(wǎng)絡(luò))修改,那么torch要相對(duì)容易一些,主要是多了一個(gè)Gate的抽象,中間參數(shù)的處理上不需要太操心,而tensorflow中LSTM和RNN抽象類(lèi)的耦合比較緊,如果涉及內(nèi)部結(jié)構(gòu)的修改會(huì)稍稍麻煩點(diǎn),需要重寫(xiě)的方法比較多。
tensorflow開(kāi)源時(shí)間不久,先拋開(kāi)不計(jì)。由于theano缺少對(duì)神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的抽象,而torch中nn模塊又設(shè)計(jì)得很合理,于是后面涌現(xiàn)的基于theano的庫(kù)多多少少都有所參照。
Keras
keras設(shè)計(jì)的level有點(diǎn)高,其設(shè)想的就是底層的計(jì)算模塊是可拔插的。這個(gè)功能當(dāng)然看起來(lái)很炫酷,我想用tensorflow就用tensorflow,想用theano就用theano作為計(jì)算內(nèi)核,然而代價(jià)也是有的,如果你想改其中的結(jié)構(gòu),復(fù)雜程度立馬上去了。我覺(jué)得這個(gè)庫(kù)的目標(biāo)用戶(hù)僅限于使用現(xiàn)有神經(jīng)網(wǎng)絡(luò)單元結(jié)構(gòu)的人。如果你發(fā)現(xiàn)某個(gè)結(jié)構(gòu)keras里沒(méi)有?沒(méi)事,這個(gè)項(xiàng)目開(kāi)發(fā)者眾多,發(fā)起個(gè)issue,馬上就有人填坑(比如highway network, 我在其它幾個(gè)庫(kù)里還沒(méi)發(fā)現(xiàn),這里居然就有了,雖然并不復(fù)雜)。如果你想構(gòu)造個(gè)自己的結(jié)構(gòu)單元?那得了,您還是看看后面幾個(gè)庫(kù)吧。
綜上所述,keras較大的亮點(diǎn)就是,簡(jiǎn)潔而全面。正所謂人多力量大嘛! 由于其底層處于兼容性做了一套自己的封裝,想改的話(huà)稍顯麻煩。
如果你覺(jué)得看完keras還不知道怎么用?想來(lái)點(diǎn)更簡(jiǎn)單的?有!sklearn用過(guò)把,fit, predict兩步即可,傻瓜式操作,人人都是機(jī)器學(xué)習(xí)大神。skflow就是類(lèi)似的,看名字就知道了。不過(guò)是基于tensorflow開(kāi)發(fā)的。我反正是沒(méi)用過(guò)這個(gè)庫(kù)......
Lasagne
lasagne對(duì)網(wǎng)絡(luò)結(jié)構(gòu)的抽象和上面的幾個(gè)庫(kù)有很大的不同,在lasagne中基本抽象單元是Layer,對(duì)應(yīng)到整個(gè)神經(jīng)網(wǎng)絡(luò)中的一層結(jié)構(gòu)。這個(gè)layer可以是cnn也可以是rnn結(jié)構(gòu),除此之外還有一個(gè)MergeLayer,就是多輸入多輸出的結(jié)構(gòu)。和torch一樣,也對(duì)Gate門(mén)結(jié)構(gòu)做了抽象。
這樣設(shè)計(jì)有好處也有麻煩的地方:
好處是,寫(xiě)出來(lái)的網(wǎng)絡(luò)結(jié)構(gòu)很簡(jiǎn)潔,網(wǎng)絡(luò)結(jié)構(gòu)的初始化和配置都包含在layer初始化參數(shù)里;
不方便的地方是,只引入了layer結(jié)構(gòu)抽象層,是在是有些單一,如果能再加一個(gè)類(lèi)似torch中的Sequential結(jié)構(gòu)就perfect了,因?yàn)橐坏┥婕暗窖h(huán),就不得不回頭去使用theano中的scan函數(shù),說(shuō)實(shí)話(huà),scan函數(shù)設(shè)計(jì)得太復(fù)雜了點(diǎn)。(當(dāng)然,作者是不這么認(rèn)為的,設(shè)計(jì)者認(rèn)為lasagne并不是要將theano完全隔離開(kāi),相反,lasagne中的所有變量都應(yīng)該相對(duì)theano是透明的Transparency)。
此外,lasagne中LSTM網(wǎng)絡(luò)的實(shí)現(xiàn)與前面的大致相同,實(shí)現(xiàn)細(xì)節(jié)上,lasagne中的lstm類(lèi)直接繼承自MergeLayer,然后內(nèi)部采用scan函數(shù)實(shí)現(xiàn),像其它庫(kù)由于有循環(huán)結(jié)構(gòu)的抽象實(shí)現(xiàn),因此每個(gè)lstm_cell類(lèi)只需要完成單個(gè)結(jié)點(diǎn)內(nèi)部的運(yùn)算(也即只實(shí)現(xiàn)scan函數(shù)中的_step輔助函數(shù))
總的感覺(jué)就是,lasagne在類(lèi)的抽象上并沒(méi)有過(guò)度設(shè)計(jì),整個(gè)網(wǎng)絡(luò)中的參數(shù)采用自頂向下的寬度優(yōu)先算法獲取,因此,只要你愿意,你可以任意在這個(gè)網(wǎng)絡(luò)上“鑿”個(gè)洞,得到該局部網(wǎng)絡(luò)的關(guān)系。有一定的擴(kuò)展性?xún)?yōu)勢(shì)。
Blocks
這個(gè)庫(kù)是我最看好的一個(gè)庫(kù),作者應(yīng)該從torch中借鑒了很多思想。
在這個(gè)庫(kù)中,每一個(gè)運(yùn)算都看做是一塊磚,這塊磚涉及配置、分配、應(yīng)用和初始化這四步。更重要的一點(diǎn)是,brick與brick之間可以嵌套,從而得到更抽象的brick。這下子解決了我們前面一直碰到的一個(gè)問(wèn)題,:抽象層次的把握!前面大多都是根據(jù)抽象層次的不同設(shè)計(jì)各自的類(lèi),而blocks通過(guò)嵌套將類(lèi)統(tǒng)一起來(lái),這樣我們?cè)谠O(shè)計(jì)自己的模塊時(shí),可以很方便地選取合適尺寸的brick。
相比lasagne中直接根據(jù)layer.get_output來(lái)獲取參數(shù),blocks采用了ComputationGraph來(lái)管理整個(gè)網(wǎng)絡(luò)結(jié)構(gòu),我的理解是,lasagne的那種方式還是有點(diǎn)野蠻......采用ComputationGraph之后,可以同時(shí)制定輸入和輸出對(duì)象,這樣即使網(wǎng)絡(luò)結(jié)構(gòu)變得更復(fù)雜了,我們也可以隨心所欲指定其中某個(gè)部分來(lái)更新。
下面用blocks文檔中關(guān)于rnn的一個(gè)模型來(lái)說(shuō)明blocks在個(gè)性化定制方面是多么優(yōu)雅。先看圖:
如果要設(shè)計(jì)這樣一個(gè)stack的模型,就需要make your hands dirty 了。在lasagne中,這個(gè)整體會(huì)被看做一個(gè)layer,所以需要自己重寫(xiě)一個(gè)layer,那跟直接用theano寫(xiě)無(wú)異了......keras中也沒(méi)有提供現(xiàn)有的模型,所以......對(duì)于tensorflow和torch來(lái)說(shuō),需要重寫(xiě)AbstractRecurrent類(lèi),從而可以讓其接受兩個(gè)輸入。
相比之下Keras提供的解決方案就比較優(yōu)雅,通過(guò)iterate將simplerecurrent在time_step維度上縮短到了1步,然后再將整個(gè)連接結(jié)構(gòu)封裝起來(lái)。(也許其它幾個(gè)庫(kù)也有類(lèi)似的控制,暫時(shí)沒(méi)發(fā)現(xiàn))
當(dāng)然,除了上面這些抽象層面的易用性,blocks還提供了豐富的可視化調(diào)試和控制接口,以及數(shù)據(jù)預(yù)處理的fuel模塊。這些功能在整個(gè)工程變得越來(lái)越臃腫的時(shí)候還是很實(shí)用的。
總結(jié)
在了解theano的基礎(chǔ)上,如果只是想跑一下現(xiàn)有的模型不關(guān)注底層的實(shí)現(xiàn),可以直接用Keras,上手快,模塊清晰。如果打算持續(xù)投入,涉及大量網(wǎng)絡(luò)結(jié)構(gòu)改進(jìn),推薦使用bricks,其對(duì)訓(xùn)練過(guò)程的控制有著獨(dú)特的優(yōu)勢(shì)。
另外需要注意的一點(diǎn)是,同樣的數(shù)據(jù),用不同庫(kù)的同一個(gè)算法時(shí),結(jié)果很可能會(huì)出現(xiàn)幾個(gè)點(diǎn)的差異,這往往是不同庫(kù)中對(duì)默認(rèn)參數(shù)的初始化方式不同引起的,需要仔細(xì)檢查下。
歡迎加入本站公開(kāi)興趣群商業(yè)智能與數(shù)據(jù)分析群
興趣范圍包括各種讓數(shù)據(jù)產(chǎn)生價(jià)值的辦法,實(shí)際應(yīng)用案例分享與討論,分析工具,ETL工具,數(shù)據(jù)倉(cāng)庫(kù),數(shù)據(jù)挖掘工具,報(bào)表系統(tǒng)等全方位知識(shí)
QQ群:81035754
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/4340.html
摘要:深度學(xué)習(xí)通過(guò)組合低層特征形成更加抽象的高層表示屬性類(lèi)別或特征,以發(fā)現(xiàn)數(shù)據(jù)的分布式特征表示。深度學(xué)習(xí)的概念由等人于年提出。但是自年以來(lái),機(jī)器學(xué)習(xí)領(lǐng)域,取得了突破性的進(jìn)展。 深度學(xué)習(xí)是機(jī)器學(xué)習(xí)研究中的一個(gè)新的領(lǐng)域,其動(dòng)機(jī)在于建立、模擬人腦進(jìn)行分析學(xué)習(xí)的神經(jīng)網(wǎng)絡(luò),它模仿人腦的機(jī)制來(lái)解釋數(shù)據(jù),例如圖像,聲音和文本。深度學(xué)習(xí)是無(wú)監(jiān)督學(xué)習(xí)的一種。 深度學(xué)習(xí)的概念源于人工神經(jīng)網(wǎng)絡(luò)的研究。含多隱層的多層感知...
摘要:考慮這樣一個(gè)計(jì)算集合,它可以被允許在每一個(gè)節(jié)點(diǎn)和可能的圖結(jié)構(gòu)中,并定義了一個(gè)函數(shù)族。傳統(tǒng)的前饋神經(jīng)網(wǎng)絡(luò)能夠被看做擁有等于層數(shù)的深度比如對(duì)于輸出層為隱層數(shù)加。理論結(jié)果證實(shí)那些事實(shí)上所需要的節(jié)點(diǎn)數(shù)隨著輸入的大小指數(shù)增長(zhǎng)的函數(shù)族是存在的。 查看論文 Yoshua Bengio, Learning Deep Architectures for AI, Foundations and Trends i...
摘要:有監(jiān)督學(xué)習(xí)與無(wú)監(jiān)督學(xué)習(xí),分類(lèi)回歸,密度估計(jì)聚類(lèi),深度學(xué)習(xí),,有監(jiān)督學(xué)習(xí)和無(wú)監(jiān)督學(xué)習(xí)給定一組數(shù)據(jù),為,。由于不需要事先根據(jù)訓(xùn)練數(shù)據(jù)去聚類(lèi)器,故屬于無(wú)監(jiān)督學(xué)習(xí)。 Deep Learning是機(jī)器學(xué)習(xí)中一個(gè)非常接近AI的領(lǐng)域,其動(dòng)機(jī)在于建立、模擬人腦進(jìn)行分析學(xué)習(xí)的神經(jīng)網(wǎng)絡(luò),最近研究了機(jī)器學(xué)習(xí)中一些深度學(xué)習(xí)的相關(guān)知識(shí),本文給出一些很有用的資料和心得。Key Words:有監(jiān)督學(xué)習(xí)與無(wú)監(jiān)督學(xué)習(xí),分類(lèi)...
摘要:之機(jī)器學(xué)習(xí)第一彈。機(jī)器學(xué)習(xí)是發(fā)展中應(yīng)用廣泛的一個(gè)領(lǐng)域。庫(kù)集成了一些常用的機(jī)器學(xué)習(xí)方法在進(jìn)行機(jī)器學(xué)習(xí)任務(wù)時(shí)并不需要實(shí)現(xiàn)算法只需要簡(jiǎn)單的調(diào)用庫(kù)中提供的模塊就能完成大多數(shù)的機(jī)器學(xué)習(xí)任務(wù)。 ...
閱讀 1055·2021-09-13 10:29
閱讀 3403·2019-08-29 18:31
閱讀 2651·2019-08-29 11:15
閱讀 3025·2019-08-26 13:25
閱讀 1384·2019-08-26 12:00
閱讀 2329·2019-08-26 11:41
閱讀 3430·2019-08-26 10:31
閱讀 1501·2019-08-26 10:25