1. 程式人生 > >Tensorflow 與Caffe(轉)

Tensorflow 與Caffe(轉)

tps 良好的 輸出 控制 get 開發人員 生命 network 完全

TensorFlow

TensorFlow 是相對高階的機器學習庫,用戶可以方便地用它設計神經網絡結構,而不必為了追求高效率的實現親自寫 C++或 CUDA 代碼。它和 Theano 一樣都支持自動求導,用戶不需要再通過反向傳播求解梯度。其核心代碼和 Caffe 一樣是用 C++編寫的,使用 C++簡化了線上部署的復雜度,並讓手機這種內存和CPU資源都緊張的設備可以運行復雜模型(Python 則會比較消耗資源,並且執行效率不高)。除了核心代碼的 C++接口,TensorFlow 還有官方的 Python、Go 和 Java 接口,是通過 SWIG(Simplified Wrapper and Interface Generator)實現的,這樣用戶就可以在一個硬件配置較好的機器中用 Python進行實驗,並在資源比較緊張的嵌入式環境或需要低延遲的環境中用 C++部署模型。SWIG 支持給 C/C++代碼提供各種語言的接口,因此其他腳本語言的接口未來也可以通過 SWIG 方便地添加。不過使用 Python 時有一個影響效率的問題是,每一個 mini-batch 要從 Python 中 feed 到網絡中,這個過程在 mini-batch 的數據量很小或者運算時間很短時,可能會帶來影響比較大的延遲。現在 TensorFlow 還有非官方的 Julia、Node.js、R 的接口支持,地址如下。

Julia: http://github.com/malmaud/TensorFlow.jl

Node.js: http://github.com/node-tensorflow/node-tensorflow

R: http://github.com/rstudio/tensorflow

TensorFlow 也有內置的 TF.Learn 和 TF.Slim 等上層組件可以幫助快速地設計新網絡,並且兼容 Scikit-learn estimator 接口,可以方便地實現 evaluate、grid search、cross validation 等功能。同時 TensorFlow 不只局限於神經網絡,其數據流式圖支持非常自由的算法表達,當然也可以輕松實現深度學習以外的機器學習算法。事實上,只要可以將計算表示成計算圖的形式,就可以使用 TensorFlow 。用戶可以寫內層循環代碼控制計算圖分支的計算,TensorFlow 會自動將相關的分支轉為子圖並執行叠代運算。TensorFlow 也可以將計算圖中的各個節點分配到不同的設備執行,充分利用硬件資源。定義新的節點只需要寫一個 Python 函數,如果沒有對應的底層運算核,那麽可能需要寫 C++或者 CUDA 代碼實現運算操作。

在數據並行模式上,TensorFlow 和 Parameter Server 很像,但 TensorFlow 有獨立的 Variable node,不像其他框架有一個全局統一的參數服務器,因此參數同步更自由。TensorFlow 和 Spark 的核心都是一個數據計算的流式圖,Spark 面向的是大規模的數據,支持 SQL 等操作,而 TensorFlow 主要面向內存足以裝載模型參數的環境,這樣可以最大化計算效率。

TensorFlow 的另外一個重要特點是它靈活的移植性,可以將同一份代碼幾乎不經過修改就輕松地部署到有任意數量 CPU 或 GPU 的 PC、服務器或者移動設備上。相比於 Theano,TensorFlow 還有一個優勢就是它極快的編譯速度,在定義新網絡結構時,Theano 通常需要長時間的編譯,因此嘗試新模型需要比較大的代價,而 TensorFlow 完全沒有這個問題。TensorFlow 還有功能強大的可視化組件 TensorBoard,能可視化網絡結構和訓練過程,對於觀察復雜的網絡結構和監控長時間、大規模的訓練很有幫助。TensorFlow 針對生產環境高度優化,它產品級的高質量代碼和設計都可以保證在生產環境中穩定運行,同時一旦 TensorFlow 廣泛地被工業界使用,將產生良性循環,成為深度學習領域的事實標準。

