caffe原始碼分析-layer_factory
阿新 • • 發佈:2018-12-13
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);