如何評價 Theano?


Theano 雖然誕生在 LISA lab,但是本身和深度學習沒有關係,需求拆分非常到位。

為什麼會有 Theano?無非是因為一群研究者想用 Python,但是純用 NumPy/SciPy 太痛苦,得手動推導全部函數再在代碼里堆起來。想調用一下庫就能得到導數的符號表達式?那得上計算機代數系統,可是當時 SymPy 也出來沒兩年,注重符號運算本身,與後續的數值計算銜接不太好。

於是大家造了些和 SymPy 的功能有關的輪子,並且和數值計算無縫對接,注重性能和數值穩定性。惰性求值,自動在 GPU 上運行,都是以這兩點為考量。把這些輪子整理一下就有了 Theano 的原型。

Theano 的結構、實現不一定是最優的,但現階段只有它填補了這一空缺,而且相對成熟,所以大家都用它。它的功能也給 Python 的進一步進化指了一個方向(很多科學計算包在考慮利用 Theano 進行加速),將來的趨勢應該是 NumPy、SymPy、Theano 整合到一起,新的 SciPy 構建在這個包之上並保持介面不變。

PS:現在你可以用 SymPy 算符號表達式,再扔給 Theano 作數值計算。 Numeric Computation


看到大家都在說 Theano 好 (不好不要用不要打擾我發paper飛升!)我在這裡唱唱反調。

1. 捉雞的 Scan

我對 theano 一半以上的糾結都是在 scan 上。

作為在表達式中表示尋循環的方法,scan 我相信大家都用過。我不知道以下問題大家有沒有碰到過:

a. scan 套 scan 速度感人。

我就默認大家都實現過 RNN 或者 LSTM. 在實現這一類基於序列的神經網路中,你幾乎至少要用一層 scan. 這是正常情況。一般在這樣的情況下 compile 相關的 function 只需要幾分鐘時間,最多總不會超過20分鐘。

然而大家為了灌水總要在模型上修修改改,有時候難免會遇到 scan 套 scan 的情況。這種時候 compile function 的時候花費時間會彪的飛起,我最長碰上過 compile 1個小時的情況。

b. scan 中糟糕參數的傳遞限制

比如說你用 scan 實現一個 recurrent neural network, 你在計算 h_{t} 的時候,要用到上一步的 h_{t-1}. 這時h_{t-1} 是通過上一次 scan 方法的return得到的。如果你的模型複雜一點,那你在scan方法內就要返回更多的東西,比如 cell state c_{t-1}, 如果你還要做變種,那你就要額外再加些別的,這當然沒有問題,但是……

我不知道大家遇到過這樣的情況沒有,就是說你希望你每次輸出的 向量或矩陣是變長的,就好比說每次在 scan 中計算一個 m_{t},這個 m_{t}每次迭代時都會向下添加一維。這個時候坑爹的設定就來了,我發現scan中對返回值的要求是要固定維數!這意味著我必須在初始化的時候就直接開好一個大矩陣,這個矩陣除了第一行其他行都padding 為0,然後每次迭代的時候 set_subtentor 重新構造一個與這個大矩陣同維度的新矩陣然後返回! theano 學函數式學啥不好偏偏這時候非要 immutable, 導致了循環中大量的資源佔用,而且為實現添加了不必要的麻煩(我覺得)。

c. immutable 機制導致 function compile 時候的時間過長

這裡提一下上述說的 immutable. 在 theano 中,由於你定義的表達式要形成一個 graph 來為後面的自動求導做準備,因此定義的變數很多情況下是不能修改的,比如你定義一個矩陣M。然後在某個操作中你希望更新這個矩陣中的某一維,你發現你不能直接使用諸如 M[2, :] = .. 的形式, 而是使用 theano 官方提供的 set_subtensor 還有一個相應的姊妹函數來 new 一個新的矩陣來滿足要求,這不是問題,可以理解。但是當把set_subtensor 放入 scan 的時候編譯時間不要太長好嗎!

這個缺陷我搜索過相關郵件列表,有人遇到過相同的瓶頸,除了想辦法繞過去並沒有太好的解決方案。

2. theano 定義 function 時缺乏靈活的多態機制。

