# How to create a custom Caffe layer in Python? This tutorial will guide through the steps to create a simple custom layer for Caffe using python. By the end of it, there are some examples of custom layers. ###- Why would I want to do that? Usually you would create a custom layer to implement a funcionality that isn't available in Caffe, tuning it for your requirements. ###- What will I need? Python and Caffe instaled and a sample layer template (provided bellow) so you can customize it. ##Layer Template ```python import caffe class My_Custom_Layer(caffe.Layer): def setup(self, bottom, top): pass def forward(self, bottom, top): pass def reshape(self, bottom, top): pass def backward(self, bottom, top): pass ``` So important things to remember: - Your custom layer has to inherit from **caffe.Layer** (so don't forget to *import caffe*); - You must define the four following methods: **setup**, **forward**, **reshape** and **backward**; - All methods have a *top* and a *bottom* parameters, which are the blobs that store the input and the output passed to your layer. You can access it using *top[i].data* or *bottom[i].data*, where *i* is the index of the blob in case you have more than one upper or lower blob. ###- Setup method The Setup method is called once during the lifetime of the execution, when Caffe is instantiating all layers. This is where you will read parameters, instantiate fixed-size buffers. ###- Reshape method Use the reshape method for initialization/setup that depends on the bottom blob (layer input) size. It is called once for each batch. ###- Forward method The Forward method is called for each input batch and is where most of your logic will be. ###- Backward method The Backward method is called during the backward pass of the network. For example, in a convolution-like layer, this would be where you would calculate the gradients. This is optional (a layer can be forward-only). ##Prototxt Template Ok, so now you have your layer designed! This is how you define it in your *.prototxt* file: ``` layer { name: "LayerName" type: "Python" top: "TopBlobName"  bottom: "BottomBlobName"  python_param { module: "My_Custom_Layer_File" layer: "My_Custom_Layer_Class"    param_str: '{"param1": 1,"param2":True, "param3":"some string"}' } include{ phase: TRAIN } } ``` Important remarks: - **type** must be **Python**; - You must have a **python_param** dictionary with at least the **module** and **layer** parameters; - **module** refers to the file where you implemented your layer; - **layer** refers to the name of your class; - You can pass parameters to the layer using **param_str** (more on accessing them bellow); - Just like any other layer, you can define in which phase you want it to be active (see the examples to see how you can check the current phase); ##Passing Parameters to the layer You can define the layer parameters in the prototxt by using *param_str*. Once you've done it, here is an example on how you access these paremeters inside the layer class: ```python def setup(self, bottom, top): params = eval(self.param_str)    param1 = params["param1"] param2 = params.get('param2', False) #I usually use this when fetching a bool param3 = params["param3"] #Continue with the setup # ... ```