除了支持常見的網絡結構(卷積神經網絡(Convolutional Neural Network,CNN)、循環神經網絡(Recurent Neural Network,RNN))外,TensorFlow 還支持深度強化學習乃至其他計算密集的科學計算(如偏微分方程求解等)。TensorFlow 此前不支持 symbolic loop,需要使用 Python 循環而無法進行圖編譯優化,但最近新加入的 XLA 已經開始支持 JIT 和 AOT,另外它使用 bucketing trick 也可以比較高效地實現循環神經網絡。TensorFlow 的一個薄弱地方可能在於計算圖必須構建為靜態圖,這讓很多計算變得難以實現,尤其是序列預測中經常使用的 beam search。

TensorFlow 的用戶能夠將訓練好的模型方便地部署到多種硬件、操作系統平臺上,支持 Intel 和 AMD 的 CPU,通過 CUDA 支持 NVIDIA 的 GPU (最近也開始通過 OpenCL 支持 AMD 的 GPU,但沒有 CUDA 成熟),支持 Linux 和 Mac,最近在 0.12 版本中也開始嘗試支持 Windows。在工業生產環境中,硬件設備有些是最新款的,有些是用了幾年的老機型,來源可能比較復雜,TensorFlow 的異構性讓它能夠全面地支持各種硬件和操作系統。同時,其在 CPU 上的矩陣運算庫使用了 Eigen 而不是 BLAS 庫,能夠基於 ARM 架構編譯和優化,因此在移動設備(Android 和 iOS)上表現得很好。

TensorFlow 在最開始發布時只支持單機,而且只支持 CUDA 6.5 和 cuDNN v2,並且沒有官方和其他深度學習框架的對比結果。在 2015 年年底,許多其他框架做了各種性能對比評測,每次 TensorFlow 都會作為較差的對照組出現。那個時期的 TensorFlow 真的不快,性能上僅和普遍認為很慢的 Theano 比肩,在各個框架中可以算是墊底。但是憑借 Google 強大的開發實力,很快支持了新版的 cuDNN (目前支持cuDNN v5.1),在單 GPU 上的性能追上了其他框架。表 2-3 所示為 https://github.com/soumith/convnet-benchmarks 給出的各個框架在 AlexNet 上單 GPU 的性能評測。

技術分享圖片

表2-3 各深度學習框架在 AlexNet 上的性能對比

目前在單 GPU 的條件下,絕大多數深度學習框架都依賴於 cuDNN,因此只要硬件計算能力或者內存分配差異不大,最終訓練速度不會相差太大。但是對於大規模深度學習來說,巨大的數據量使得單機很難在有限的時間完成訓練。這時需要分布式計算使 GPU 集群乃至 TPU 集群並行計算,共同訓練出一個模型,所以框架的分布式性能是至關重要的。TensorFlow 在 2016 年 4 月開源了分布式版本,使用 16 塊 GPU 可達單 GPU 的 15 倍提速,在 50 塊 GPU 時可達到 40 倍提速,分布式的效率很高。目前原生支持的分布式深度學習框架不多,只有 TensorFlow、CNTK、DeepLearning4J、MXNet 等。不過目前 TensorFlow 的設計對不同設備間的通信優化得不是很好,其單機的 reduction 只能用 CPU 處理,分布式的通信使用基於 socket 的 RPC,而不是速度更快的 RDMA,所以其分布式性能可能還沒有達到最優。

