Caffe學習(十):Caffe中Solver、Net、Layer、Blob的構建流程

以訓練流程的構建爲例:

首先在caffe.cpptrain()中調用caffe::SolverRegistry<float>::CreateSolver(solver_param)

  shared_ptr<caffe::Solver<float> >
      solver(caffe::SolverRegistry<float>::CreateSolver(solver_param));

即通過solover_factory.hpp中的工廠機制(registry[type](param))new 一個具體的已註冊的Solver的子類(例如new SGDSolver<Dtype>(param))的實例而在SGDSolver的構造函數中,首先使用SolverParameter來初始化父類Solver如下:

  explicit SGDSolver(const SolverParameter& param)
      : Solver<Dtype>(param) { PreSolve(); }

而在父類Solver的構造函數中調用Slover::Init(),Slover::Init()中又調用Slover::InitTrainNet(),而在InitTrainNet()中首先從SolverParameter參數中解析出Net所需要的參數,

  if (param_.has_net()) {
    LOG_IF(INFO, Caffe::root_solver())
        << "Creating training net from net file: " << param_.net();
    ReadNetParamsFromTextFileOrDie(param_.net(), &net_param);
  }

然後再通過net_.reset(new Net<Dtype>(net_param)) new一個Net網絡實例:

  if (Caffe::root_solver()) {
    net_.reset(new Net<Dtype>(net_param));
  } else {
    net_.reset(new Net<Dtype>(net_param, root_solver_->net_.get()));
  }

進入到Net類中,在Net的構造函數中調用Net::Init(), Net::Init()中的for循環中根據總層數逐次調用LayerRegistry<Dtype>::CreateLayer(layer_param):

layers_.push_back(LayerRegistry<Dtype>::CreateLayer(layer_param));

即通過layer_factory.cpp中的工廠機制new 一個具體的已註冊的layer層這裏是根據Net傳進來的layer_param獲取到層類型再調用registry[type](param)。例如首先是DataLayer層, 使用Net中傳進來的該層的參數LayerParameter初始化DataLayer

template <typename Dtype>
DataLayer<Dtype>::DataLayer(const LayerParameter& param)
  : BasePrefetchingDataLayer<Dtype>(param),
    reader_(param) {
}

然後又在Net::Init()中for循環中new 下一層例如ConvolutionNet中new出來的子層都放到layers_隊列中。

另外,每個for循環中,new出一個Layer後,又通過AppendTop()AppendBottom()等函數將各層的bottom與top以及weight值構建出一個鏈路出來,bottom、top、weight都是Blob結構,這裏一個top就是一個Blob,例如在mnist的Data層(對應於Caffe中的DataLayer層)中一個top: "data"(一個Blob)即表示一個批次的元素,其維度信息爲(64,1,28,28),一個批次爲64張圖片,長寬均爲28。另外一個top: "label",其維度信息爲(64,1),這也是一個Blob

Net構造函數中new出所有的子層後回到Slover::InitTrainNet()Solver用new出來的Net來初始化其成員 shared_ptr<Net<Dtype> > net_; InitTrainNet()構建完訓練網絡後,Slover::Init()又調用Solver<Dtype>::InitTestNets()使用和InitTrainNet()一樣的方法構建測試網絡(即訓練過程中的驗證操作),其成員變量爲vector<shared_ptr<Net<Dtype> > > test_nets_

以上調用完成後遍回到caffe.cpptrain()中,即完成了SolverNet、Layer的構建。以上流程說明了,在Caffe中Blob就是磚頭、Layer是牆,Net是大廈,而Solver就是圖紙。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章