1. 程式人生 > >caffe2 和 caffe 有何不同

caffe2 和 caffe 有何不同

前幾天 facebook 開源的 caffe2,讓我們在深度學習框架上又多了一個選擇。caffe2 宣稱是輕量級、模組化和可擴充套件的一個框架,code once,run anywhere。作為一個老 caffe 玩家,自是要好好研究一番。

依賴處理

第一版 caffe 的依賴是個讓人頭疼的事,尤其是在公司舊版的伺服器上安裝時,需要花費大量的時間折騰。伺服器的系統舊,python的版本低(2.4),直接升級可能會影響現有服務,所以只能原始碼編譯安裝各種依賴。當時比較頭疼的問題有兩個:

  • 依賴裡面套著依賴:glog需要gflags,gflags需要cmake(版本低了,好像也會有問題),numpy依賴python的版本和Cython,等等。
  • 解決完一臺的問題,下一臺還會出現新問題。

當然,現在有了docker,這些都不再是問題了。但當時前前後後安裝了好多遍,又是改程式碼,又是改Makefile,每次都挺麻煩。

現在新版的 caffe2 通過簡化依賴,按需配置,完美的解決了這些問題。在 caffe2 的資料夾中,只有core和proto兩個資料夾是必須的,其他都是可配置的。而所謂的code once,run everywhere,核心就在於此。

Deep_Learning/caffe2/caffe2(master⚡)» tree -d .                                                                         
.
├── binaries ├── contrib │ ├── docker-ubuntu-14.04 │ ├── gloo │ ├── mpscnn-fb │ ├── nccl │ ├── nervana │ ├── nnpack │ ├── prof │ ├── snpe-fb │ ├── torch │ └── warpctc ├── core ├── cuda_rtc ├── db ├── distributed ├── experiments │ ├── operators │ └── python ├── image ├── mkl │ └── operators ├── mpi ├── operators ├── proto ├── python │ ├── docs │ ├── examples │ ├── helpers │ ├── layers │ ├── mint │ │ ├── static │ │ │ └── css │ │ └── templates │ ├── models │ ├── operator_test │ ├── predictor │ ├── tutorial │ └── tutorials │ ├── experimental │ └── images ├── queue
├── sgd ├── test │ └── assets └── utils ├── mkl └── threadpool 48 directories

這樣,就可以針對不同的需求做不同的選擇,靈活性更大。

Net 組成方式

第一版的 caffe 的 Net 由粒度較粗的layer組成,即每個layer的 weight 和 bias 都以layer級別儲存,這樣做雖然簡單直觀,但有以下幾個問題:

  • 針對具體平臺做優化時,就會比較繁瑣,現有的程式碼只有GPU和CPU的版本,即forward_cpu,forward_gpu,如果針對arm優化,則不僅僅新增該layer的arm實現,還要修改其他地方的程式碼。
  • 新增新的layer實現,需要修改caffe.proto檔案,重新編譯,而且當新的layer是已有幾個layer的組合時,比如LRN layer,就由split layer、power layer和pooling layer組成,複用起來稍有複雜。
  • weight 和 bias 引數和 layer 繫結在一起,finetune 也會稍顯複雜,修改Net的prototext檔案,指定哪些layer的引數保持不變,哪些layer的引數需要重新學習。

其實最後一個問題是我經常所遇到的問題,感謝開源,有很多現成的模型可以直接使用,我一般會挑選合適的模型進行finetune,很少會從零開始訓練(只有個家用級別的GPU,也訓不起來,哈哈)。做的多了,就會想,如果可方便的方式進行finetune就好了,比如我基本都在搞分類識別,基本都會保留前幾層的卷積引數不動,用來提取中級特徵,如果Net的組成方式更加靈活,不同的訓練可以載入使用相同的layer,類似與資料並行,就可以同時訓練出好幾組模型了。

新版 caffe2 的Net組成,也採用了 tensorflow、mxnet 等這些框架使用 operator 方式,由更細粒度的 operator 組合而成。當粒度變小時,可以做的優化就更多了:

  • 多平臺的支援變得更加容易了,operator 僅僅是處理資料的邏輯,這就可以有針對性的優化。這個優化不僅包括單個 operator 在新平臺的支援,還包括多個 operator 組合的優化。
  • layer 變成了 operator 的組合,剝離了 weight 和 bias 的引數,一方面生成新的 layer 更加方便,另一方面也可對 weight 和 bias 控制。就像 output=f(wx+b),當把w和b都當成了引數,就可以把一個函式變成一類函數了。
  • 最大的好處,我覺得還是可以宣告式的編寫神經網路了,這個和第一版 caffe 相比,就類似使用所見即所得的方式 vs 使用latex 編寫文件一樣。

在原始碼的scripts資料夾中,可以看到iOS、Android、Raspberry PI、windows等平臺的編譯指令碼,而僅僅改動幾行,就可以支援watchOS,很好很強大,具體可以看看這個Pull Request。

基礎資料 Blob

caffe2 中把 caffe 中的 Blob 進行擴充套件,支援了更多的型別,這就讓 Binary Net 和模型的量化壓縮變得可行。這兩個在工業界應該關注更多一些,畢竟關乎成本,它們可以讓模型在現有的 CPU 機器上可實用,進一步可以應用到手機端。目前動輒幾十、幾百MB的模型,怎麼嵌入到手機端,確實是個大問題啊(怪不得 facebook 的 iOS 端的安裝包越來越大,會不會和這個有關?哈哈)。

總結

caffe2 可以看作是 caffe 更細粒度的重構,在實用的基礎上,增加了擴充套件性和靈活性。作為 caffe 的重度使用者,caffe2 解決了我的好幾個痛點,後續我會從原始碼角度進行深入學習,會在樹莓派上進行測試,同時我業餘也在使用 golang 進行第一版 caffe 模型的量化壓縮和視覺化的研究,即 gocaffe,對這方面感興趣的朋友可以關注微博或者微信公眾號:hackcv,一起交流學習。