Google 在 2016 年 2 月開源了 TensorFlow Serving,這個組件可以將 TensorFlow 訓練好的模型導出,並部署成可以對外提供預測服務的 RESTful 接口,如圖 2-2 所示。有了這個組件,TensorFlow 就可以實現應用機器學習的全流程:從訓練模型、調試參數,到打包模型,最後部署服務,名副其實是一個從研究到生產整條流水線都齊備的框架。這裏引用 TensorFlow 內部開發人員的描述:“ TensorFlow Serving 是一個為生產環境而設計的高性能的機器學習服務系統。它可以同時運行多個大規模深度學習模型,支持模型生命周期管理、算法實驗,並可以高效地利用 GPU 資源,讓 TensorFlow 訓練好的模型更快捷方便地投入到實際生產環境”。除了 TensorFlow 以外的其他框架都缺少為生產環境部署的考慮,而 Google 作為廣泛在實際產品中應用深度學習的巨頭可能也意識到了這個機會,因此開發了這個部署服務的平臺。TensorFlow Serving 可以說是一副王牌,將會幫 TensorFlow 成為行業標準做出巨大貢獻。

技術分享圖片

圖2-2 TensorFlow Serving 架構

TensorBoard 是 TensorFlow 的一組 Web 應用,用來監控 TensorFlow 運行過程,或可視化 Computation Graph。TensorBoard 目前支持五種可視化:標量(scalars)、圖片(images)、音頻(audio)、直方圖(histograms)和計算圖(Computation Graph)。TensorBoard 的 Events Dashboard 可以用來持續地監控運行時的關鍵指標,比如 loss、學習速率(learning rate)或是驗證集上的準確率(accuracy);Image Dashboard 則可以展示訓練過程中用戶設定保存的圖片,比如某個訓練中間結果用 Matplotlib 等繪制(plot)出來的圖片;Graph Explorer 則可以完全展示一個 TensorFlow 的計算圖,並且支持縮放拖曳和查看節點屬性。TensorBoard 的可視化效果如圖 2-3 和圖 2-4 所示。

技術分享圖片

圖2-3 TensorBoard 的 loss 標量的可視化

技術分享圖片

圖2-4 TensorBoard 的模型結構可視化

TensorFlow 擁有產品級的高質量代碼,有 Google 強大的開發、維護能力的加持,整體架構設計也非常優秀。相比於同樣基於 Python 的老牌對手 Theano,TensorFlow 更成熟、更完善,同時 Theano 的很多主要開發者都去了 Google 開發 TensorFlow(例如書籍 Deep Learning 的作者 Ian Goodfellow,他後來去了 OpenAI)。Google 作為巨頭公司有比高校或者個人開發者多得多的資源投入到 TensorFlow 的研發,可以預見,TensorFlow 未來的發展將會是飛速的,可能會把大學或者個人維護的深度學習框架遠遠甩在身後。

Caffe

官方網址:http://caffe.berkeleyvision.org/

GitHub:http://github.com/BVLC/caffe

Caffe 全稱為 Convolutional Architecture for Fast Feature Embedding,是一個被廣泛使用的開源深度學習框架(在 TensorFlow 出現之前一直是深度學習領域 GitHub star 最多的項目),目前由伯克利視覺學中心(Berkeley Vision and Learning Center,BVLC)進行維護。Caffe 的創始人是加州大學伯克利的 Ph.D.賈揚清,他同時也是TensorFlow的作者之一,曾工作於 MSRA、NEC 和 Google Brain,目前就職於 Facebook FAIR 實驗室。Caffe 的主要優勢包括如下幾點。

  • 容易上手,網絡結構都是以配置文件形式定義,不需要用代碼設計網絡。

  • 訓練速度快,能夠訓練 state-of-the-art 的模型與大規模的數據。

  • 組件模塊化,可以方便地拓展到新的模型和學習任務上。

