caffe中的“Python”层是什么?

Caffe有一个图层类型“Python”.

例如,该层类型可以用作loss layer.
在其他情况下,它被用作input layer.

这层类型是什么?
如何使用这一层?

解决方法:

PruneBharat的答案给出了“Python”层的总体目的:在python而不是c中实现的通用层.

我打算将这个答案作为使用“Python”层的教程.

“Python”图层教程

什么是“Python”图层?

请参阅PruneBharat的优秀答案.

先决条件

为了使用’Python’层,你需要用flag编译caffe

WITH_PYTHON_LAYER := 1

在’Makefile.config’中设置.

如何实现“Python”层?

“Python”层应该实现为从caffe.Layer基类派生的python类.该类必须具有以下四种方法:

import caffe
class my_py_layer(caffe.Layer):
  def setup(self, bottom, top):
    pass

  def reshape(self, bottom, top):
    pass

  def forward(self, bottom, top):
    pass

  def backward(self, top, propagate_down, bottom):
    pass

这些方法是什么?

def setup(self,bottom,top):当caffe构建网络时,此方法被调用一次.此函数应检查输入数量(len(底部))和输出数量(len(顶部))是否符合预期.
您还应该在此处分配网络的内部参数(即self.add_blobs()),有关详细信息,请参阅this thread.
此方法可以访问self.param_str – 从原型文本传递到图层的字符串.有关更多信息,请参见this thread.

def reshape(self,bottom,top):只要caffe重塑网络,就会调用此方法.此函数应分配输出(每个顶部blob).输出的形状通常与底部的形状有关.

向前(自我,底部,顶部):从下到上实施前进传球.

def向后(self,top,propagate_down,bottom):此方法实现反向传播,它从顶部到底部传播渐变. propagate_down是len(底部)的布尔向量,指示渐变应该传播到哪个底部.

您可以在this post找到有关底部和顶部输入的更多信息.

例子
您可以看到简化的python层here,herehere的一些示例.
可以在here找到“移动平均”输出层的示例.

可训练的参数
“Python”层可以具有可训练的参数(如“Conv”,“InnerProduct”等).
您可以在this threadthis one中找到有关添加可训练参数的更多信息.在caffe git中还有一个非常简化的示例.

如何在原型文件中添加“Python”图层?

有关详细信息,请参阅Bharat的答案.
您需要将以下内容添加到您的原型文本中:

layer {
  name: 'rpn-data'
  type: 'Python'  
  bottom: 'rpn_cls_score'
  bottom: 'gt_boxes'
  bottom: 'im_info'
  bottom: 'data'
  top: 'rpn_labels'
  top: 'rpn_bbox_targets'
  top: 'rpn_bbox_inside_weights'
  top: 'rpn_bbox_outside_weights'
  python_param {
    module: 'rpn.anchor_target_layer'  # python module name where your implementation is
    layer: 'AnchorTargetLayer'   # the name of the class implementation
    param_str: "'feat_stride': 16"   # optional parameters to the layer
  }
}

如何使用pythonic NetSpec接口添加“Python”图层?

这很简单:

import caffe
from caffe import layers as L

ns = caffe.NetSpec()
# define layers here...
ns.rpn_labels, ns.rpn_bbox_targets, \
  ns.rpn_bbox_inside_weights, ns.rpn_bbox_outside_weights = \
    L.Python(ns.rpn_cls_score, ns.gt_boxes, ns.im_info, ns.data, 
             name='rpn-data',
             ntop=4, # tell caffe to expect four output blobs
             python_param={'module': 'rpn.anchor_target_layer',
                           'layer': 'AnchorTargetLayer',
                           'param_str': '"\'feat_stride\': 16"'})

如何使用带有“Python”图层的网络?

从caffe调用python代码是你不必担心的. Caffe使用boost API从编译的c调用python代码.
你需要做什么?
确保实现你的图层的python模块在$PYTHONPATH中,这样当caffe导入它时 – 可以找到它.
例如,如果您的模块my_python_layer.py在/path/to/my_python_layer.py中,那么

PYTHONPATH=/path/to:$PYTHONPATH $CAFFE_ROOT/build/tools/caffe train -solver my_solver.prototxt

应该工作得很好.

如何测试我的图层?

在使用之前,您应该始终测试您的图层.
测试转发功能完全取决于您,因为每个层具有不同的功能.
测试后向方法很简单,因为这种方法只实现了一个向前的渐变,它可以自动进行数值测试!
查看test_gradient_for_python_layer测试实用程序:

import numpy as np
from test_gradient_for_python_layer import test_gradient_for_python_layer

# set the inputs
input_names_and_values = [('in_cont', np.random.randn(3,4)), 
                          ('in_binary', np.random.binomial(1, 0.4, (3,1))]
output_names = ['out1', 'out2']
py_module = 'folder.my_layer_module_name'
py_layer = 'my_layer_class_name'
param_str = 'some params'
propagate_down = [True, False]

# call the test
test_gradient_for_python_layer(input_names_and_values, output_names, 
                               py_module, py_layer, param_str, 
                               propagate_down)

# you are done!

特别通知

值得注意的是,python代码仅在CPU上运行.因此,如果您计划在网络中间安装Python层,那么如果您计划使用GPU,则会看到性能显着下降.这是因为caffe需要在调用python层之前将blob从GPU复制到CPU,然后复制回GPU以继续前进/后退传递.
如果python层是输入层或最顶层丢失层,那么这种降级就不那么重要了.
更新:2017年9月19日PR #5904合并为主人.这个PR通过python接口暴露了blob的GPU指针.
您可以直接从python访问blob._gpu_data_ptr和blob._gpu_diff_ptr,风险自负.

上一篇:anaconda 安装caffe,cntk,theano-未整理


下一篇:【Caffe学习八】基于Anaconda源码编译安装Caffe