我不知道其他人有沒有這樣的需求。比方說你需要對同一個數據集實現多個模型做對比實驗,你實現兩個模型:LSTM, LSTM-peephole. 這兩個模型你會發現很多表達式與變數定義可以通用。這時候你當然可以搞父類子類來寫有擴展性的代碼,恩恩,大丈夫。然後當最後你寫 theano function 時發現傻逼了。只要 inputs 參數有一點不一樣,你就需要寫一個新的 function. 如果你想實現10個LSTM的變種,你就需要寫10個對應的function. 然後用 if else 來控制哪個模型與哪個function 相對應,坑爹呢!有一個相應的解決辦法是搞一個input variable 的並集,然後在統一定義一個 function, 在其中加入 on_unused_input 來標記自動忽略未使用的參數。但是這在參數定義的時候就需要在不同的模型中加入冗餘的變數來保證一致性。我不知道有沒有更好的方法來解決這個問題。

3. 困難的調試方法

由於 theano 的時候是嚴格遵循三步走戰略,即:a.表達式定義 b. 函數編譯 c. 主程序調用theano編譯好的函數來獲得結果。 這就導致的傳統的測試方法到了 theano 這裡變得比較困難。想知道自己的模型表達式定義的對不對?對不起等函數先編譯好了再說。然後編譯函數需要一個多小時。你跑起了程序,然後趁著函數編譯的時候打打艦娘,等打了1小時終於撈到了Roma回頭看程序跑的情況,我草word embedding 的維度變了但是輸入層大小忘調了GG!由於theano 在表達式定義的時候是不會幫助你去檢查你的矩陣相乘、dimshuffle 等操作的時候維度是否對應,你要麼等著編譯好後跑實際數據看出不出錯,要麼嘗試把中間步驟拆開一步一步構造測試數據排查錯誤,這其中的工作量可想而知。在這裡我也向諸位知友請教一下 theano的調試最佳實踐,我暫沒有找到更好的方法。

