1. 程式人生 > >caffe中新增自定義的layer

caffe中新增自定義的layer

有兩種方式,一種是使用python layer相對簡單,另一種是使用C++。

1.python layer

參考 http://chrischoy.github.io/research/caffe-python-layer/

layer {
  type: 'Python'
  name: 'loss'
  top: 'loss'
  bottom: 'ipx'
  bottom: 'ipy'
  python_param {
    # the module name -- usually the filename -- that needs to be in $PYTHONPATH
    module: 'pyloss'
    # the layer name -- the class name in the module
    layer: 'EuclideanLossLayer'
  }
  # set loss weight so Caffe knows this is a loss layer
  loss_weight: 1
}

module的名字就是自定義的layer的python檔案的檔名,比如上面的新檔案就是pyloss.py,檔案需在$PYTHONPAT路徑下。layer的名字就是新定義的類名,比如上面的類名就是EuclideanLossLayer。該類一般必須包含四個函式,分別是setup、reshape、forword、backword

下面是示例,解釋python層該怎麼寫。建立pyloss.py,並定義EuclideanLossLayer

import caffe
import numpy as np
class EuclideadLossLayer(caffe.Layer):#EuclideadLossLayer沒有權值,反向傳播過程中不需要進行權值的更新。如果需要定義需要更新自身權值的層,最好還是使用C++
       def setup(self,bottom,top):
           #在網路執行之前根據相關引數引數進行layer的初始化
           if len(bottom) !=2:
              raise exception("Need two inputs to compute distance")
       def reshape(self,bottom,top):
           #在forward之前呼叫,根據bottom blob的尺寸調整中間變數和top blob的尺寸
           if bottom[0].count !=bottom[1].count:
              raise exception("Inputs must have the same dimension.")
           self.diff=np.zeros_like(bottom[0].date,dtype=np.float32)
           top[0].reshape(1)
       def forward(self,bottom,top):
           #網路的前向傳播
            self.diff[...]=bottom[0].data-bottom[1].data
            top[0].data[...]=np.sum(self.diff**2)/bottom[0].num/2.
       def backward(self,top,propagate_down,bootm):
            #網路的前向傳播
             for i in range(2):
                 if not propagate_down[i]:
                         continue
                 if i==0:
                    sign=1
                 else:
                    sign=-1
                  bottom[i].diff[...]=sign*self.diff/bottom[i].num

2.C++方式

參考

https://github.com/BVLC/caffe/issues/684 

https://chrischoy.github.io/research/making-caffe-layer/


Here's roughly the process I follow.

  1. Add a class declaration for your layer to the appropriate one of common_layers.hppdata_layers.hpp,loss_layers.hppneuron_layers.hpp
    , or vision_layers.hpp. Include an inline implementation oftype and the *Blobs() methods to specify blob number requirements. Omit the *_gpu declarations if you'll only be implementing CPU code.
  2. Implement your layer in layers/your_layer.cpp.
    • SetUp for initialization: reading parameters, allocating buffers, etc.
    • Forward_cpu for the function your layer computes
    • Backward_cpu for its gradient
  3. (Optional) Implement the GPU versions Forward_gpu and Backward_gpu in layers/your_layer.cu.
  4. Add your layer to proto/caffe.proto, updating the next available ID. Also declare parameters, if needed, in this file.
  5. Make your layer createable by adding it to layer_factory.cpp.
  6. Write tests in test/test_your_layer.cpp. Use test/test_gradient_check_util.hpp to check that your Forward and Backward implementations are in numerical agreement.