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就是图纸。

发布了40 篇原创文章 · 获赞 51 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/zh8706/article/details/96840731