首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >caffe源码分析-ReLULayer

caffe源码分析-ReLULayer

作者头像
bear_fish
发布2019-02-25 11:51:18
5160
发布2019-02-25 11:51:18
举报

激活函数如:ReLuSigmoidlayer相对较为简单,所以在分析InnerProductLayer前,我们先看下激活函数层。

常见激活层ReLU的使用示例如下:

layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}

我们可以看到bottomtop是同一个,那是因为激活层运算均为同址计算

NeuronLayer作为激活层的基类, 继承Layer,定义如下:

template <typename Dtype>
class NeuronLayer : public Layer<Dtype> {
public:
    explicit NeuronLayer(const LayerParameter& param)
            : Layer<Dtype>(param) {}

    virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
                         const vector<Blob<Dtype>*>& top);

    virtual inline int ExactNumBottomBlobs() const { return 1; }
    virtual inline int ExactNumTopBlobs() const { return 1; }
    
};

由于每个激活layer的bottom, top的shape一样,因此NeuronLayer定义了Reshape函数:

template <typename Dtype>
void NeuronLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
                                 const vector<Blob<Dtype>*>& top) {
    top[0]->ReshapeLike(*bottom[0]);
}

ReLULayer的核心函数在与Forward_cpu,Backward_cpu,而且相对也比较简单(简单起见删除了negative_slope运算):

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));
    }
}

反向传播主要是更新blob中的diff_反向传递梯度:

Dtype* bottom_diff = bottom0->mutable_cpu_diff();

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();

        for (int i = 0; i < count; ++i) {
            bottom_diff[i] = top_diff[i] * ((bottom_data[i] > 0);
        }

    }
}

caffe系列源码分析介绍

本系列深度学习框架caffe 源码分析主要内容如下:

1. caffe源码分析-cmake 工程构建:

caffe源码分析-cmake 工程构建主要内容:

自己从头构建一遍工程,这样能让我更好的了解大型的项目的构建。当然原始的caffe的构建感觉还是比较复杂(主要是cmake),我这里仅仅使用cmake构建,而且简化点,当然最重要的是支持CLion直接运行调试(如果需要这个工程可以评论留下你的邮箱,我给你发送过去)。

2. caffe的数据内存分配类SyncedMemory, 以及类Blob数据传输的媒介.

主要内容:

caffe源码分析-SyncedMemory

caffe源码分析-Blob

其中Blob分析给出了其直接与opencv的图片相互转化以及操作,可以使得我们更好的理解Blob.

3. caffe layer的源码分析,包括从整体上说明了layer类别以及其proto定义与核心函数.

内容如下:

caffe源码分析-layer

caffe源码分析-ReLULayer

caffe源码分析-inner_product_layer

caffe源码分析-layer_factory

首先分析了最简单的layer Relu,然后在是inner_product_layer全连接层, 最后是layer_factorycaffe中 以此工厂模式create各种Layer.

4. 数据输入层,主要是多线程+BlockingQueue的方式读取数据训练:

内容如下:

caffe源码分析-BlockingQueue

caffe源码分析-InternalThread

caffe源码分析-DataReader

5. IO处理例如读取proto文件转化为网络,以及网络参数的序列化

内容如下:

caffe源码分析-DataTransformer

caffe源码分析-db, io

6. 最后给出了使用纯C++结合多层感知机网络训练mnist的示例

内容如下:

caffe c++示例(mnist 多层感知机c++训练,测试)

类似与caffe一样按照layer、solver、loss、net等模块构建的神经网络实现可以见下面这篇blog,相信看懂了这个python的代码理解caffe框架会更简单点.

神经网络python实现


最后如果需要**cmake** + CLion**直接运行调试**caffe**的代码工程,可以评论留下你的邮箱,我给你发送过去.**

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年10月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • caffe系列源码分析介绍
    • 1. caffe源码分析-cmake 工程构建:
      • 2. caffe的数据内存分配类SyncedMemory, 以及类Blob数据传输的媒介.
        • 3. caffe layer的源码分析,包括从整体上说明了layer类别以及其proto定义与核心函数.
          • 4. 数据输入层,主要是多线程+BlockingQueue的方式读取数据训练:
            • 5. IO处理例如读取proto文件转化为网络,以及网络参数的序列化
              • 6. 最后给出了使用纯C++结合多层感知机网络训练mnist的示例
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档