(15)caffe总结之自定义Layer的实现
2017-04-22 11:22
316 查看
自定义一个计算层,实现y = x^power + b的功能。
自定义神经层具体可以分成5个步:
1.创建定义的头文件include/caffe/layers/my_neuron_layer.hpp
重新Layer名的方法:virtual inline const char* type() const {return "MyNeuron";}
如果只是需要cpu的方法的话,可以注释掉forward/backward_gpu()这两个方法
2.创建对应src/caffe/src/my_neuron_layer.cpp的源文件
重写方法LayerSetUp,实现能从protoxt读取参数
重写方法Reshape,如果对继承类没有修改的话,就不需要重写
重写方法Forward_cpu
重写方法Backward_cpu(非必须)
*如果要GPU支持,则还需要创建src/caffe/src/my_neuron_layer.cu,同理重写方法Forward_gpu/Backward_gpu(非必须)
3.proto/caffe.proto注册新的Layer
5,重写编译
接下来,我们测试定义的Layer
定义deploy.prototxt
结果:
自定义神经层具体可以分成5个步:
1.创建定义的头文件include/caffe/layers/my_neuron_layer.hpp
重新Layer名的方法:virtual inline const char* type() const {return "MyNeuron";}
如果只是需要cpu的方法的话,可以注释掉forward/backward_gpu()这两个方法
#ifndef CAFFE_MY_NEURON_LAYER_HPP_ #define CAFFE_MY_NEURON_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> class MyNeuronLayer : public NeuronLayer<Dtype> { public: explicit MyNeuronLayer(const LayerParameter& param) : NeuronLayer<Dtype>(param) {} virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top); virtual inline const char* type() const { return "MyNeuron"; } 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); Dtype power_; Dtype b_; }; } // namespace caffe #endif // CAFFE_MY_NEURON_LAYER_HPP_
2.创建对应src/caffe/src/my_neuron_layer.cpp的源文件
重写方法LayerSetUp,实现能从protoxt读取参数
重写方法Reshape,如果对继承类没有修改的话,就不需要重写
重写方法Forward_cpu
重写方法Backward_cpu(非必须)
*如果要GPU支持,则还需要创建src/caffe/src/my_neuron_layer.cu,同理重写方法Forward_gpu/Backward_gpu(非必须)
#include <vector> #include "caffe/layers/my_neuron_layer.hpp" #include "caffe/util/math_functions.hpp" namespace caffe { template <typename Dtype> void MyNeuronLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top){ NeuronLayer<Dtype>::LayerSetUp(bottom,top); power_ = this->layer_param_.my_neuron_param().power(); b_ = this->layer_param_.my_neuron_param().b(); } // Compute y = x^power + b template <typename Dtype> void MyNeuronLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top){ Dtype* top_data = top[0]->mutable_cpu_data(); const int count = bottom[0]->count(); caffe_powx(count, bottom[0]->cpu_data(), Dtype(power_), top_data); for (int i = 0; i < count; ++i) { top_data[i] = top_data[i] + b_; } } template <typename Dtype> void MyNeuronLayer<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(); if(propagate_down[0]){ const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); caffe_powx(count, bottom_data, Dtype(power_ - 1), bottom_diff); caffe_scal(count, Dtype(power_), bottom_diff); caffe_mul(count, bottom_diff, top_diff, bottom_diff); } } INSTANTIATE_CLASS(MyNeuronLayer); REGISTER_LAYER_CLASS(MyNeuron); }// namespace caffe
3.proto/caffe.proto注册新的Layer
message LayerParameter{ ... ++ optional MyNeuronParameter my_neuron_param = 150; ... } ... ++ message MyNeuronParameter{ ++ optional float power = 1 [default = 2]; ++ optional float b = 2 [default = 1]; } ... message V1LayerParameter{ ... ++ MYNEURON = 40; ... }4.my_neuron_layer.cpp添加注册的宏定义
INSTANTIATE_CLASS(MyNeuronLayer); REGISTER_LAYER_CLASS(MyNeuron);如果有my_neuron_layer.cu,则添加
INSTANTIATE_LAYER_GPU_FUNCS(MyNeuronLayer);
5,重写编译
接下来,我们测试定义的Layer
定义deploy.prototxt
name: "CaffeNet" input: "data" input_shape { dim: 1 # batchsize dim: 1 # number of colour channels - rgb dim: 28 # width dim: 28 # height } layer { name: "myneuron" type: "MyNeuron" bottom: "data" top: "data_out" my_neuron_param { power : 2 b : 1 } }运行test_my_neuron.py
import numpy as np import matplotlib.pyplot as plt import os import sys import caffe deploy_file = "./deploy.prototxt" test_data = "./5.jpg" if __name__ == '__main__': net = caffe.Net(deploy_file,caffe.TEST) #加载model 和network #设置图像预处理 transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) #设定图像的格式(1,1,28,28) transformer.set_transpose('data', (2, 0, 1)) #改变维度顺序,由原始图片(28,28,1)变为(1,28,28) img = caffe.io.load_image(test_data,color=False) #读取图片 net.blobs['data'].data[...] = transformer.preprocess('data', img) #执行上面的预处理,并加载到blob中 print net.blobs['data'].data[0][0][14] #打印出原始数据 out = net.forward() //执行测试 print out['data_out'][0][0][14] #打印处理之后的数据
结果:
相关文章推荐
- Caffe学习笔记7--自定义layer的实现
- caffe实现focal loss层的一些理解和对实现一个layer层易犯错的地方的总结
- 用ObjectDataSource实现自定义分页的心得总结
- ActiveReports工作总结12——用Designer控件实现用户自定义报表印刷
- 【iOS开发-24】导航控制器下不同视图控制器之间切换:利用CATrasition和view的layer层来实现自定义的动画效果
- android总结整理----(1)自定义按钮实现
- Android自定义组件系列【15】——四个方向滑动的菜单实现
- ActiveReports工作总结12——用Designer控件实现用户自定义报表印刷
- iOS——自定义Segue实现总结
- Java学习总结15——实现SingleThreadModel,容器不为servlet创建新的实例的问题
- 模块管理常规功能自定义系统的设计与实现(30--第二阶段总结)
- android总结整理----(3)自定义ListView(自定义BaseAdapter实现)
- ActiveReports工作总结12——用Designer控件实现用户自定义报表印刷
- [WinForm ADO.NET实现TaskVision][SQL Server 2008][winform datagridview总结][自定义Custom控件]Winform DataGridView各种现有column及自定义column+Winform自定义控件
- JSP实现自定义标签Taglib重点总结
- 软工总结(15—20)——软件实现
- 【续】用ObjectDataSource实现自定义分页的心得总结,几种分页方法的性能对比
- 实现给Fedora 15的gnome3增加自定义程序快捷方式方法
- Android学习小Demo(15)一个自定义AlertDialog的实现
- iOS开发导航控制器下不同视图控制器之间切换:利用CATrasition和view的layer层来实现自定义的动画效果