前幾天 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,一起交流學習。
原貼:http://www.hackcv.com/index.php/archives/110/?utm_source=tuicool&utm_medium=referral