最近打算看一看caffe實現的原始碼,因為發現好多任務作都是基於改動網路來實現自己的的目的。比如變更目標函式以及網路結構,以實現風格轉化或者達到更好的效果。此次閱讀**是按照caffe訓練這個線索進行的。在閱讀之前,可能需要了解一下caffe大概有哪些模組以及各個模組的大概作用,可以參考caffe各模組構成
caffe.bin
網路初始化
tools/caffe.cpp
這個是我們在訓練網路時用到的可執行檔案,其對應的原始碼為,其中main()函式首先對輸入引數進行解析,這裡邊用到了google的工具包gflags,引數會把linux下輸入的
./build/tools/caffe.bin train --solver=examples/mnist/lenet_solver.prototxt -gpu all
識別為兩部分,./build/tools/caffe.bin和train,然後前面帶」-「的自動識別為引數。之後在main()函式中呼叫getbrewfunction()函式啟動對應的函式(train,test,time),這些函式是通過registerbrewfunction()在編譯中把指向其的指標儲存到乙個map結構中。
接著,在train()函式中,首先讀取指定網路hyper parameters以及網路結構,這是由.proto格式的檔案定義的,這是一種類似xml和json的資料交換格式,且google有對應的工具包來生成對應的處理函式以及類。
caffe::readsolverparamsfromtextfileordie(flags_solver, &solver_param);
其中flags_solver是.proto檔案的位址,solverparameter的定義在src/caffe/proto/caffe.proto中,在編譯時,會產生乙個caffe.pb.cc和caffe.pb.h檔案,對應的就是其產生的類以及一些函式。在讀取到這些引數後,開始設定gpu/cpu模式,然後呼叫
solver(caffe::solverregistry::createsolver(solver_param));
函式初始化網路。
include/caffe/solver_factory.hpp
在上面呼叫的函式中,createsolver()函式是產生乙個creatorregistry的物件,這是乙個map結構,其key值是string,指定優化演算法,value是乙個指向solver類物件的指標。這個函式在返回的時候,會呼叫solver類的建構函式產生乙個solver類物件。然後上面的solver類物件solver通過預設的拷貝建構函式產生這個solver物件。
src/caffe/solver.cpp
在solver類的建構函式中,其會呼叫init()函式,這個函式中會呼叫其兩個成員函式inittrainnet()和inittestnets()。在solver這個類中,有net的類物件作為其成員變數,包括用於訓練的網路net_和用於測試的網路test_nets_。在上面的兩個函式內,這些物件會通過reset()函式複製由
net(const netparameter& param, const net* root_net);
建構函式產生的net類物件。
src/caffe/net.cpp
在net類的建構函式中,會呼叫類成員函式
init(const netparameter& in_param);
其會首先對網路的每層做一次過濾filternet(),比如對於訓練網路來說,accuracy網路層是不必要的,而起始的測試(訓練)網路的輸入層對訓練(測試)網路來說是不必要的。接著網路呼叫在++src/caffe/util/insert_splits.cpp++中定義的insertsplits()函式來根據情況產生一層網路。就是當網路層a的輸出會作為網路層b,c的輸入,那麼通過insertsplits()函式會產生一層split層,就是對共享輸入的層,在這些層前面加入一層split(參考)。
之後網路開始根據層數的多少設定輸入bottom和輸出top的大小,它們是存放在vector容器中的blob資料格式,其定義在blob類中,此地按下不表。對於每一層,用乙個for迴圈,設定層與層之間的連線,以及存放每層得到的殘差的記憶體空間,哪些層需要後向傳播,並統計記憶體消耗等。然後從後往前遍歷一遍網路,統計哪些blobs會涉及到網路損失的計算。並且對於剩餘的為處理分配的blobs,認定其為輸出。最後可能某些層之間會共享w和b的權重以及方差,所以需要呼叫shareweights()函式開啟一下,至此網路初始化完成。
《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具
檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...
caffe原始碼閱讀5 各種layer概述
工廠模式 乙個工廠可以生產n種產品,那麼就需要n種磨具。因為從來沒有玩過設計模式,而layer是採用工廠模式的,就臨時看了一下,大概可以用上面的那一句話來描述吧。基本可以說caffe中的所有層都是繼承了layer類的,那麼在caffe中,一共有哪些層呢?可以在caffe.proto中看到 enum ...
Caffe原始碼閱讀 1 全連線層
發表於 2014 09 15 今天看全連線層的實現。主要看的是 主要是三個方法,setup,forward,backward 主體的思路,作者的注釋給的很清晰。主要是要弄清楚一些變數對應的含義 123 m 表示的樣本數 k 表示單個樣本的特徵長度 n 表示輸出神經元的個數 為了打字方便,以下省略下劃...