Create new layer in caffe

1. Problem

I want to design my own layer in caffe.

In my opinion, layer is kernel in caffe, even in deep learning. It represents a universal-computing framework.

A lot of algorithms can be represented in this form. So design layer is a must-skill.

2. Solution

Two things need to do:
1. Add layer parameter in src/caffe/caffe.proto
2. Create layer.hpp, layer.cpp, layer.cu

2.1 caffe.proto

message DuinoParameter {
  optional float bias = 1;
}

All layer parameter is called via LayerParameter. We need to add DuinoParameter to LayerParameter.

message LayerParameter{
  ...
  optional DuinoParameter duino_param = 147;
}

Number 147 should occur only once.

Since we change caffe.proto, we need to update caffe.pb.h and caffe.pb.cc

cd src/caffe/proto/
protoc caffe.proto --cpp_out=../../../include/caffe/proto --python_out=../../../python/caffe/proto

2.2 Create .hpp, .cpp, .cu

touch include/layers/duino_layer.hpp src/layers/duino_layer.cpp src/layers/duino_layer.cu

duino_layer.hpp

#ifndef CAFFE_DUINO_LAYER_HPP_
#define CAFFE_DUINO_LAYER_HPP_

#include <vector>

#include "caffe/blob.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"

#include <string>

namespace caffe{

template <typename Dtype>
class DuinoLayer : public Layer<Dtype> {
public:
    explicit DuinoLayer(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 "Duino"; }
    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>*>& bottom, 
            const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& top);
    virtual void Backward_gpu(const vector<Blob<Dtype>*>& bottom, 
            const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& top);
};

}

#endif

About these functions, caffe official site gives a brief explanation.

duino_layer.cpp

#include <vector>

#include "caffe/layers/duino_layer.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe{

template <typename Dtype>
void DuinoLayer<Dtype>::LayerSetup(const vector<Blob<Dtype>*>& bottom,
                                   const vector<Blob<Dtype>*>& top)
{
}

template <typename Dtype>
void DuinoLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
                                const vector<Blob<Dtype>*>& top){}

template <typename Dtype>
void DuinoLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
                                    const vector<Blob<Dtype>*>& top)
{
    // get input and output data
    const Dtype* bottom_data = bottom[0]->cpu_data();
    Dtype* top_data = top[0]->mutable_cpu_data();
    const int count = bottom[0]->count();
    // get parameter
    Dtype bias = this->layer_param_.duino_param().bias();
    // compute
    for (int i = 0; i < count; ++i){
        top_data[i] = bottom_data[i] + bias;
    }
}

template <typename Dtype>
void DuinoLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& bottom,
                                     const vector<bool>& propagate_down,
                                     const vector<Blob<Dtype>*>& top){}

INSTANTIATE_CLASS(DuinoLayer);
REGISTER_LAYER_CLASS(Duino);
}

duino_layer.cu

#include <vector>

#include "caffe/layers/duino_layer.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe{

template <typename Dtype>
void DuinoLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
                                    const vector<Blob<Dtype>*>& top){}

template <typename Dtype>
void DuinoLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& bottom,
                                     const vector<bool>& propagate_down,
                                     const vector<Blob<Dtype>*>& top){}

INSTANTIATE_LAYER_GPU_FUNCS(DuinoLayer);

}

3. Test

Use in lenet.proto

name: "Lenet"
...
layer {
  name: "duino1"
  type: "Duino"
  bottom: "ip2"
  top: "ip2"
  duino_param {
    bias: 1
  }
}
...

Use train_lenet.sh to train LeNet.

Done.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值