caffe创建新的layer一般分为以下步骤:
1. 创建hpp头文件;
2. 创建cpp文件;
3. 修改caffe.proto文件(文件路径:.\src\caffe\proto\caffe.proto)
4. 重新编译caffe即可
—————————————分割线————————————
详细步骤(以diff_cuto_layer.hpp为例):
注:由于创建的新层实现的功能不同,可以caffe中现有的文件进行编写(路径:.\include\caffe\layers);
(1) 在.\include\caffe\layers路径下创建名为diff_cuto_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)在.\src\caffe\layers路径下创建名为diff_cutoff_layer.cpp文件,并写入如下代码:
#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文件
注:此处主要是为新layer添加参数和消息函数
- 找到message LayerParameter{ }并添加新的参数信息;
message LayerParameter {
// 将此语句添加在文中对应位置
optional DiffCutoffParameter diffcutoff_param = 143; // 新添加的ID
}
- 在任意位置添加消息函数,代码如下:
message DiffCutoffParameter {
optional float diff_scale = 1 [default = 1]; //默认梯度不缩放
}
- 在message V1LayerParameter {}中添加以下内容:
在enum LayerType {}中添加唯一ID,注意不可重复!
DIFF_CUTOFF=45;
同样在message LayerParameter{ }添加ID,不可重复!
optional DiffCutoffParameter diffcutoff_param = 46;
在message V0LayerParameter {}添加参数定义
optional float diff_scale = 47 [default = 1];
(4)重新编译caffe
sudo make clean
sudo make all