caffe原始碼解析 層(layer)的註冊與管理

2021-08-28 15:25:23 字數 2765 閱讀 4234

caffe中所有的layer都是類的結構,它們的構造相關的函式都註冊在乙個全域性變數g_registry_ 中。

首先這個變數的型別 creatorregistry是乙個map定義,

public:

typedef shared_ptr> (*creator)(const layerparameter&);

typedef std::mapcreatorregistry;

注意creator會根據資料型別(如float,double)的不同而不同,

該定義對應的變數是g_registry_(實際是對應float有乙個,對應double有乙個)

層的註冊函式是通過下邊這個registry() 函式實現的,

static creatorregistry& registry()
注意static 這個關鍵字,這是乙個靜態結構,在caffe程式啟動時(通過register_layer_class(……)這個巨集)建立g_registry_ ,(因為是static,所以只在建立時執行一次),以後各個層通過register_layer_class(……)這個巨集呼叫時,返回的是註冊到g_registry_的具體的層。

當然我們可以看一眼這個巨集定義,

template class layerregisterer 

};#define register_layer_creator(type, creator) \

static layerregistererg_creator_f_##type(#type, creator); \

static layerregistererg_creator_d_##type(#type, creator) \

#define register_layer_class(type) \

template \

shared_ptr> creator_##type##layer(const layerparameter& param) \

\register_layer_creator(type, creator_##type##layer)

} // namespace caffe

比如對absval層,register_layer_class 這個巨集首先定義了乙個creator_absvallayer函式,然後通過巨集

register_layer_creator(type, creator_absvallayer)定義了乙個layerregisterer(實際是兩個layerregisterer,根據資料型別是float還是double,各定義了乙個)靜態例項,這個定義相當根據資料型別於立即執行了

addcreateor("convolution", creator_absvallayer)這個函式,

// adds a creator.

static void addcreator(const string& type, creator creator)

也就是把這個creator_absvallayer函式註冊到陣列

registry["convolution"] = creator_absvallayer;

如果我們把最終所有類的註冊展開的話,會是下面的形式(注意這個是對應資料型別為float的registry,對應資料型別為double的也有乙個同樣結構的registery)

在構造網路時,net::init函式中的for迴圈會根據網路的型別逐層構建,通過

layers_.push_back(layerregistry::createlayer(layer_param));

呼叫

// get a layer using a layerparameter.

static shared_ptr> createlayer(const layerparameter& param)

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);

}

完成這個layer的建設工作。當然,取決於不同的層,呼叫函式是不同的,例如對convolution層,呼叫函式是

shared_ptr> getconvolutionlayer(const layerparameter& param)

以absval為例,這個createlayer先是得到型別type=「absval」,然後得到registry也就該類對應的註冊資訊,最後通過registry[type](param)例項化absval這個類。

另外,值得注意的一點是,像convolution這樣不能直接自己構造的類(因為有gpu和cpu模式),註冊的建構函式有所不同,如

register_layer_creator(convolution, getconvolutionlayer);

caffe原始碼解析

目錄目錄 簡單介紹 主要函式readprotofromtextfile 函式 writeprotototextfile 函式 readprotofrombinaryfile 函式 writeprototobinaryfile 函式 readimagetocvmat 函式 matchext 函式 cv...

caffe原始碼 卷積層

input 3 5 5 c h w pading 1 步長 2 卷積核 2 3 3 3 n c k k output 2 3 3 c h w 如下圖所示 首先需要理解caffe裡面的im2col和col2im 然後 卷積層 其實和 全連線層 差不多了 input 3 4 4 c h w 卷積核 1 ...

caffe原始碼解析 一

用si載入 後 首先從caffe layer的實現看起,不同框架下最大的差異就在於層的實現也決定了層的靈活性 layer可以看成是乙個基類,下面存在data layer,activation neuron layers,vision layer,common layers,loss layer,各個...