簡體   English   中英

caffe中的“Python”層是什么?

[英]What is a `“Python”` layer in caffe?

Caffe有一個圖層類型"Python"

例如,該層類型可以用作損耗層
在其他情況下,它用作輸入層

這層類型是什么?
如何使用這一層?

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(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) :從bottomtop實施前進傳球。

def backward(self, top, propagate_down, bottom) :此方法實現反向傳播,它從top bottom傳播漸變。 propagate_downlen(bottom)的布爾向量,指示應該傳播漸變的bottom

有關bottomtop輸入的更多信息,您可以在本文中找到。

例子
你可以 這里這里看到一些簡化的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
  }
}

如何使用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 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。 與其他圖層一樣,您需要使用以下函數定義類:

  • 設置 - 使用從圖層變量獲取的參數初始化圖層
  • 前進 - 圖層的輸入和輸出是什么
  • 向后 - 給定下一層的預測和漸變,計算前一層的漸變
  • 重塑 - 根據需要重塑您的blob

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM