深度学习21天实战caffe学习笔记《6 : Caffe代码梳理》

Caffe代码梳理

1、caffe目录结构


2、caffe阅读路线:

  • src/caffe/proto/caffe.proto          了解基本数据结构内存对象和磁盘文件的一一映射,主要由ProtoBuffer工具完成;
  • include头文件                                理解整个框架,从基类向派生类顺藤摸瓜;
  • .cpp和.cu文件                                caffe框架不需要大改,只需要按需求派生出新的类实现即可;
  • 编写各类工具集成到caffe内部         如tools下的工具;
注:快速追踪关键字
(1)多个终端,用vi的查找命令追踪;
(2)使用linux grep,在caffe根目录下运行:
      $grep -n -H -R "XXXXX"
      [  -n : 显示行号;  -H : 显示文件名;  -R : 递归查找每个子目录;]

3、caffe支持的速度学习特性

卷积层和全连接层统称为权值层,具有可学习参数(权值):
3.1、卷积层:
卷积层计算步骤由二维增加至三维、四维卷积,多了“通道(channel)”,每个通道进行二维卷积,没有“翻转”,而是与输入图片做滑动窗口“相关”计算;
多个通道与多个卷积核分别进行二维卷积,得到多通道输出,“合并”为一个通道;


注:其中L、I、J参数可以在.prototxt中找到,图像大小M*N,输出通道K从日志文件可以找到。
3.2、全连接层
全连接层每个节点与相邻层的所有节点都连接,计算类型为矩阵-向量乘;
              y=Wx       (输入节点向量x;维度D;输出节点向量y,维度V;W为V.D维权值矩阵)

则:
单样本前向传播计算量:CaculationsMAC=V.D
参数统计:Params =V.D
CPR值 : CPR=Caculations/Params=1(始终为1,与输入输出维度无关,权值重复利用率很低)

卷积层vs全连接层:参数量全连接层是卷积层的16倍;计算量只有25%;(得益于权值共享&局部连接)
3.3、激活函数
常用的激活函数:
在caffe中位于:include/caffe/neural_layers.hpp

src/caffe/proto/caffe.proto

message ReLUParameter {

  optional float negative_slope = 1 [default = 0];
  enum Engine {
    DEFAULT = 0;
    CAFFE = 1;
    CUDNN = 2;
  }
  optional Engine engine = 2 [default = DEFAULT];
}
Relu.layer
#ifndef CAFFE_RELU_LAYER_HPP_
#define CAFFE_RELU_LAYER_HPP_

#include <vector>

#include "caffe/blob.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"

#include "caffe/layers/neuron_layer.hpp"

namespace caffe {

/**
 * @brief Rectified Linear Unit non-linearity @f$ y = \max(0, x) @f$.
 *        The simple max is fast to compute, and the function does not saturate.
 */
template <typename Dtype>
class ReLULayer : public NeuronLayer<Dtype> {      //派生于NeuronLayer,实现Relu激活函数的计算
 public:
  /**
   * @param param provides ReLUParameter relu_param,
   *     with ReLULayer options:
   *   - negative_slope (\b optional, default 0).
   *     the value @f$ \nu @f$ by which negative values are multiplied.
   */
  //显示构造函数
  explicit ReLULayer(const LayerParameter& param)
      : NeuronLayer<Dtype>(param) {}
//返回类名字符串
  virtual inline const char* type() const { return "ReLU"; }

 protected:
  //前向传播函数
  virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top);
  virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top);

  //反向传播函数
  virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);
  virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);
};

}  // namespace caffe

#endif  // CAFFE_RELU_LAYER_HPP_

src/caffe/layers/relu_layer.cpp

#include <algorithm>
#include <vector>

#include "caffe/layers/relu_layer.hpp"

namespace caffe {

template <typename Dtype>
void ReLULayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    const vector<Blob<Dtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = top[0]->mutable_cpu_data();
  const int count = bottom[0]->count();
  Dtype negative_slope = this->layer_param_.relu_param().negative_slope();
  for (int i = 0; i < count; ++i) {
    top_data[i] = std::max(bottom_data[i], Dtype(0))
        + negative_slope * std::min(bottom_data[i], Dtype(0));
  }
}

template <typename Dtype>
void ReLULayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
    const vector<bool>& propagate_down,
    const vector<Blob<Dtype>*>& bottom) {
  if (propagate_down[0]) {
    const Dtype* bottom_data = bottom[0]->cpu_data();
    const Dtype* top_diff = top[0]->cpu_diff();
    Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
    const int count = bottom[0]->count();
    Dtype negative_slope = this->layer_param_.relu_param().negative_slope();
    for (int i = 0; i < count; ++i) {
      bottom_diff[i] = top_diff[i] * ((bottom_data[i] > 0)
          + negative_slope * (bottom_data[i] <= 0));
    }
  }
}


#ifdef CPU_ONLY
STUB_GPU(ReLULayer);
#endif

INSTANTIATE_CLASS(ReLULayer);

}  // namespace caffe



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

女王の专属领地

您的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值