Skip to content

Framework Extension Guide on User Defined Layers

Jintao Meng edited this page Jun 20, 2018 · 2 revisions

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.

Prepare User Defined Network.

Define your layer in Caffe (.prototxt) and train to get the weights in caffemodel. Finally get the user.protocol, user.caffemodel Ready. 

Prerequisites

  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 user defined layer code into FeatherCNN framework

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

Layer Register

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