-
Notifications
You must be signed in to change notification settings - Fork 283
Framework Extension Guide on User Defined Layers
This is an example to show how to extend FeatherCNN by adding a new user-defined layer or new implementation for exist layer. In the following, we illustrate necessary steps to show how we extend FeatherCNN to support an user-defined filter Layer.
Given c input channels, Filter layer is defined to filter m (m<=c) input channels as the output channels. The weights for this layer is consisted with c float numbers, which will contain m 1s, and all the rest will be 0s.
Define your layer in Caffe (.prototxt) and train to get the weights in caffemodel. Finally get the user.protocol, user.caffemodel Ready.
- Install protobuf first.
- Download flatbuffer from https://github.com/google/flatbuffers/releases, then compile it with the following commands:
mkdir build
cd build
cmake ..
make install
flatc will be generated in build directory.
flatc --proto user.prototxt feather_simple.fbs
flatc --cpp feather_simple.fbs
mv feather_simple_generated.h ../src/
The new head file feather_simple_generated.h will be regenerated with parameter definitions for user-defined filter layer.
- Update flatbuffer header files in ./src/flatbuffers/
Add filter_layer.h and filter_layer.cpp into src/layers directory. As in filter_layer.h, each layer provides 3 functions except a constructor function:
int GenerateTopBlobs();
int Forward();
int Init();
and some private variables to hold user defined parameters.
int num_output;
float* select_weights;
All implementations should go to filter_layer.cpp. -Parameters and weights initialization can be implemented in Init():
select_weights = _weight_blobs[0]->data();
const Blob<float>* bottom_blob = _bottom_blobs[_bottom[0]];
size_t channels = bottom_blob->channels();
-After initialization, each layer should generate its top blobs first:
const Blob<float>* bottom_blob = _bottom_blobs[_bottom[0]];
size_t num = bottom_blob->num();
size_t channels = num_output;
size_t height = bottom_blob->height();
size_t width = bottom_blob->width();
_top_blobs[_top[0]] = new Blob<float>(num, channels, height, width);
_top_blobs[_top[0]]->Alloc();
-Then the layer operation can be implement in the forward function. Details can be refer to https://github.com/Tencent/FeatherCNN/blob/master/src/layers/filter_layer.cpp
Remember to regist filter layer in line 138 and 160 in https://github.com/Tencent/FeatherCNN/blob/master/src/layer_factory.cpp
Layer *GetFilterLayer(const LayerParameter *layer_param, const RuntimeParameter<float> * rt_param)
{
return (Layer *)new FilterLayer(layer_param, rt_param);
}
REGISTER_LAYER_CREATOR(Filter, GetFilterLayer);
- Building the project
./build_scripts/build_linux.sh
./build_scripts/build_linux_test.sh
Test FeatherCNN with filter layer:
./feather_benchmark ./filter.feathermodel ./line_3_224_224.txt 10 1