赞
踩
当你想实现论文中某个前卫的方法时,caffe中纷繁的网络层模型也不再够用,需要自行定义。同理,你也可以写自己的损失层、数据层和视觉层来加入到网络模型。
我们要实现一个叫NewLayer的新层,这是一个全通层,它并不做任何事情,只是为了方便展示如何加入自定义的网络层。
我们要添加一个新层,要做以下四件事:
使用python接口,需要先编译:
[root@master ]# cd /download/caffe
[root@master ]# make pycaffe
我们不实现GPU功能,所以省略第三步。
在include/caffe/layers中创建头文件:new_layer.hpp
#ifndef CAFFE_HANSS_LAYER_HPP_
#define CAFFE_HANSS_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 NewLayer : public NeuronLayer<Dtype> {
public:
explicit NewLayer(const LayerParameter& param)
: NeuronLayer<Dtype>(param) {}
virtual inline const char* type() const { return "AllPass"; }
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);
};
} // namespace caffe
#endif
在src/caffe/layers中创建实现文件:new_layer.cpp
#include <algorithm>
#include <vector>
#include "caffe/layers/new_layer.hpp"
#include <iostream>
using namespace std;
#define DEBUG_AP(str) cout<<str<<endl
namespace caffe {
template <typename Dtype>
void NewLayer<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();
for (int i = 0; i < count; ++i) {
top_data[i] = bottom_data[i];
}
DEBUG_AP("Here is New Layer's forwarding.");
DEBUG_AP(this->layer_param_.new_param().key());
}
template <typename Dtype>
void NewLayer<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();
for (int i = 0; i < count; ++i) {
bottom_diff[i] = top_diff[i];
}
}
DEBUG_AP("Here is New Layer's backwarding.");
DEBUG_AP(this->layer_param_.new_param().key());
}
#ifdef CPU_ONLY
STUB_GPU(NewLayer);
#endif
INSTANTIATE_CLASS(NewLayer);
REGISTER_LAYER_CLASS(New);
} // namespace caffe
在src/caffe/caffe.proto中添加一些定义内容
注意对照前后代码,添加我写的下面代码里的关于new_layer的代码:
... ...
optional TileParameter tile_param = 138;
optional WindowDataParameter window_data_param = 129;
//mymodel
optional HanssParameter new_param = 155;
}
//mymodel
message NewParameter {
optional float key = 1 [default = 0];
}
// Message that stores parameters used to apply transformation
// to the data layer's data
message TransformationParameter {
... ...
然后记得重新编译caffe与pycaffe!
最后,写一个网络测试,我只写这个网络层及其它前后两个:
layer {
name: "ip1"
type: "InnerProduct"
bottom: "data"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 50
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "drop1"
type: "Dropout"
bottom: "ip1"
top: "ip1"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
name: "newLayer"
type: "Hanss"
bottom: "ip1"
top: "newLayer"
hanss_param {
key: 12.88
}
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "newLayer"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 50
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "drop2"
type: "Dropout"
bottom: "ip2"
top: "ip2"
dropout_param {
dropout_ratio: 0.4
}
}
完成,运行即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。