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