以上就是我在使用 theano 的時候遇到的一些困惑,希望能與大家交流,將問題一併解決,讓實驗更加順利(


利益相關:基本上只用Theano。跟Theano的最早的lead developers之一比較熟。

速度上:

Theano的compile是慢的。這取決於computation graph的結構。

Running速度是可以的(相對而言只能說OK,soumith/convnet-benchmarks · GitHub)。

Parallel以及data loading和是蛋疼的。其中Cpython中的global interpreter lock居功至偉。

關於好用不好用:

先說缺點,debug是困難的。往往需要推測才知道具體是哪裡出了問題。

如果說是做標準的結構,有keras,lasagne,blocks,pylearn2等等庫的支持,實現起來非常容易。

如果說是方便灌水了。那torch,caffe或者whatever toolbox不都是為大家提供灌水的機會?簡直不要太「用我灌水我自豪啊」

讓試一下convnet的人知道convlayer的backprop的細節

簡直就是

讓敲回車的人知道回字的四種寫法

如果說是做非標準的結構,需要把forward graph滿天飛連來連去。

那Theano不要方便太多好不好!

那Theano不要方便太多好不好!

那Theano不要方便太多好不好!

如果需要和別的領域的code結合起來

那Python不要方便太多好不好!

那Python不要方便太多好不好!

那Python不要方便太多好不好!

Theano的替代品Computation Graph Toolkit

網站上說是解決了許多theano內在的問題。不過還不是很成熟。個人還沒有用過。

如何看待之前的答案:

關於@石佳欣的答案:deepmind某人的那句話,不condition在當時的context裡面解讀方式不要太多好不好?

We don"t like people who use theano. We like those who do things on their own.

什麼是like,是喜歡hire(這還要分什麼職位)?還是欣賞?喜歡讀他們的paper?喜歡跟他們合作?這個like不like是不是限定在某個特定領域?

什麼是use theano,是只要用theano就不喜歡?還是說某人用theano就代表他不懂行的概率比較大?那如果我又用theano,又contribute又這麼說?

不說montreal有多少人去了deepmind。另外一位靠theano贏了幾次kaggle比賽的大牛About me – Sander Dieleman也去了deepmind。

他有沒有可能是對著一個用theano的同事開玩笑呢?

除去context,拿一句話出來過分解讀,是沒有意義的。explaining away懂得伐。

PS: @鄧博元的答案中對於SymPy和Theano的關係表述有些含混,容易造成誤導。

SymPy做的事symbolic differentiation,而Theano做的automatic differentiation。是有本質的區別的。詳情請見wikipedia Automatic differentiation,或者自行搜索。

先這麼多,想起來再補充。


轉載 嫣然晴歡的博客

因為看這個問題的知友可能想安裝theano,除了下面這個安裝方式其餘都是錯的,我折騰了兩天,python卸了裝,裝了卸好幾次,僅僅在這個下面安裝成功

要做卷積神經網路的一些東西,所以要裝theano,網上很多Theano安裝教程版本較老,而各安裝包更新很快,參考價值有限。走了很多彎路才裝好,把這個過程記錄下來,希望對大家有幫助~ ~

我的配置:win7,32位(64和32位安裝步驟沒差,下安裝包版本有差而已),vs2012

首先推薦一篇英文安裝指南,寫的十分詳細,很多安裝指南都是參考的這篇。不過因為這篇里存在著一些冗餘成分,個人酌情參考,不過遇到難題時可以看看:Installing Theano

0.操作系統

ubuntu下安裝會比windows下省事很多,但是好像是直接裝進系統里的,python出問題會崩系統(忘了從哪裡看的了),可以考慮pip個虛擬環境。我平時的工作環境是windows,並不好裝,但是用起來方便一點(個人感覺)。

1.安裝anaconda(已內置python,numpy和scipy兩個必要庫以及一些其他庫,自帶安裝。)

地址:http://www.continuum.io/downloads

選擇原因:安裝簡單,網上參考資料多。

也有人會選pythonxy,提醒一下,網上pythonxy資源不多,我裝完pythonxy, import theano之後出現了這個問題ImportError: not import name gof,百度谷歌上能試的解決方式我都試了,然並卵。

也有可能沒有內置numpy等等,請按照如下方式安裝:

Anaconda的一些命令(在Anaconda的命令行窗口輸入):

conda list #該命令,將列出Anaconda安裝的所有應用包,我們可以看到Anaconda已經安裝了numpy, nose, pip, python, scipy, mingw等等。

conda install &

#該命令用於安裝應用包,如 conda install numpy.

pip install &

#該命令用於安裝應用包,如 pip install theano.

conda update &

#升級應用包,如 conda update python

2.安裝mingw

裝完anaconda直接pip install theano是行不通的,在python里搜g++會發現搜不到,有些參考資料裡面寫:

添加環境變數: path: C:AnacondaMinGWin;C:AnacondaMinGWx86_64-w64-mingw32lib;

新建環境變數:PYTHONPATH: C:AnacondaLibsite-packages heano;

問題在於anaconda底下根本沒有MinGW包,不要聽信什麼自己下個zip,安裝到anaconda底下,正確方法:cmd輸入:conda install mingw libpython

MinGW等文件夾會自動裝到anaconda下面,life is short, save your time.

3.環境配置

在用戶變數中,PATH添加C:Anaconda;C:AnacondaScripts;

並新建 PYTHONPATH:C:AnacondaLibsite-packages heano;

在cmd的home目錄中新建 .theanorc.txt 文件(注意名字中的「.」),根據自己安裝MinGW的路徑寫上MinGW的路徑,我的如下:

[blas]

ldflags=

[gcc]

cxxflags = -IC:AnacondaMinGW

重啟電腦

4.安裝theano

別用什麼theano.zip解壓到目錄底下或者theano_installer_latest.msi,不嫌麻煩你就去試,正確方式:cmd輸入:pip install theano

(pip用法看這裡:pip 安裝使用詳解)

裝完之後在ipython中輸入以下兩行代碼測試一下:

import theano

theano.test()

沒有error的話,恭喜你,安裝成功了~ ~

5.GPU加速

GPU加速首先就是安裝CUDA,然而CUDA只支持NVIDIA顯卡,因為CUDA軟體就是他家出的,如果你的本並不是NVIDIA顯卡,別費勁了

6.BLAS

看看numpy是不是已經默認BLAS加速了,在python里輸入:

import numpy

id(numpy.dot) == id(numpy.core.multiarray.dot)

結果為False表示已經成功依賴了BLAS加速,如果是Ture則表示用的是python自己的實現,並沒有加速。

參考(然而他們的完全有用的話,我就沒必要寫這些了~ ~):

下面這些都是胡扯

win 8.1 64bit 深度學習theano 安裝設置

http://blog.163.com/yuyang_tech/blog/static/216050083201469101518900/

Theano學習筆記:Theano的艱辛安裝體驗

Python錯誤集錦


說的簡單點,寫代碼容易,debug難,如果對演算法的實現細節不是太感興趣單純用它跑數據,推薦lasagne,介面更簡單明了,我個人也是從theano開始接觸deeplearning,如果能把deep learning tutorial研究明白,也算入門了,如果對實現deeplearning的演算法感興趣,推薦stanford的兩門課,cs231n和cs224d,當然,想讓你的代碼跑得更快,毫無疑問需要c或者c++,數據量大的情況下純python基本不實用,不過theano的實現也是不錯的,我曾經把自己實現的一個stack autoencoder(向量化實現,無for循環)和theano比較了一下,最後theano快了1.5到2倍,準確度相差無幾,99%多一些,希望回答能對樓主有益。


最近正在為theano摳大腦,感覺它更像是一個代數符號驗算系統,寫起來有點寫FPGA的感覺。它本身並沒有說自己跟神精網路有什麼關係,theano這個庫對自己的定義是這樣的:

Theano is a Python library that allows you to define, optimize, and
evaluate mathematical expressions involving multi-dimensional
arrays efficiently.

翻譯成漢語應該是:

Theano是一個Python庫,專門用於定義、優化、求值數學表達式,效率高,適用於多維數組。

因為是一個代數符號系統,所以數學表達式裡面的一個符號(symbol,Theano也管這個叫variable)是一個Variable對象,對象之間用加減乘除等操作符連接起來,就變成了一個圖(Theano管這個叫graph)。在建模一個神經網路的時候將網路表示成為一個巨大的公式(graph)。此舉給神精網路的建模提供了not any more的靈活性,你用C++寫無非也就如此嘛,就是前排答主說得需求拆分非常到位,所以不僅是神經網路,市面上大部分參數化模型都可以用Theano實現,非參模型用theano的話不知道應該是什麼思路(決策樹、GBDT、RF)。

比如最簡單的z = x + y這個表達式,你需要使用theano.tensor.*裡面提供的對象,組合出這樣一個圖:

圖片來源:Graph Structures

上圖綠色的代表操作符類的對象,紅色的是變數類的對象,紫色的是類型類的對象。一個神經網路也是這樣構建出來的,因為是從符號的粒度去構建一個神經網路,所以你可以手工攢出你想要的任意形狀的神經網路。

因為是一個代數符號系統,一個graph可以充分地表達一個表達式,這樣就能夠對表達式進行自動求導,這方面理論和實踐都已經很成熟了:Introduction to Automatic Differentiation

因為是一個代數符號系統,而且相當於在命令語言(Python)里造了一個符號語言(類似PFGA),用命令語言去做符號操作,操作起來可想而知是非常蹩腳的。那個scan的tutorial那幾個例子看了好半天都看不明白,看完scan的spec感覺真是日了狗了。。。我從沒見過一個Python庫的API參數設計得這麼擰巴。。。

來,給大家開開眼

scan的tutorial:Loop — Theano 0.7 documentation

scan的spec:http://deeplearning.net/software/theano/library/scan.html

啊,還有就是,Theano安裝起來實在是太令人傷心了。。。


今年蹭acl在poster遇到deepmind的人,遂厚著臉皮上前搭訕,到今天聊了什麼已經記不太清了,但有一句話印象深刻:We don"t like people who use theano. We like those who do things on their own.

theano最早提出自動求導這個feature很有insight,也確實方便了研究者們(尤其是Montreal眾),使他們能夠減少花在推導數和實現演算法上的精力。然而壞處是:也給很多連back propagation細節都沒搞清楚的人創造了用神經網路灌水的機會。


(歪個題……)

如果是在Windows+Anaconda環境下配置Theano (+Cuda),建議參考這篇文章 windows10下theano啟用gpu:CUDA + Anaconda


各種坑


keras的到來讓暮年的theano又春天了一把


還沒裝成功,這麼難配置的python庫我真的是有一句。。。

要不是要keras,我倒騰這個幹嘛

初學者,windows環境,勿噴


推薦閱讀:

能否使用區塊鏈的算力來解決深度學習訓練?
目前,人工智慧語音在說中文時的語氣感覺上還比較機械,怎樣使人工智慧語音的語氣更自然一些?
theano中怎麼查看TensorVariable的值,在debug時如何跟蹤這樣的變數?
是不是對於任意 n×n 大小的圍棋棋盤,人類都贏不了 AlphaGo Zero 了?

TAG:機器學習 | 深度學習DeepLearning | Theano |