從Caffe原始碼分析訓練過程
下面開始來具體進行介紹。
先從Caffe.cpp檔案中的train()函式開始說起。
1、建立一個SolverParameter solver_param用來儲存求解(優化)的一些引數,SolverParameter這個資料結構具體被定義在caffe.proto檔案中。
2、Caffe::readProtoFromTextFileDie(“solver.proto”,&solver_param)//讀取solver.proto中的求解引數,並將其儲存在solver_param中。
3、設定Solver模式—設定GPU/CPU進行訓練求解。
4、建立shared_ptr<caffe::Solver<float>> solver(caffe::GetSolver<float>(solver_param))物件,這裡是一種簡單工廠的設計模式,caffe::GetSolver<float>(solver_param),根據solver_param引數的不同,建立不同的物件例項。在這裡caffe預設建立一個SGD的物件例項,即SGD(SGD派生類)求解方式。
在這裡具體實現有:
1、呼叫Solver類建構函式,呼叫Init()函式;
2、Init()函式中呼叫InitTrainNet(),這個函式建立訓練網路Net,首先建立一個Net物件net_,這個net_物件會根據自己配置的網路結構檔案建立不同型別的layer. InitTestNet()與InitTrainNet()類似。
3、呼叫PreSolve函式,這個函式功能是將引數push_back到history_,update_,temp_這三個vector中。
5、solver->Solve求解,主要是反覆呼叫Net::ForwardBackward函式,因為誤差來自於loss層,因此Net::ForwardBackward()只有一個引數。
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Dtype Net::ForwardBackward(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Blob<Dtype></span>* > & bottom) { Dtype loss; Forward(bottom, &loss);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//誤差來自於loss層</span> Backward(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> loss; } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
Net::Forward函式函式,呼叫Net::ForwardPrefilled(), Net::ForwardPrefilled()呼叫Net::ForwardFromTo—這個函式將呼叫layers::Forward函式,因為在Net建立時,layers_物件就儲存了每一層型別,因此每一個layers_[i]呼叫屬於它自己型別的Forward和Backward函式(虛擬函式,多型)。
第一次寫部落格,首先先把caffe的整體訓練的過程理清楚,接下來將寫blob,layers,net,solver的具體實現啦。