[英]What is a `“Python”` layer in caffe?
Prune和Bharat的答案給出了"Python"
層的總體目的:通用層,用python而不是c ++實現。
我打算將這個答案作為使用"Python"
層的教程。
"Python"
圖層教程 "Python"
圖層? 為了使用'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(bottom)
)和輸出數量( len(top)
)是否符合預期。
您還應該在此處分配網絡的內部參數(即self.add_blobs()
),有關詳細信息,請參閱此主題 。
此方法可以訪問self.param_str
- 從原型文本傳遞到self.param_str
的字符串。 有關更多信息,請參閱此主題 。
def reshape(self, bottom, top)
:只要caffe重塑網絡,就會調用此方法。 此函數應分配輸出(每個top
blob)。 輸出的形狀通常與bottom
的形狀有關。
def forward(self, bottom, top)
:從bottom
到top
實施前進傳球。
def backward(self, top, propagate_down, bottom)
:此方法實現反向傳播,它從top
bottom
傳播漸變。 propagate_down
是len(bottom)
的布爾向量,指示應該傳播漸變的bottom
。
有關bottom
和top
輸入的更多信息,您可以在本文中找到。
例子
你可以在 這里和這里看到一些簡化的python層的例子。
可以在此處找到“移動平均”輸出層的示例。
可訓練的參數
"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
}
}
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 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
應該工作得很好。
在使用之前,您應該始終測試您的圖層。
測試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!
值得注意的是,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"
}
}
這里,層的名稱是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設置中不起作用,因此使用它們是一個缺點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.