深度学习之Caffe完全掌握:用C++开发(自定义)网络层

来源:互联网 发布:尊而光律所怎么样知乎 编辑:程序博客网 时间:2024/06/05 10:05

深度学习之Caffe完全掌握:用C++开发(自定义)网络层(纯cpu实现)


这里写图片描述


意义

当你想实现论文中某个前卫的方法时,caffe中纷繁的网络层模型也不再够用,需要自行定义。同理,你也可以写自己的损失层、数据层和视觉层来加入到网络模型。


我们要做什么

我们要实现一个叫NewLayer的新层,这是一个全通层,它并不做任何事情,只是为了方便展示如何加入自定义的网络层。
我们要添加一个新层,要做以下四件事:

  1. 在include/caffe/layers中创建头文件:new_layer.hpp
  2. 在src/caffe/layers中创建实现文件:new_layer.cpp
  3. 在src/caffe/layers中创建cuda实现文件:new_layer.cu
  4. 在src/caffe/caffe.proto中添加一些定义内容
    注意:之前的要在layer_factory中在 Layer 工厂注册新 Layer 加工函数这一步不再必要了!!

顺便提一句

使用python接口,需要先编译:

[root@master ]# cd /download/caffe[root@master ]# make pycaffe

开始完成那四件事

我们不实现GPU功能,所以省略第三步。
在include/caffe/layers中创建头文件:new_layer.hpp

#ifndef CAFFE_HANSS_LAYER_HPP_  #define CAFFE_HANSS_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 {  template <typename Dtype>  class NewLayer : public NeuronLayer<Dtype> {   public:    explicit NewLayer(const LayerParameter& param)        : NeuronLayer<Dtype>(param) {}    virtual inline const char* type() const { return "AllPass"; }   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  

在src/caffe/layers中创建实现文件:new_layer.cpp

#include <algorithm>  #include <vector>  #include "caffe/layers/new_layer.hpp"  #include <iostream>  using namespace std;  #define DEBUG_AP(str) cout<<str<<endl  namespace caffe {  template <typename Dtype>  void NewLayer<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();    for (int i = 0; i < count; ++i) {      top_data[i] = bottom_data[i];    }    DEBUG_AP("Here is New Layer's forwarding.");    DEBUG_AP(this->layer_param_.new_param().key());  }  template <typename Dtype>  void NewLayer<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];      }    }    DEBUG_AP("Here is New Layer's backwarding.");    DEBUG_AP(this->layer_param_.new_param().key());  }  #ifdef CPU_ONLY  STUB_GPU(NewLayer);  #endif  INSTANTIATE_CLASS(NewLayer);  REGISTER_LAYER_CLASS(New);  }  // namespace caffe  

在src/caffe/caffe.proto中添加一些定义内容
注意对照前后代码,添加我写的下面代码里的关于new_layer的代码:

  ... ...  optional TileParameter tile_param = 138;  optional WindowDataParameter window_data_param = 129;  //mymodel  optional HanssParameter new_param = 155;}//mymodelmessage NewParameter {    optional float key = 1 [default = 0];  }  // Message that stores parameters used to apply transformation// to the data layer's datamessage TransformationParameter {... ...

然后记得重新编译caffe与pycaffe!
最后,写一个网络测试,我只写这个网络层及其它前后两个:

layer {  name: "ip1"  type: "InnerProduct"  bottom: "data"  top: "ip1"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  inner_product_param {    num_output: 50    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "relu1"  type: "ReLU"  bottom: "ip1"  top: "ip1"}layer {  name: "drop1"  type: "Dropout"  bottom: "ip1"  top: "ip1"  dropout_param {    dropout_ratio: 0.5  }}layer {  name: "newLayer"  type: "Hanss"  bottom: "ip1"  top: "newLayer"  hanss_param {    key: 12.88    }}layer {  name: "ip2"  type: "InnerProduct"  bottom: "newLayer"  top: "ip2"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  inner_product_param {    num_output: 50    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "drop2"  type: "Dropout"  bottom: "ip2"  top: "ip2"  dropout_param {    dropout_ratio: 0.4  }}

完成,运行即可。
这里写图片描述