当前位置:   article > 正文

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

完全掌握c++

深度学习之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
  • 1
  • 2

开始完成那四件事

我们不实现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  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在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  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

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

  ... ...
  optional TileParameter tile_param = 138;
  optional WindowDataParameter window_data_param = 129;
  //mymodel
  optional HanssParameter new_param = 155;
}

//mymodel
message NewParameter {  
  optional float key = 1 [default = 0];  
}  

// Message that stores parameters used to apply transformation
// to the data layer's data
message TransformationParameter {
... ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

然后记得重新编译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
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/256888
推荐阅读
相关标签
  

闽ICP备14008679号