关于怎么注册层,caffe提供了两种方式:
(1)只有一个构造函数时,在cpp文件最后加上
REGISTER_LAYER_CLASS(MyAwesome);
即可
(2)若是还有如下形式的构造函数
template
Layer
#ifndef CAFFE_LAYER_FACTORY_H_
#define CAFFE_LAYER_FACTORY_H_
#include <map>
#include <string>
#include <vector>
#include "caffe/common.hpp"
#include "caffe/layer.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&);//函数指针Creator指向输入为层参数,返回类型为Layer<Dtype>指针
typedef std::map<string, Creator> CreatorRegistry;//map存储Creator和层类型,将层类型和Creator句柄联系起来,通过类型可以调用相应的前向和后向计算.
static CreatorRegistry& Registry() {
//获取注册表,static只创建一个实例
static CreatorRegistry* g_registry_ = new CreatorRegistry();
return *g_registry_;
}
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;
}
static shared_ptr<Layer<Dtype> > CreateLayer(const LayerParameter& param) {
//根据层参数来创建层,在net中就是通过调用这个函数来建楼的
if (Caffe::root_solver()) {
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: " << LayerTypeListString() << ")";
return registry[type](param);
}
static vector<string> LayerTypeList() {
//获取所注册过的层类型列表
CreatorRegistry& registry = Registry();
vector<string> layer_types;
for (typename CreatorRegistry::iterator iter = registry.begin();
iter != registry.end(); ++iter) {
layer_types.push_back(iter->first);
}
return layer_types;
}
private:
LayerRegistry() {}//禁止实例化
static string LayerTypeListString() {
//获取所注册过的层类型列表(上面是向量,这里是字符串)
vector<string> layer_types = LayerTypeList();
string layer_types_str;
for (vector<string>::iterator iter = layer_types.begin();
iter != layer_types.end(); ++iter) {