文章作者:Tyan
博客:noahsnail.com ?|? CSDN ?|? 簡書
Caffe的設(shè)計
根據(jù)賈揚(yáng)清的分享整理
Caffe遵循了神經(jīng)網(wǎng)絡(luò)的一個假設(shè):所有的計算都是以layer形式表示的,layer的作用就是根據(jù)輸入數(shù)據(jù),輸出一些計算以后的結(jié)果蟋恬。以卷積為例,就是輸入一幅圖像年缎,然后與這一層的參數(shù)(filter)進(jìn)行卷積運(yùn)算,然后輸出卷積的結(jié)果铃慷。每一個layer需要進(jìn)行兩種運(yùn)算:1.forward单芜,從輸入計算輸出;2.backward根據(jù)上面的梯度(gradient)來計算相對于輸入的梯度犁柜。在每個layer都實(shí)現(xiàn)了這兩個函數(shù)以后洲鸠,我們可以將很多層連接成一個網(wǎng)絡(luò),這個網(wǎng)絡(luò)做的事情就是輸入我們的數(shù)據(jù)(圖像或者語音或者whatever)赁温,然后來計算我們需要的輸出(比如說識別的label)坛怪。在訓(xùn)練時,我們可以根據(jù)已有的label來計算loss和gradient股囊,然后用gradient來update網(wǎng)絡(luò)的參數(shù)袜匿。這個就是Caffe的一個基本流程!
Caffe主要結(jié)構(gòu)
Caffe代碼本身非常模塊化稚疹,主要由4部分組成Blob居灯,Layer,Net和Solver内狗。
- Blob
Blob主要用來表示網(wǎng)絡(luò)中的數(shù)據(jù)怪嫌,包括訓(xùn)練數(shù)據(jù),網(wǎng)絡(luò)各層自身的參數(shù)柳沙,網(wǎng)絡(luò)之間傳遞的數(shù)據(jù)都是通過Blob來實(shí)現(xiàn)的岩灭,同時Blob數(shù)據(jù)也支持在CPU與GPU上存儲,能夠在兩者之間做同步赂鲤。
- Layer
Layer是對神經(jīng)網(wǎng)絡(luò)中各種層的一個抽象噪径,包括卷積層和下采樣層柱恤,還有全連接層和各種激活函數(shù)層等等。同時每種Layer都實(shí)現(xiàn)了前向傳播和反向傳播找爱,并通過Blob來傳遞數(shù)據(jù)梗顺。
- Net
Net是對整個神經(jīng)網(wǎng)絡(luò)的表示,由各種Layer前后連接組合而成车摄,也是我們要構(gòu)建的網(wǎng)絡(luò)模型寺谤。
- Solver
Solver定義了針對Net網(wǎng)絡(luò)模型的求解方法,記錄神經(jīng)網(wǎng)絡(luò)的訓(xùn)練過程吮播,保存神經(jīng)網(wǎng)絡(luò)模型參數(shù)变屁,中斷并恢復(fù)網(wǎng)絡(luò)的訓(xùn)練過程。自定義Solver能夠?qū)崿F(xiàn)不同的神經(jīng)網(wǎng)絡(luò)求解方式意狠。
Caffe整體架構(gòu)
Caffe的架構(gòu)與其它的深度學(xué)習(xí)框架稍微不同敞贡,它沒有根據(jù)算法實(shí)現(xiàn)過程的方式來進(jìn)行編碼,而是以系統(tǒng)級的抽象作為整體架構(gòu)摄职,逐層的封裝實(shí)現(xiàn)細(xì)節(jié),使得上層的架構(gòu)變得很清晰获列。Caffe的整體架構(gòu)如下:
1. SyncedMem
這個類的主要功能是封裝CPU和GPU的數(shù)據(jù)交互操作谷市。一般來說,數(shù)據(jù)的流動形式都是:硬盤->CPU內(nèi)存->GPU內(nèi)存->CPU內(nèi)存->(硬盤)击孩,所以在寫代碼的過程中經(jīng)常會寫CPU/GPU之間數(shù)據(jù)傳輸?shù)拇a迫悠,同時還要維護(hù)CPU和GPU兩個處理端的內(nèi)存指針。這些事情處理起來不會很難巩梢,但是會很繁瑣创泄。因此SyncedMem的出現(xiàn)就是把CPU/GPU的數(shù)據(jù)傳輸操作封裝起來,只需要調(diào)用簡單的接口就可以獲得兩個處理端同步后的數(shù)據(jù)括蝠。
2. Blob
Blob是用于存儲數(shù)據(jù)的對象鞠抑,在Caffe中各種數(shù)據(jù)(圖像輸入、模型參數(shù))都是以Blob的形式在網(wǎng)絡(luò)中傳輸?shù)募删珺lob提供統(tǒng)一的存儲操作接口搁拙,可用來保存訓(xùn)練數(shù)據(jù)、模型參數(shù)等法绵,同時Blob還能在CPU和GPU之間進(jìn)行同步以支持CPU/GPU的混合運(yùn)算箕速。
這個類做了兩個封裝:一個是操作數(shù)據(jù)的封裝,使用Blob可以操縱高維的數(shù)據(jù)朋譬,快速訪問其中的數(shù)據(jù)盐茎,變換數(shù)據(jù)的維度等;另一個是對原始數(shù)據(jù)和更新量的封裝徙赢,每一個Blob中都有data和diff兩個數(shù)據(jù)指針字柠,data用于存儲原始數(shù)據(jù)探越,diff用于存儲反向傳播(Backpropagation)的梯度更新值。Blob使用了SyncedMem募谎,這樣便于訪問不同的處理端扶关。Blob基本實(shí)現(xiàn)了整個Caffe數(shù)據(jù)結(jié)構(gòu)部分的封裝,在Net類中可以看到所有的前后向數(shù)據(jù)和參數(shù)都用Blob來表示就足夠了数冬。數(shù)據(jù)的抽象到這個就可以了节槐,接下來作層級的抽象。神經(jīng)網(wǎng)絡(luò)的前后向計算可以做到層與層之間完全獨(dú)立拐纱,只要每個層按照一定的接口規(guī)則實(shí)現(xiàn)铜异,就可以確保整個網(wǎng)絡(luò)的正確性。
3. Layer
Layer是網(wǎng)絡(luò)Net的基本單元秸架,也是Caffe中能在外部進(jìn)行調(diào)整的最小網(wǎng)絡(luò)結(jié)構(gòu)單元揍庄,每個Layer都有輸入Blob和輸出Blob。Layer(層)是Caffe中最龐大最繁雜的模塊东抹,它是神經(jīng)網(wǎng)絡(luò)的基本計算單元蚂子。由于Caffe強(qiáng)調(diào)模塊化設(shè)計,因此只允許每個layer完成一類特定的計算缭黔,例如convolution操作食茎、pooling、非線性變換馏谨、內(nèi)積運(yùn)算别渔,以及數(shù)據(jù)加載、歸一化和損失計算等惧互。Caffe中l(wèi)ayer的種類有很多哎媚,具體的種類及功能請看官方文檔。在創(chuàng)建一個Caffe模型的時候喊儡,也是以Layer為基礎(chǔ)進(jìn)行的拨与。Layer是一個父類,它的下面還有各種實(shí)現(xiàn)特定功能的子類管宵,例如data_layer截珍,conv_layer,loss_layer等箩朴。Layer是通過LayFactory來創(chuàng)建的岗喉。
4. Net
Net是一個完整的深度網(wǎng)絡(luò),包含輸入層炸庞、隱藏層钱床、輸出層,在Caffe中一般是一個卷積神經(jīng)網(wǎng)絡(luò)(Convolution Neural Networ埠居,CNN)查牌。通過定義不同類型的Layer事期,并用Blob將不同的Layer連接起來,就能產(chǎn)生一個Net纸颜。Net將數(shù)據(jù)Blob和層Layer組合起來做進(jìn)一步的封裝兽泣,對外提供了初始化和前后傳播的接口,使得整體看上去和一個層的功能類似胁孙,但內(nèi)部的組合可以是多種多樣的唠倦。值得一提的是,每一層的輸入輸出數(shù)據(jù)統(tǒng)一保存在Net中涮较,同時每個層內(nèi)的參數(shù)指針也保存在Net中稠鼻,不同的層可以通過WeightShare共享相同的參數(shù),因此可以通過配置來實(shí)現(xiàn)多個神經(jīng)網(wǎng)絡(luò)層之間共享參數(shù)的功能狂票。一個Net由多個Layer組成候齿。一個典型的網(wǎng)絡(luò)從data layer(從磁盤中載入數(shù)據(jù))出發(fā)到loss layer結(jié)束。
5. Solver
有了Net就可以進(jìn)行神經(jīng)網(wǎng)絡(luò)的前后向傳播計算了闺属,但是還缺少神經(jīng)網(wǎng)絡(luò)的訓(xùn)練和預(yù)測功能慌盯,Solver類進(jìn)一步封裝了訓(xùn)練和預(yù)測相關(guān)的一些功能。它還提供了兩個接口:一個是更新參數(shù)的接口掂器,繼承Solver可以實(shí)現(xiàn)不同的參數(shù)更新方法润匙,如Momentum,Nesterov唉匾,Adagrad等,因此可以使用不同的優(yōu)化算法匠楚。另一個接口是訓(xùn)練過程中每一輪特定狀態(tài)下的可注入的一些回調(diào)函數(shù)巍膘,在代碼中這個回調(diào)點(diǎn)的直接使用者就是多GPU訓(xùn)練算法。Solver定義了針對Net網(wǎng)絡(luò)模型的求解方法芋簿,記錄網(wǎng)絡(luò)的訓(xùn)練過程峡懈,保存網(wǎng)絡(luò)模型參數(shù),中斷并恢復(fù)網(wǎng)絡(luò)的訓(xùn)練過程与斤。自定義Solver能夠?qū)崿F(xiàn)不同的神經(jīng)網(wǎng)絡(luò)求解方式肪康。閱讀Solver的代碼可以了解網(wǎng)絡(luò)的求解優(yōu)化過程。Solver是一個父類撩穿,它下面還有實(shí)現(xiàn)不同優(yōu)化方法的子類磷支,例如sgd_solver,adagrad_sovler等食寡,Solver是通過SolverFactory來創(chuàng)建的雾狈。
6. Proto
caffe.proto位于…/src/caffe/proto目錄下,在這個文件夾下還有一個.pb.cc和一個.pb.h文件抵皱,這兩個文件都是由caffe.proto編譯而來的善榛。 在caffe.proto中定義了很多結(jié)構(gòu)化數(shù)據(jù)辩蛋,包括:
BlobProto、Datum移盆、FillerParameter悼院、NetParameter、SolverParameter咒循、SolverState据途、LayerParameter、ConcatParameter剑鞍、ConvolutionParameter昨凡、DataParameter、DropoutParameter蚁署、HDF5DataParameter便脊、HDF5OutputParameter、ImageDataParameter光戈、InfogainLossParameter哪痰、InnerProductParameter、LRNParameter久妆、MemoryDataParameter晌杰、PoolingParameter、PowerParameter筷弦、WindowDataParameter肋演、V0LayerParameter。
7. IO
除了上面的東西之外烂琴,還需要輸入數(shù)據(jù)和參數(shù)爹殊。DataReader和DataTransformer幫助準(zhǔn)備輸入數(shù)據(jù),F(xiàn)iller對參數(shù)進(jìn)行初始化奸绷,一些Snapshot方法可以對模型進(jìn)行持久化梗夸。
參考資料: