Caffe中Layer_factory详解

原创 2015年12月21日 17:54:58

Layer_factory.hpp

Layer_factory的主要作用是负责Layer的注册,已经注册完事的Layer在运行时可以通过传递一个 LayerParameterCreaterLayer 函数的方式来调用:

LayerRegistry::CreateLayer(param);//可以参考net.cpp 中的调用方法

假设有一个如下的Layer:

template <typename Dtype>
class MyAwesomeLayer : public Layer<Dtype> {
  // your implementations
};

它的type就是C++类名,除去后缀”Layer”:

(“MyAwesomeLayer” -> “MyAwesome”).

我们可以通过以下两种方式来注册一个Layer:

只有一个构造函数

如果这个Layer只能通过它的构造函数来创建的话,在对应的C++文件里面加入以下行就行:

REGISTER_LAYER_CLASS(MyAwesome);

有可选的构造函数

如果这个Layer还可以通过另外一个如下形式的构造函数构造:

template <typename Dtype>
 Layer<Dtype*> GetMyAwesomeLayer(const LayerParameter& param) {
   // your implementation
 }

具体可以参考GetConvolutionLayer,Layer_factory.cpp。
这种情况下,我们可以通过注册构造函数的方式来进行Layer的注册:

REGISTER_LAYER_CREATOR(MyAwesome, GetMyAwesomeLayer)

注意:每一个Layer type 只允许注册一次

具体实现细节可以参考layer_factory.hpp的源码,我随后会尽可能详细的给出我的理解和注释


#ifndef CAFFE_LAYER_FACTORY_H_
#define CAFFE_LAYER_FACTORY_H_
#include <map>
#include <string>

#include "caffe/common.hpp"
#include "caffe/proto/caffe.pb.h"

namespace caffe {

template <typename Dtype>
class Layer;

template <typename Dtype>
class LayerRegistry {
 public:
  typedef shared_ptr<Layer<Dtype> > (*Creator)(const LayerParameter&);
  typedef std::map<string, Creator> CreatorRegistry;

  static CreatorRegistry& Registry() {
    static CreatorRegistry* g_registry_ = new CreatorRegistry();
    return *g_registry_;
  }

  // Adds a creator.
  static void AddCreator(const string& type, Creator creator) {
    CreatorRegistry& registry = Registry();
    CHECK_EQ(registry.count(type), 0)
        << "Layer type " << type << " already registered.";
    registry[type] = creator;
  }

  // Get a layer using a LayerParameter.
  static shared_ptr<Layer<Dtype> > CreateLayer(const LayerParameter& param) {
    LOG(INFO) << "Creating layer " << param.name();
    const string& type = param.type();
    CreatorRegistry& registry = Registry();
    CHECK_EQ(registry.count(type), 1) << "Unknown layer type: " << type
        << " (known types: " << LayerTypeList() << ")";
    return registry[type](param);
  }

 private:
  // Layer registry should never be instantiated - everything is done with its
  // static variables.
  LayerRegistry() {}

  static string LayerTypeList() {
    CreatorRegistry& registry = Registry();
    string layer_types;
    for (typename CreatorRegistry::iterator iter = registry.begin();
         iter != registry.end(); ++iter) {
      if (iter != registry.begin()) {
        layer_types += ", ";
      }
      layer_types += iter->first;
    }
    return layer_types;
  }
};


template <typename Dtype>
class LayerRegisterer {
 public:
  LayerRegisterer(const string& type,
                  shared_ptr<Layer<Dtype> > (*creator)(const LayerParameter&)) {
    // LOG(INFO) << "Registering layer type: " << type;
    LayerRegistry<Dtype>::AddCreator(type, creator);
  }
};


  #define REGISTER_LAYER_CREATOR(type, creator)                                \
  static LayerRegisterer<float> g_creator_f_##type(#type, creator<float>);     \
  static LayerRegisterer<double> g_creator_d_##type(#type, creator<double>)    \

