caffe添加新层教程

22844人阅读 评论(20)

（1）创建HPP头文件diff_cutoff_layer.hpp

//*****************************************
#ifndef CAFFE_DIFFCUTOFF_LAYER_HPP_
#define CAFFE_DIFFCUTOFF_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>
//******以后我们层的type: "DiffCutoff" *******
class DiffCutoffLayer : public NeuronLayer<Dtype> {
//*****************************************
public:
explicit DiffCutoffLayer(const LayerParameter& param) : NeuronLayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>&top);

//****我们只需要一个bottom和一个top*****
virtual inline int ExactNumBottomBlobs() const { return 1; }

//******以后我们层的type: "DiffCutoff" *******
virtual inline const char* type() const { return "DiffCutoff"; }

protected:
//******这里只写了CPU功能，故删掉了原本的GPU函数 *******
virtual void Forward_cpu(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);

//  *****定义一个Dtype型的标量，用来存储梯度放缩倍数***
Dtype diff_scale;
};
}
#endif  

（2）创建diff_cutoff_layer.cpp文件

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

#include <algorithm>
#include <vector>

//*****************************************
#include "caffe/layers/diff_cutoff_layer.hpp"
//*****************************************

#include "caffe/util/math_functions.hpp"
namespace caffe {

template <typename Dtype>
void DiffCutoffLayer<Dtype>::LayerSetUp(
const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
NeuronLayer<Dtype>::LayerSetUp(bottom, top);

// 因为对前向传播不修改，因此top的shape应和bottom的shape相同
top[0]->Reshape(bottom[0]->shape());
}

template <typename Dtype>
void DiffCutoffLayer<Dtype>::Forward_cpu(
const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
// 前向传播直接将bottom的数据copy到top
const int count = top[0]->count();
caffe_copy(
count,
bottom[0]->cpu_data(),
top[0]->mutable_cpu_data());
}

template <typename Dtype>
void DiffCutoffLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
const int count = top[0]->count();
const Dtype* top_diff = top[0]->cpu_diff();
//读取我们实际指定的梯度放缩倍数，注意我们的参数名为diff_scale
diff_scale= this->layer_param_.diffcutoff_param().diff_scale();

// 如果bottom前向传播完成，我们就把top的diff放缩后赋给bottom的diff
if (propagate_down[0]) {
Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
caffe_cpu_axpby(
count,
diff_scale,
top_diff,
Dtype(0),
bottom_diff);
}
}

#ifdef CPU_ONLY
STUB_GPU(DiffCutoffLayer);
#endif

INSTANTIATE_CLASS(DiffCutoffLayer);
REGISTER_LAYER_CLASS(DiffCutoff);
} 

（3）修改src\caffe\proto\caffe.proto文件

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

// NOTE
// Update the next available ID when you add a new LayerParameter field.
//
// LayerParameter next available layer-specific ID: 143 (last added: BatchCLuster)
message LayerParameter {

  optional DiffCutoffParameter diffcutoff_param = 143;

【2】在任意位置添加消息函数

message DiffCutoffParameter {
optional float diff_scale = 1 [default = 1]; //默认梯度不缩放
}

【3】 在message V1LayerParameter {}中添加以下内容

   DIFF_CUTOFF=45;

  optional DiffCutoffParameter diffcutoff_param = 46;

【4】 在message V0LayerParameter {}添加参数定义

  optional float diff_scale = 47 [default = 1]; 

（4）最后重新编译caffe即可

layer {
name: "diff_1"
type: "DiffCutoff"
bottom: "conv1"
top: "diff_1"
diff_cutoff_param {
diff_scale: 0.0001
}
}

（5）忠告与建议

（1）一定要注意大小写、一定要注意大小写、一定要注意大小写

（2）不会写、不确定，就去找caffe现有的层来参考模仿

（3）caffe数据操作的函数定义在src/caffe/util/math_functions.cpp,

http://blog.csdn.net/seven_first/article/details/47378697

8
0

个人资料
• 访问：652545次
• 积分：6852
• 等级：
• 排名：第4062名
• 原创：135篇
• 转载：11篇
• 译文：1篇
• 评论：523条