Caffe 的核心概念是 Layer,每一個神經網絡的模塊都是一個 Layer。Layer 接收輸入數據,同時經過內部計算產生輸出數據。設計網絡結構時,只需要把各個 Layer 拼接在一起構成完整的網絡(通過寫 protobuf 配置文件定義)。比如卷積的 Layer,它的輸入就是圖片的全部像素點,內部進行的操作是各種像素值與 Layer 參數的 convolution 操作,最後輸出的是所有卷積核 filter 的結果。每一個 Layer 需要定義兩種運算,一種是正向(forward)的運算,即從輸入數據計算輸出結果,也就是模型的預測過程;另一種是反向(backward)的運算,從輸出端的 gradient 求解相對於輸入的 gradient,即反向傳播算法,這部分也就是模型的訓練過程。實現新 Layer 時,需要將正向和反向兩種計算過程的函數都實現,這部分計算需要用戶自己寫 C++或者 CUDA (當需要運行在 GPU 時)代碼,對普通用戶來說還是非常難上手的。正如它的名字 Convolutional Architecture for Fast Feature Embedding 所描述的,Caffe 最開始設計時的目標只針對於圖像,沒有考慮文本、語音或者時間序列的數據,因此 Caffe 對卷積神經網絡的支持非常好,但對時間序列 RNN、LSTM 等支持得不是特別充分。同時,基於 Layer 的模式也對 RNN 不是非常友好,定義 RNN 結構時比較麻煩。在模型結構非常復雜時,可能需要寫非常冗長的配置文件才能設計好網絡,而且閱讀時也比較費力。

Caffe 的一大優勢是擁有大量的訓練好的經典模型(AlexNet、VGG、Inception)乃至其他 state-of-the-art (ResNet等)的模型,收藏在它的 Model Zoo (http://github.com/BVLC/ caffe/wiki/Model-Zoo)。因為知名度較高,Caffe 被廣泛地應用於前沿的工業界和學術界,許多提供源碼的深度學習的論文都是使用 Caffe 來實現其模型的。在計算機視覺領域 Caffe 應用尤其多,可以用來做人臉識別、圖片分類、位置檢測、目標追蹤等。雖然 Caffe 主要是面向學術圈和研究者的,但它的程序運行非常穩定,代碼質量比較高,所以也很適合對穩定性要求嚴格的生產環境,可以算是第一個主流的工業級深度學習框架。因為 Caffe 的底層是基於 C++的,因此可以在各種硬件環境編譯並具有良好的移植性,支持 Linux、Mac 和 Windows 系統,也可以編譯部署到移動設備系統如 Android 和 iOS 上。和其他主流深度學習庫類似,Caffe 也提供了 Python 語言接口 pycaffe,在接觸新任務,設計新網絡時可以使用其 Python 接口簡化操作。不過,通常用戶還是使用 Protobuf 配置文件定義神經網絡結構,再使用 command line 進行訓練或者預測。Caffe 的配置文件是一個 JSON 類型的 .prototxt 文件,其中使用許多順序連接的 Layer 來描述神經網絡結構。Caffe 的二進制可執行程序會提取這些 .prototxt 文件並按其定義來訓練神經網絡。理論上,Caffe 的用戶可以完全不寫代碼,只是定義網絡結構就可以完成模型訓練了。Caffe 完成訓練之後,用戶可以把模型文件打包制作成簡單易用的接口,比如可以封裝成 Python 或 MATLAB 的 API 。不過在 .prototxt 文件內部設計網絡節構可能會比較受限,沒有像 TensorFlow 或者 Keras 那樣在 Python 中設計網絡結構方便、自由。更重要的是,Caffe 的配置文件不能用編程的方式調整超參數,也沒有提供像 Scikit-learn 那樣好用的 estimator 可以方便地進行交叉驗證、超參數的 Grid Search 等操作。Caffe 在 GPU 上訓練的性能很好(使用單塊 GTX 1080 訓練 AlexNet 時一天可以訓練上百萬張圖片),但是目前僅支持單機多 GPU 的訓練,沒有原生支持分布式的訓練。慶幸的是,現在有很多第三方的支持,比如雅虎開源的 CaffeOnSpark,可以借助 Spark 的分布式框架實現 Caffe 的大規模分布式訓練。

Tensorflow 與Caffe(轉)