1. 程式人生 > >caffe原始碼分析-layer_factory

caffe原始碼分析-layer_factory

caffe中有許多的layer,在net中建立連線layer是通過工廠模式的方式建立,而不是每一個new然後連線。在net.cpp中建立layer方式如下:

layers_.push_back(LayerRegistry<Dtype>::CreateLayer(layer_param));

下面簡要分析下layer_factory


template<typename Dtype>
class LayerRegistry{
public:
    // 函式指標Creator,返回Layer<Dtype>指標
    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(); LOG(INFO) << "AddCreator: " << type; registry[type] = creator; } // Get a layer using a LayerParameter. static shared_ptr<Layer<Dtype> > CreateLayer
(const LayerParameter& param) { const string& type = param.type(); CreatorRegistry& registry = Registry(); CHECK_EQ(registry.count(type), 1) << "Unknown layer type: "; return registry[type](param); } private: // Layer registry should never be instantiated // everything is done with its static variables. LayerRegistry() {} };

結合巨集定義以及模板特化建立的對應的註冊類:


template <typename Dtype>
class LayerRegisterer {
public:
    LayerRegisterer(const string& type,
                  shared_ptr<Layer<Dtype>>(*creator)(const LayerParameter&))
    {
        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)
    
}

使用如下,例如輸入層:


INSTANTIATE_CLASS(InputLayer);
REGISTER_LAYER_CLASS(Input);