caffe中添加新层(差分层)

原文网址:http://blog.csdn.net/wfei101/article/details/76735760

caffe中添加新层(最新版本2017.8)

正向直接copy传播,反向时将梯度放缩指定倍。

这个层对一些特定的网络结构有很重要的辅助作用,比如有时我们的网络存在分支,但我们不希望某一分支影响之前层的更新,那么我们就将梯度放缩0倍

(1)创建hpp头文件diff_cutoff_layer.hpp

不同功能类型的层所引的头文件也不同,具体大家可以到“caffe/include/caffe/layers”目录下找相似的现成的文件参考 。我们这次写的hpp文件最后也要放在这个目录下。
注意:下面注释包起来的部分为需要注意的部分。
特别注意:
命名的时候应严格一致和注意大小写,这一点是导致很多人加层失败的主要原因

[cpp]  view plain  copy
  1. //*****************************************  
  2. #ifndef CAFFE_DIFFCUTOFF_LAYER_HPP_  
  3. #define CAFFE_DIFFCUTOFF_LAYER_HPP_  
  4. //*****************************************  
  5.   
  6. #include <vector>  
  7. #include "caffe/blob.hpp"  
  8. #include "caffe/layer.hpp"  
  9. #include "caffe/proto/caffe.pb.h"  
  10.   
  11. //*****************************************  
  12. #include "caffe/layers/neuron_layer.hpp"  
  13. //*****************************************  
  14.   
  15. namespace caffe {  
  16.   
  17. template <typename Dtype>  
  18. //******以后我们层的type: "DiffCutoff" *******  
  19.   class DiffCutoffLayer : public NeuronLayer<Dtype> {  
  20. //*****************************************  
  21.   public:  
  22.     explicit DiffCutoffLayer(const LayerParameter& param) : NeuronLayer<Dtype>(param) {}  
  23.     virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>&top);  
  24.   
  25. //****我们只需要一个bottom和一个top*****  
  26.     virtual inline int ExactNumBottomBlobs() const { return 1; }  
  27.   
  28. //******以后我们层的type: "DiffCutoff" *******  
  29.     virtual inline const char* type() const { return "DiffCutoff"; }  
  30.   
  31.   protected:  
  32. //******这里只写了CPU功能,故删掉了原本的GPU函数 *******  
  33.     virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top);  
  34.     virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);  
  35.   
  36. //  *****定义一个Dtype型的标量,用来存储梯度放缩倍数***  
  37.      Dtype diff_scale;  
  38.     };  
  39. }   
  40. #endif    
(2)创建diff_cutoff_layer.cpp文件

CPP文件应当位于src/caffe/layers下

[cpp]  view plain  copy
  1. #include <algorithm>  
  2. #include <vector>  
  3.   
  4. //*****************************************  
  5. #include "caffe/layers/diff_cutoff_layer.hpp"  
  6. //*****************************************  
  7.   
  8. #include "caffe/util/math_functions.hpp"  
  9. namespace caffe {  
  10.   
  11.   template <typename Dtype>  
  12.   void DiffCutoffLayer<Dtype>::LayerSetUp(  
  13.     const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {  
  14.     NeuronLayer<Dtype>::LayerSetUp(bottom, top);  
  15.   
  16.  // 因为对前向传播不修改,因此top的shape应和bottom的shape相同  
  17.     top[0]->Reshape(bottom[0]->shape());   
  18.   }  
  19.   
  20.   template <typename Dtype>  
  21.   void DiffCutoffLayer<Dtype>::Forward_cpu(  
  22.     const vector<Blob<Dtype>*>& bottom,  
  23.     const vector<Blob<Dtype>*>& top) {  
  24.  // 前向传播直接将bottom的数据copy到top  
  25.     const int count = top[0]->count();  
  26.     caffe_copy(  
  27.         count,  
  28.         bottom[0]->cpu_data(),  
  29.         top[0]->mutable_cpu_data());  
  30.   }  
  31.   
  32.   template <typename Dtype>  
  33.   void DiffCutoffLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {  
  34.     const int count = top[0]->count();  
  35.     const Dtype* top_diff = top[0]->cpu_diff();  
  36.   //读取我们实际指定的梯度放缩倍数,注意我们的参数名为diff_scale  
  37.     diff_scale= this->layer_param_.diff_cutoff_param().diff_scale();  
  38.   
  39. // 如果bottom前向传播完成,我们就把top的diff放缩后赋给bottom的diff  
  40.     if (propagate_down[0]) {  
  41.       Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();  
  42.       caffe_cpu_axpby(  
  43.       count,  
  44.       diff_scale,  
  45.       top_diff,  
  46.       Dtype(0),  
  47.       bottom_diff);  
  48.     }    
  49.   }  
  50.   
  51. #ifdef CPU_ONLY  
  52.   STUB_GPU(DiffCutoffLayer);  
  53. #endif  
  54.   
  55.   INSTANTIATE_CLASS(DiffCutoffLayer);  
  56.   REGISTER_LAYER_CLASS(DiffCutoff);  
  57. }   

(3)修改src\caffe\proto\caffe.proto文件

【1】由于我们的层有一个diff_scale参数,因此我们首先应该在message LayerParameter {}中添加新参数信息。添加信息时,首先要制定一个唯一ID,这个ID的可选值可以由这句话看出:

[cpp]  view plain  copy
  1. // NOTE  
  2. // Update the next available ID when you add a new LayerParameter field.  
  3. //  
  4. // LayerParameter next available layer-specific ID: 147 (last added: BatchCLuster)  
  5. message LayerParameter {  

由上图可以看出,可选的ID为147。 于是我们就可以添加这样一行:

[cpp]  view plain  copy
  1. optional DiffCutoffParameter diffcutoff_param = 147;  

任意位置出定义层的参数

[cpp]  view plain  copy
  1. message DiffCutoffParameter   
  2. {   
  3. optionalfloat  diff_scale = 1 [default = 1];//默认梯度不缩放  
  4. }  
(4)最后重新编译caffe即可
设置train.prototxt

[cpp]  view plain  copy
  1. layer {  
  2. name: "diff_1"  
  3. type: "DiffCutoff"  
  4. bottom: "conv1"  
  5. top: "diff_1"  
  6. diff_cutoff_param {  
  7. diff_scale: 0.0001  
  8. }  
  9. }  
(5)放入到相应的位置,然后运行caffe,就可以了!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值