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