  #define REGISTER_LAYER_CLASS(type)                                           \
  template <typename Dtype>                                                    \
  shared_ptr<Layer<Dtype> > Creator_##type##Layer(const LayerParameter& param) \
  {                                                                            \
    return shared_ptr<Layer<Dtype> >(new type##Layer<Dtype>(param));           \
  }                                                                            \
  REGISTER_LAYER_CREATOR(type, Creator_##type##Layer)

}  // namespace caffe

#endif  // CAFFE_LAYER_FACTORY_H_

未完待续。。。。

caffe增加自己的layer实战(下-续1)--caffe学习(13)

接上篇:caffe增加自己的layer实战(下)–caffe学习(12) 构造完函数后我们就要进入proto目录。编辑caffe.proto文件,构造我们的video_data_layer的输入参数...
  • u014381600
  • u014381600
  • 2017年01月09日 15:49
  • 1268

使用Caffe 增加自定义 Layer 及其 ProtoBuffer 参数

在使用 Caffe 过程中经常会有这样的需求:已有 Layer 不符合我的应用场景;我需要这样这样的功能,原版代码没有实现;或者已经实现但效率太低,我有更好的实现。 方案一:简单粗暴...
  • king16304
  • king16304
  • 2016年10月09日 09:46
  • 3324

【深夜福利】Caffe 增加自定义 Layer 及其 ProtoBuffer 参数

在飞驰的列车上,无法入眠。外面阴雨绵绵,思绪被拉扯到天边。翻看之前聊天,想起还欠一个读者一篇博客。于是花了点时间整理一下之前学习 Caffe 时增加自定义 Layer 及自定义 ProtoBuffer...
  • kkk584520
  • kkk584520
  • 2016年10月02日 03:17
  • 13219

梳理caffe代码layer_factory

//工厂模式 #include "stdafx.h" #include #include using namespace std; class Product { public: virtual ...
  • gaoenyang760525
  • gaoenyang760525
  • 2017年06月04日 12:53
  • 147

caffe源码追踪--layer_factory

关于怎么注册层,caffe提供了两种方式: (1)只有一个构造函数时,在cpp文件最后加上 REGISTER_LAYER_CLASS(MyAwesome); 即可 (2)若是还有如下形...
  • little_sun_123
  • little_sun_123
  • 2017年08月09日 15:35
  • 128

caffe代码layer_factory梳理分析

因为前一篇描述的是layer层,其实应该先学习工厂模式,最早我也学习过了23中模式设计,不熟悉这个模式的可以看一下下面这段代码。   ? 1 2 ...
  • ZhikangFu
  • ZhikangFu
  • 2016年11月10日 16:57
  • 422

Caffe--layer.cpp 与 layer_factory.cpp源码阅读

1 导读Layer是网络的基本单元(“积木”),由此派生出了各种层类。如果做数据特征表达相关的研究,需要修改这部分。Layer类派生出来的层类通过这 实现两个虚函数Forward()和Backward...
  • daska110
  • daska110
  • 2017年04月23日 11:37
  • 297

Caffe实例开发学习笔记。——网络配置文件 Layer参数详解——

(caffe/example/mnist/lenet_train_test.prototxt) 数据层 (caffe一般将数据做成数据库的形式,读取速度快,匹配cpu读取跟GPU运算) Ø so...
  • yxr403614258
  • yxr403614258
  • 2017年07月07日 10:56
  • 137

caffe下relu_layer.cu详解

relu_layer是caffe框架的一个线性激活单元,具体功能、作用、和c++代码我不做详细分析,相信有点c++基础和深度学习基础的孩子都能看懂,今天我来详细分析relu_layer.cu文件,因为...
  • aizenggege
  • aizenggege
  • 2017年05月18日 19:22
  • 334

梳理caffe代码conv_layer(十九)

前面的基类理解了,这个比较简单了。 conv_layer.cpp: #include #include "caffe/layers/conv_layer.hpp" namespace caf...
  • langb2014
  • langb2014
  • 2016年06月04日 12:02
  • 2499
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Caffe中Layer_factory详解
举报原因:
原因补充:

(最多只允许输入30个字)