3. caffe源码解读----layer.hpp、layer.cpp

一、include/caffe/layer.hpp                                                                                                  点击此处返回总目录

二、src/caffe/layer.cpp

 

一、layer.hpp

Layer头文件位于include/caffe/layer.hpp中。内容如下:

 

#ifndef CAFFE_LAYER_H_
#define CAFFE_LAYER_H_

#include <algorithm>
#include <string>
#include <vector>

#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/layer_factory.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/math_functions.hpp"

/**
 Forward declare boost::thread instead of including boost/thread.hpp
 to avoid a boost/NVCC issues (#1009, #1010) on OSX.
 */

之前有一个boost/NVCC的问题,这个是GitHub上的1009和1010号问题。这个问题通过声明boost::thread代替boost/thread.hpp来解决了。有兴趣可以自己看一下。


namespace boost { class mutex; }    //在boost里面定义了一个类,但是什么也没做。这个可能是跟上面的问题有关,我们不做研究。

namespace caffe {

/**
 * @brief An interface for the units of computation which can be composed into a
 *        Net.
 *
 * Layer%s must implement a Forward function, in which they take their input
 * (bottom) Blob%s (if any) and compute their output Blob%s (if any).
 * They may also implement a Backward function, in which they compute the error
 * gradients with respect to their input Blob%s, given the error gradients with
 * their output Blob%s.
 */

计算单元可以连接成网络,Layer就是这些计算单元的接口。

Layer类的子类必须实现Forward函数,Forward函数接受输入Blob,计算输出Blob。

Layrer类的子类也可能实现反向传播函数,从输入的Blob计算梯度误差,然后把梯度误差给输出的Blob。也可能不需要实现反向传播函数。


template <typename Dtype>     //Dtype就是区分double和float的。
class Layer {
 public:
  /**
   * You should not implement your own constructor. Any set up code should go
   * to SetUp(), where the dimensions of the bottom blobs are provided to the
   * layer.
   */

  explicit Layer(const LayerParameter& param)       //这里声明了一下构造函数,不能被隐式地调用。显示构造函数。作用是:从LayerParameter对象中加载配置。
    : layer_param_(param), is_shared_(false) {         //初始化列表
      // Set phase and copy blobs (if there are any).  //第一件事就是从参数里面设置phase,并且如果有blob的话就拷贝blob
      phase_ = param.phase();                                  //设置当前阶段(train/test)
      if (layer_param_.blobs_size() > 0) {                   //把上面一层和下面一层的blob都拷贝进来。
        blobs_.resize(layer_param_.blobs_size());     //按layer_param_设置本身Blob对象个数,并依次将每个Blob对象尺寸调整为与layer_param_中的Blob尺寸一致
        for (int i = 0; i < layer_param_.blobs_size(); ++i) {
          blobs_[i].reset(new Blob<Dtype>());
          blobs_[i]->FromProto(layer_param_.blobs(i));
        }
      }
    }
  virtual ~Layer() {}            //虚析构函数。析构函数也是需要你在子类中实现的。

  /**
   * @brief Implements common layer setup functionality.
   *
   * @param bottom the preshaped input blobs
   * @param top
   *     the allocated but unshaped output blobs, to be shaped by Reshape
   *
   * Checks that the number of bottom and top blobs is correct.
   * Calls LayerSetUp to do special layer setup for individual layer types,
   * followed by Reshape to set up sizes of top blobs and internal buffers.
   * Sets up the loss weight multiplier blobs for any non-zero loss weights.
   * This method may not be overridden.
   */

配置函数,实现常用层的配置功能。参数bottom是已经预分配形状的blobs,就是说形状已经定义好了。参数top是已经分配但是还没有没有确定形状的blobs。也就是说,输入的形状是固定的,输出的形状是不固定的。输出是要根据输入和这一层的一些参数来决定的,比如卷积层要根据卷积核长度,有没有padding等来确定。

第一步,检查上一层和下一层的blobs数目对不对。

第二步,调用LayerSetup()函数对不同类型的层使用不同的setup方法。

第三步,根据我们算的形状把top的blob的大小设置好,还有一些内部的缓存空间也设置好。

第四步,设置损失权值因子blobs。

SetUp这个函数就不要重写它了。我们严格来遵守这个原则,如果想实现就实现里面的具体的函数,但是这个总的大纲就不要动。


  void SetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
    InitMutex();
    CheckBlobCounts(bottom, top);     //第一步,检查Blob
    LayerSetUp(bottom, top);               //第二步,与层相关的配置过程
    Reshape(bottom, top);                   //第三步,对top blob变形
    SetLossWeights(top);                     //第四步,设置损失权值因子Blob
  }

  /**
   * @brief Does layer-specific setup: your layer should implement this function
   *        as well as Reshape.
   *
   * @param bottom
   *     the preshaped input blobs, whose data fields store the input data for
   *     this layer
   * @param top
   *     the allocated but unshaped output blobs
   *
   * This method should do one-time layer specific setup. This includes reading
   * and processing relevent parameters from the <code>layer_param_</code>.
   * Setting up the shapes of top blobs and internal buffers should be done in
   * <code>Reshape</code>, which will be called before the forward pass to
   * adjust the top blob sizes.
   */

LayerSetUp()函数做了特定类型层相关的设置。自己的层应该实现这个函数和下面的Reshape()函数。

这里就定义了一个虚函数,就一个声明,什么也没干,就是要让你继承并实现它。这里声明了,就必须要实现它。

参数bottom是输入的blob。

参数top是输出的blob。没有分配形状。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值