0
雷鋒網(wǎng) AI 評論按:關(guān)于深度學(xué)習(xí)的框架之爭一直沒有停止過。PyTorch,TensorFlow,Caffe還是Keras ?近日, 斯坦福大學(xué)計算機科學(xué)博士生Awni Hannun就發(fā)表了一篇文章,對比當(dāng)前兩個主流框架PyTorch和TensorFlow。
雷鋒網(wǎng) AI 科技評論編譯如下:
這篇指南是我目前發(fā)現(xiàn)的PyTorch和TensorFlow之間的主要差異。寫這篇文章的目的是想幫助那些想要開始新項目或者轉(zhuǎn)換深度學(xué)習(xí)框架的人進行選擇。文中重點考慮訓(xùn)練和部署深度學(xué)習(xí)堆棧組件時框架的可編程性和靈活性。我不會權(quán)衡速度、內(nèi)存使用情況等性能。
結(jié)論
PyTorch更適合于在研究中快速進行原型設(shè)計、業(yè)余愛好者和小型項目,TensorFlow則更適合大規(guī)模的調(diào)度,尤其當(dāng)考慮到跨平臺和嵌入式調(diào)度操作時。
準備時間
優(yōu)勝者: PyTorch
PyTorch實際上是NumPy的替代,它支持GPU,有著更高級的功能,可以用來構(gòu)建和訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)。
如果你熟悉NumPy、Python和常見的深度學(xué)習(xí)概念(卷積層、遞歸層、SGD等),那么學(xué)習(xí)Python對你來說會很容易。
而TensorFlow則可以看成是一種嵌入Python的編程語言。當(dāng)你在編寫TensorFlow代碼時,它們會通過Python編譯成一張圖,然后由TensorFlow執(zhí)行引擎運行。我看到過剛使用TensorFlow的人因為這個額外的間接層而苦思冥想。也因為如此,想用TensorFlow還需要學(xué)一些額外的概念,比如會話、圖、變量作用域和占位符等。要運行基本模型,還需要更多的樣板代碼。使用TensorFlow的前期準備時間肯定比PyTorch要長。
圖創(chuàng)建和調(diào)試
優(yōu)勝者: PyTorch
創(chuàng)建和運行計算圖可能是這兩個框架最大的不同。在PyTorch中,圖架構(gòu)是動態(tài)的,這意味著圖是在運行時創(chuàng)建的。而在TensorFlow中,圖架構(gòu)是靜態(tài)的,這意味著先編譯出圖然后再運行。
下面是一個簡單的例子,在PyTorch中可以使用標(biāo)準的Python語言編寫for循環(huán)結(jié)構(gòu)
for _ in range(T):
h = torch.matmul(W, h) + b
你可以在這段代碼的執(zhí)行過程中改變T的值。而在TensorFlow中,需要使用控制流運算(control flow operation)來創(chuàng)建圖,例如tf.while_loop。對于更常見的結(jié)構(gòu),TensorFlow可以執(zhí)行dynamic_rnn語句,但是創(chuàng)建自定義的動態(tài)計算更加困難。
PyTorch中簡單的圖架構(gòu)更容易推導(dǎo),或許更重要的一點是,它更容易調(diào)試。調(diào)試PyTorch代碼如同調(diào)試Python代碼,可以使用pdb并在任何地方設(shè)置斷點。而調(diào)試TensorFlow代碼并不那么容易,你有兩個選擇,一是請求會話中你想要檢查的變量,二是學(xué)習(xí)和使用TensorFlow調(diào)試器(tfdbg)。
覆蓋率
優(yōu)勝者: TensorFlow
因為PyTorch在逐漸發(fā)展,我認為兩者之間的差距會縮小到零。然而,目前仍有一些TensorFlow支持但PyTorch不支持的功能,如下所示:
沿著維度翻轉(zhuǎn)張量 (np.flip, np.flipud, np.fliplr)
檢查張量是空值還是無限值(np.is_nan, np.is_inf)
快速傅里葉變換(np.fft)
此外,TensorFlow的contrib包中有更多比PyTorch更高級的函數(shù)和模型。
序列化
優(yōu)勝者: TensorFlow
在這兩種框架下保存和加載模型都很簡單。PyTorch有一個特別簡單的API,既可以保存模型的所有權(quán)重,也可以pickle全部類。
TensorFlow的Saver對象也很容易使用,并為檢查點(check-pointing)提供了更多選擇。
在序列化中TensorFlow的主要優(yōu)點是可以將整個圖保存為協(xié)議緩沖區(qū)。這包括參數(shù)和運算。此外,該圖可以通過其他支持的語言(C++,Java)加載。這對不支持Python的調(diào)度棧來說至關(guān)重要。理論上,在改變模型源代碼之后,你想要運行舊模型時它也能有所幫助。
部署
優(yōu)勝者: TensorFlow
對于小規(guī)模的服務(wù)器端部署,兩個框架都很容易封裝在諸如Flask web服務(wù)器中。
不過,TensorFlow支持移動和嵌入式部署??梢源_定的說,這比包括PyTorch在內(nèi)的大多數(shù)深度學(xué)習(xí)框架支持功能的都要多。將TensorFlow部署到Android或iOS上確實需要大量的工作,但至少你不必用Java或C++重寫模型的整個推理程序。
此外,TensorFlow Serving支持高性能的服務(wù)器端部署。我沒有使用過TensorFlow Serving,因此不能很確信地寫出它的利弊。由于機器學(xué)習(xí)服務(wù)使用的頻率很高,我猜想這是人們堅持使用TensorFlow的充分理由。除了性能之外,TensorFlow Serving的一個明顯特點是,支持輕松地換用模型而不會降低服務(wù)性能。
文檔
平手
我在兩種框架的文檔中都找到了我需要的東西。Python的 API在兩個框架中都有良好的文檔記錄,并且有足夠的例子和教程來學(xué)習(xí)這兩種框架。
一個比較邊緣的問題是,PyTorch的 C語言庫大多是無文檔記錄的,不過這只影響到編寫定制的C語言擴展程序,而且這種操作是否有助于軟件還存疑。
數(shù)據(jù)加載
優(yōu)勝者: PyTorch
PyTorch中用于數(shù)據(jù)加載的API設(shè)計得很好。接口在數(shù)據(jù)集、采樣器和數(shù)據(jù)加載器中有明確規(guī)定。數(shù)據(jù)加載器接收數(shù)據(jù)集和采樣器,根據(jù)采樣器的調(diào)度,在數(shù)據(jù)集上生成迭代器。加載并行數(shù)據(jù)就像把num_workers語句傳遞到數(shù)據(jù)加載器一樣簡單。
我在TensorFlow還沒發(fā)現(xiàn)特別有用的加載數(shù)據(jù)的工具,例如readers, queues, queue runners等,都不夠好。部分原因是因為將想要運行的所有預(yù)處理代碼添加到TensorFlow圖中并不總是直接的,例如計算時頻譜(spectrogram)。
而且,API本身更繁瑣,更難以學(xué)習(xí)。
設(shè)備管理
優(yōu)勝者: TensorFlow
TensorFlow管理設(shè)備時的無縫性非常好。通常不需要規(guī)定任何東西,因為默認已經(jīng)設(shè)好了。例如,如果GPU可用,TensorFlow將默認在GPU上運行。在PyTorch中,即使支持CUDA,都必須明確地將所有東西移到設(shè)備上。
TensorFlow設(shè)備管理的唯一缺點是,即使你只使用一個GPU它也會默認占用所有GPU的顯存。簡單的解決方法是用CUDA_VISIBLE_DEVICES語句指定顯卡。但有時會忘了設(shè)置,所以當(dāng)GPU實際上處于空閑狀態(tài)時,會顯示內(nèi)存不足。
在PyTorch中,代碼需要更頻繁地檢查CUDA的可用性和更明確的設(shè)備管理,當(dāng)編寫能夠同時在CPU和GPU上運行的代碼時尤甚。另外,將GPU上的PyTorch Variable轉(zhuǎn)換為NumPy數(shù)組有點繁瑣。
numpy_var = variable.cpu().data.numpy()
自定義擴展
優(yōu)勝者: PyTorch
在這兩種框架中都可以用C語言、C++或CUDA構(gòu)建或綁定自定義擴展。但TensorFlow需要更多的樣板代碼,即使它支持多種類型和設(shè)備。在PyTorch中,只需為每個CPU和GPU版本編寫一個接口和相應(yīng)的實現(xiàn)。用這兩種框架來編譯擴展都很直接,并且不需要下載除了pip安裝包之外的任何頭文件或源代碼。
擴展
關(guān)于TensorBoard
TensorBoard是用于展示訓(xùn)練機器學(xué)習(xí)模型過程的可視化工具。它是TensorFlow自帶的最有用的功能之一。只需要通過訓(xùn)練腳本中的一些代碼片段,就可以查看任何模型的訓(xùn)練曲線和驗證結(jié)果。TensorBoard作為web服務(wù)運行,它可以非常方便地將存儲在無頭節(jié)點(headless node)上的結(jié)果可視化。
我在用PyTorch之前一直在用這種功能并嘗試找到能替代這種功能的選擇。值得慶幸的是,目前至少有兩個開源項目支持這種功能。一個是istensorboard_logger,另一個是crayon。istensorboard_logger庫甚至比TensorFlow中的TensorBoard摘要數(shù)據(jù)更容易使用,不過需要安裝TensorBoard來使用。crayon完全能取代TensorBoard,不過需要更多的設(shè)置(支持docker是先決條件)。
關(guān)于Keras
Keras是一個更高級的API,可配置后端,支持TensorFlow、Theano和CNTK,也許在不久的將來也會支持PyTorch。Keras就像TensorFlow里的tf.contrib庫一樣。
我上面沒有討論Keras,不過它使用起來特別容易。它是調(diào)試最常用的幾種深度神經(jīng)網(wǎng)絡(luò)架構(gòu)最快的方法之一。不過它的靈活性不如PyTorch或core TensorFlow。
關(guān)于TensorFlow Fold
谷歌在2017年2月發(fā)布了TensorFlow Fold。該庫構(gòu)建在TensorFlow之上,支持更多動態(tài)圖構(gòu)建,主要優(yōu)點是動態(tài)批處理功能——可以對不同規(guī)模的輸入數(shù)據(jù)(如解析樹上的遞歸網(wǎng)絡(luò))自動進行批量計算。在可編程性上,它的語法不如PyTorch直接,不過在某些情況下,批量處理帶來的性能改進可以讓我們忽略語法上的不足。
via:kdnuggets
雷鋒網(wǎng) AI科技評論
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。