从caffe中新增layer(cpp版本)
来源:互联网 发布:phpstorm mac 激活 编辑:程序博客网 时间:2024/06/05 13:39
在caffe 中增加一个什么都不做的layer(不考虑forward&backward算法,只考虑打通流程)
英文教程 https://github.com/BVLC/caffe/wiki/Development#developing-new-layers
一 修改 /src/caffe/proto/caffe.proto
1 在 LayerParameter 增加
optional MyLayerParameter my_layer_param = 147; (这个ID :147。是因为最近的layerid是146 增加新的layer的话,id数字递增就好了)
2 添加 自己的 MyLayerParameter
message MyLayerParameter { // add MyLayerParameter optional float pam = 1 [default = 1.0];// 增加一个变量,调研一下怎么获取。 enum Engine { DEFAULT = 0; CAFFE = 1; CUDNN = 2; } optional Engine engine = 2 [default = DEFAULT];}
二 在include/layers/ 增加 MyLayer .hpp文件。样例
#ifndef CAFFE_MY_LAYER_HPP_#define CAFFE_MY_LAYER_HPP_#include <vector>#include "caffe/blob.hpp"#include "caffe/layer.hpp"#include "caffe/proto/caffe.pb.h"namespace caffe {template <typename Dtype>class MyLayer : public Layer<Dtype> { public: explicit MyLayer(const LayerParameter& param) : Layer<Dtype>(param) {} //virtual void Reshape(const vector<Blob<Dtype>*>& bottom, // const vector<Blob<Dtype>*>& top); virtual inline const char* type() const { return "My"; } virtual inline int ExactNumBottomBlobs() const { return 1; } virtual inline int MinTopBlobs() const { return 1; } virtual void Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); protected: 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); virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual void Backward_gpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom); float myParm;};} // namespace caffe#endif // CAFFE_MY_LAYER_HPP_
注意:
1 {*}Blobs()之类的方法 约定了输入和输出的blob的个数。例如在neuron_layer.hpp 中ExactNumBottomBlobs(确切数字),MinTopBlobs 返回值为1.而ConcatLayer 中约定了MinBottomBlobs为1。
2 virtual inline const char* type() const { return “My”; }
这一句话实现是为了在train.prototxt 中加入 my_layer 的的参数。
3 reshape && Forward_cpu && Backward_cpu && Forward_gpu && Backward_gpu 我在hpp中都写了一遍,其中reshape && Forward_cpu && Backward_cpu 在cpp文件中时需要实现的。gpu我没有实现。
三 在 /src/caffe/layers 加入 my_layer.cpp .样例
#include <algorithm>#include <vector>#include <iostream>#include "caffe/layers/my_layer.hpp"namespace caffe {template <typename Dtype>void MyLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { top[0]->ReshapeLike(*bottom[0]);}template <typename Dtype>void MyLayer<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(); myParm = this->layer_param_.my_layer_param().pam(); //std::cout<<"my parm : "<<myParm<<std::endl; for (int i = 0; i < count; ++i) { top_data[i] = bottom_data[i]; }}template <typename Dtype>void MyLayer<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(); myParm = this->layer_param_.my_layer_param().pam(); //std::cout<<"my parm : "<<myParm<<std::endl; for (int i = 0; i < count; ++i) { bottom_diff[i] = top_diff[i]; } }}#ifdef CPU_ONLYSTUB_GPU(MyLayer);#endifINSTANTIATE_CLASS(MyLayer);REGISTER_LAYER_CLASS(My);// namespace caffe}~ ~
注意:
1 在forward和backward中,data 有cpu_data()和mutable_cpu_data() 之分。
在 http://caffe.berkeleyvision.org/tutorial/net_layer_blob.html 中有所描述。
如果使用mutable或者是_data()时候的疑惑,在这里也许有答案。
http://stackoverflow.com/questions/28710350/when-does-caffe-make-copies-of-the-data
另外cpu_data() 为const Dtype*类型。而mutable_cpu_data() 是 Dtype*类型。关于c++ const的tips可以参考下面的链接: http://blog.csdn.net/melody_fhm/article/details/6683504
2 关于我们在MyLayerParameter的proto定义的 optional float pam = 1 [default = 1.0];我们可以直接以下语句获得。
myParm = this->layer_param_.my_layer_param().pam();
3 最后注册一下这个 layer ,在末尾语句是 REGISTER_LAYER_CLASS(My);另外还有别的注册方式,在/include/layer_factory.hpp中有说明。
四 编译验证。
编译之后,在比较简单的网络mnist中加入我们想要的自定义layer参数(我放在了covn1的后面)验证一下。把这个layer名字叫做debug。prototxt上下文.
layer { name: "conv1" type: "Convolution" bottom: "data" top: "conv1" param { lr_mult: 1 } param { lr_mult: 2 } convolution_param { num_output: 20 kernel_size: 5 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } }}layer { name: "debug" type: "My" //virtual inline const char* type() const { return "My"; } 作用 bottom: "conv1" top: "conv1_new" my_layer_param{ pam: 1.5 }}layer { name: "pool1" type: "Pooling" bottom: "conv1_new" top: "pool1" pooling_param { pool: MAX kernel_size: 2 stride: 2 }}
在caffe日志中会出现之前写的debug_layer。
I1116 10:57:36.935508 7338 layer_factory.hpp:77] Creating layer debugI1116 10:57:36.935542 7338 net.cpp:104] Creating Layer debugI1116 10:57:36.935552 7338 net.cpp:505] debug <- conv1I1116 10:57:36.935623 7338 net.cpp:478] debug -> conv1_newI1116 10:57:36.935653 7338 net.cpp:155] Setting up debugI1116 10:57:36.935680 7338 net.cpp:162] Top shape: 100 20 24 24 (1152000)I1116 10:57:36.935712 7338 net.cpp:170] Memory required for data: 9530800
这样就应该可以了 :)
- 从caffe中新增layer(cpp版本)
- caffe-layer.hpp-layer.cpp源代码讲解
- Caffe中Layer注册机制
- caffe中layer层介绍
- Caffe中Layer注册机制
- caffe 中 BatchNorm layer设定
- caffe源码深入学习4:支持魔改的layer:layer.hpp与layer.cpp
- Caffe 不同版本之间layer移植方法
- caffe源码学习中-tools/caffe.cpp
- Caffe中新建Layer--改写Faster-RCNN的proposal layer
- Caffe中新建Layer--改写Faster-RCNN的proposal layer
- caffe layer
- caffe layer
- caffe中增加自己的layer
- caffe中特殊的layer解释
- 在Caffe中使用Python Layer
- Caffe中Layer参数的初始化方式
- 在caffe中添加自定义的layer
- Trapping Rain Water II
- 《嫌疑人X的替身》扑朔迷离的剧情
- 基于大数据分析的安全管理平台技术研究及应用
- 【.Net码农】【NPOI】NPOI对Excel的操作(Sheet转DataTable、List<T>)
- Standard 1.1.x VM与Standard VM的区别
- 从caffe中新增layer(cpp版本)
- 2000: [Hnoi2010]stone 取石头游戏 关于题目数据有质疑
- linux中的文件和文件夹的新建、查询、删除
- c语言小知识点
- 第3讲 微信商城云服务器后台创建
- JS 中的类型转化
- Multiple annotations found at this line
- 二、大话设计模式 之 策略模式
- 获得页面url的某个url参数的方法