Caffe学习之自定义创建新的Layer层
来源:互联网 发布:python写淘宝秒杀脚本 编辑:程序博客网 时间:2024/06/06 06:35
caffe源码中已经帮我封装好了各种各样的layer,但是有时候现有的layer不能满足设计的网络要求,这个时候需要自己定义一个新的layer,本文参考here,进行简单讲解,具体方式如下:
一.创建.hpp文件
1.添加你的layer头文件置于 include/caffe/layers/ 下,比如include/caffe/layers/your_layer.hpp
2.your_layer继承选择继承layer.hpp, common_layers.hpp, data_layers.hpp, loss_layers.hpp, neuron_layers.hpp, 或者 vision_layers.hpp其中一种
3.重写
virtual inline const char* type() const { return "YourLayerName"; }
函数,这个的目的是为了在写net.prototxt时,layer{type:"YourLayerName"}
有所对应4.根据自己layer的需要,对{*}blob部分方法进行重写,以此来限制bottom和top的blob个数。比如 要是重写了
virtual inline int ExactNumBottomBlobs() const { return 1; }
就表示限制bottom的blob为15.申明
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top);
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);
6.要是需要GPU加速,则需申明:
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);
7.其他(根据算法需要的函数以及参数)
可以在/caffe/include/caffe/下找到许多对应的例子,比如inner_product_layer.hpp:
#ifndef CAFFE_INNER_PRODUCT_LAYER_HPP_#define CAFFE_INNER_PRODUCT_LAYER_HPP_#include <vector>#include "caffe/blob.hpp"#include "caffe/layer.hpp"#include "caffe/proto/caffe.pb.h"namespace caffe {/** * @brief Also known as a "fully-connected" layer, computes an inner product * with a set of learned weights, and (optionally) adds biases. * * TODO(dox): thorough documentation for Forward, Backward, and proto params. */template <typename Dtype>class InnerProductLayer : public Layer<Dtype> { public: explicit InnerProductLayer(const LayerParameter& param) : Layer<Dtype>(param) {} virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual void Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual inline const char* type() const { return "InnerProduct"; } virtual inline int ExactNumBottomBlobs() const { return 1; } virtual inline int ExactNumTopBlobs() const { return 1; } 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); int M_; int K_; int N_; bool bias_term_; Blob<Dtype> bias_multiplier_; bool transpose_; ///< if true, assume transposed weights};} // namespace caffe#endif // CAFFE_INNER_PRODUCT_LAYER_HPP_
二.创建对应的.cpp文件
1 添加你的源文件置于 src/caffe/layers/下,比如 src/caffe/layers/your_layer.cpp
2.实现LayerSetUp方法(在这里你可以读取layer的参数,权重进行初始化等等),该方法在layer::SetUp时候被调用,用于layer的初始化
3.实现Reshape 方法,根据bottom的shape,修改top的shape等等,也是在layer::SetUp时候被调用,用于layer的初始化
4.实现Forward_cpu和Backward_cpu 方法,前向传播计算loss和top,反向传播计算diff(梯度)
5.在文件末尾加上这两行代码(XXXLayer表示layer的类名),以此在fayer_factory.hpp中注册了此layer以便于运行时的统一创建
INSTANTIATE_CLASS(XXXLayer);
REGISTER_LAYER_CLASS(XXX);
具体例子可参考here
三.创建.cu文件
1.如果需要gpu加速的话,那么你需要在src/caffe/layers/下创建.cu文件,比如src/caffe/layers/your_layer.cu
2.采用cuda语言编程,实现Forward_gpu和Backward_gpu方法,和.cpp文件中Forward_cpu和Backward_cpu 方法实现类似,需要把所有的cpu字样改成gpu
具体例子参考here
四.在caffe.proto添加your_layer的message
1.如果想要在net.prototxt中设置你的layer的参数的话,你需要在caffe.proto中定义,定义好之后,即可在forward或者backward的方法中获取到参数值,进行其他相关运算
一个简单的例子(InnerProductLayer )如下:
message InnerProductParameter { optional uint32 num_output = 1; // The number of outputs for the layer optional bool bias_term = 2 [default = true]; // whether to have bias terms optional FillerParameter weight_filler = 3; // The filler for the weight optional FillerParameter bias_filler = 4; // The filler for the bias // The first axis to be lumped into a single inner product computation; // all preceding axes are retained in the output. // May be negative to index from the end (e.g., -1 for the last axis). optional int32 axis = 5 [default = 1]; // Specify whether to transpose the weight matrix or not. // If transpose == true, any operations will be performed on the transpose // of the weight matrix. The weight matrix itself is not going to be transposed // but rather the transfer flag of operations will be toggled accordingly. optional bool transpose = 6 [default = false];}
2.与此同时,在caffe.proto 的message LayerParameter中添加对应的消息,同时更新一下注释,表明下一个可用的数字大小,比如:
// LayerParameter next available layer-specific ID: 117 (last added: inner_product_param )message LayerParameter {......... optional InnerProductParameter inner_product_param = 117;.........}
五.编译
最后重新编译一下caffe代码即可
CAFFE_ROOT$make cleanmake all
- Caffe学习之自定义创建新的Layer层
- caffe 添加YOLO新层Leaky Layer
- caffe学习系列三添加新的Layer
- caffe源码解析之添加新的Layer(maxout)
- Caffe python layer 的自定义
- Caffe python layer 的自定义
- 【caffe学习笔记】loss layer 损失层
- 【caffe学习笔记】layer层简介
- caffe源码解析之Layer层(1)
- caffe源码解析之Layer层(1)
- Caffe学习笔记7--自定义layer的实现
- 深度学习笔记(1):caffe 添加新层 attention LSTM layer和LSTM layer代码精读
- (15)caffe总结之自定义Layer的实现
- caffe 追加新层new layer添加.cu文件问题--无法解析的外部符号
- caffe 的layer层组织结构
- [转]caffe中添加C++的自定义新层
- Caffe:Layer的相关学习
- caffe layer层详解
- 2.韦东山嵌入式学习内存
- 套接字编程原理及例程
- 被解放的姜戈01 初试天涯
- 接口设计
- 事务
- Caffe学习之自定义创建新的Layer层
- Spring中ApplicationContextAware接口的用法
- 计数排序
- 【妙算使用笔记】Linux学习笔记—— 浅谈关于妙算GPIO的使用
- 1030-Got error 28 from storage engine
- select函数的单进程和TCP回射服务器应用模型
- python中的type()和isinstance()
- Log4j之HelloWorld
- Hadoop基础教程-第8章 Zookeeper(8.5 Zookeeper内存数据库)(草稿)