Sha*_*hai 19 python machine-learning neural-network deep-learning caffe
Caffe有一个图层类型"Python".
例如,该层类型可以用作损耗层.
在其他情况下,它用作输入层.
这层类型是什么?
如何使用这一层?
Sha*_*hai 35
Prune和Bharat的答案给出了一个"Python"层的总体目的:一个用python而不是c ++实现的通用层.
我打算将这个答案作为使用"Python"图层的教程.
"Python"图层教程"Python"图层?为了使用'Python"图层,您需要使用flag编译caffe
WITH_PYTHON_LAYER := 1
Run Code Online (Sandbox Code Playgroud)
设置'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
Run Code Online (Sandbox Code Playgroud)
这些方法是什么?
def setup(self, bottom, top):当caffe构建网络时,此方法被调用一次.此函数应检查输入数量(len(bottom))和输出数量(len(top))是否符合预期.
您还应该在此处分配网络的内部参数(即self.add_blobs()),有关详细信息,请参阅此主题.
此方法可以访问self.param_str- 从原型文本传递到图层的字符串.有关更多信息,请参阅此主题.
def reshape(self, bottom, top):只要caffe重塑网络,就会调用此方法.此函数应分配输出(每个topblob).输出的形状通常与bottoms'形状有关.
def forward(self, bottom, top):从实施直传bottom到top.
def backward(self, top, propagate_down, bottom):此方法实现反向传播,它将渐变传播top到bottom.propagate_down是一个布尔矢量,len(bottom)表示bottom应该传播梯度中的哪一个.
您可以在这篇文章中找到更多关于bottom和top输入的信息.
例如
你可以看到蟒蛇简化层的一些例子在这里,这里和这里.
可以在此处找到"移动平均"输出层的示例.
可训练参数
"Python"层可以具有可训练参数(如"Conv","InnerProduct"等).
您可以在此主题和此主题中找到有关添加可训练参数的更多信息.在caffe git中还有一个非常简单的例子.
"Python"在原型文件中添加图层?有关细节,请参阅巴拉特的回答.
您需要将以下内容添加到您的原型文本中:
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
}
}
Run Code Online (Sandbox Code Playgroud)
"Python"使用pythonic NetSpec接口添加图层?这很简单:
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"'})
Run Code Online (Sandbox Code Playgroud)
"Python"?从caffe调用python代码是你不必担心的.Caffe使用boost API从编译的c ++中调用python代码.
你需要做什么?
确保实现你的图层的python模块已经存在,$PYTHONPATH这样当import它出现时 - 可以找到它.
例如,如果你的模块my_python_layer.py在/path/to/my_python_layer.py那里
PYTHONPATH=/path/to:$PYTHONPATH $CAFFE_ROOT/build/tools/caffe train -solver my_solver.prototxt
Run Code Online (Sandbox Code Playgroud)
应该工作得很好.
在使用之前,您应该始终测试您的图层.
测试forward功能完全取决于您,因为每个层都具有不同的功能.
测试backward方法很简单,因为这种方法只实现了forward它的梯度,可以自动进行数值测试!
检查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!
Run Code Online (Sandbox Code Playgroud)
值得注意的是,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,风险自负.
很简单,它是一个层,您可以在其中提供实现代码,而不是使用其中一个预定义类型 - 这些类型都由高效函数支持.
如果要定义自定义丢失函数,请继续:自己编写,然后使用Python类型创建图层.如果您有非标准的输入需求,也许是一些特定于数据的预处理,没问题:自己编写,并使用Python类型创建图层.
Python层与需要编译的C++层不同,它们的参数需要添加到proto文件中,最后需要在layer_factory中注册层.如果你编写一个python层,你不必担心这些事情.层参数可以定义为字符串,可以在python中作为字符串访问.例如:如果图层中有参数,则可以使用'self.param_str'访问它,前提是在原型文件中定义了param_str.与其他图层一样,您需要使用以下函数定义类:
Prototxt示例:
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'
layer: 'AnchorTargetLayer'
param_str: "'feat_stride': 16"
}
}
Run Code Online (Sandbox Code Playgroud)
这里,层的名称是rpn-data,bottom和top分别是层的输入和输出细节.python_param定义了Python层的参数.'module'指定图层的文件名.如果名为"anchor_target_layer.py"的文件位于名为"rpn"的文件夹中,则参数将为"rpn.anchor_target_layer".'layer'参数是您的类的名称,在这种情况下它是'AnchorTargetLayer'.'param_str'是图层的参数,其中包含键'feat_stride'的值16.
与C++/CUDA层不同,截至目前,Python层在caffe中的多GPU设置中不起作用,因此使用它们是一个缺点.
| 归档时间: |
|
| 查看次数: |
6931 次 |
| 最近记录: |