tutorial learning caffe2 cafe python neural-network deep-learning caffe pycaffe

python - learning - caffe2



¿Qué es una capa `` Python '''' en caffe? (3)

Caffe tiene una capa tipo "Python" .

Por ejemplo, este tipo de capa se puede usar como una capa de pérdida .
En otras ocasiones se usa como una capa de entrada .

¿Qué es este tipo de capa?
¿Cómo se puede usar esta capa?


Las capas de Python son diferentes de las capas de C ++ que deben compilarse, sus parámetros deben agregarse al archivo proto y, finalmente, debe registrar la capa en layer_factory. Si escribe una capa de Python, no necesita preocuparse por ninguna de estas cosas. Los parámetros de capa se pueden definir como una cadena, a los que se puede acceder como una cadena en python. Por ejemplo: si tiene un parámetro en una capa, puede acceder a él usando ''self.param_str'', si param_str se definió en su archivo de prototipo. Al igual que otras capas, debe definir una clase con las siguientes funciones:

  • Configuración: inicialice su capa utilizando parámetros obtenidos de variables de capa
  • Reenviar: qué sería la entrada y salida de una capa
  • Atrás: dada la predicción y los gradientes de la siguiente capa, calcule los gradientes de la capa anterior
  • Reformar: remodele su gota si es necesario

Ejemplo de prototipo:

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" } }

Aquí, el nombre de la capa es rpn-data, bottom y top son detalles de entrada y salida de la capa respectivamente. python_param define cuáles son los parámetros de la capa Python. ''módulo'' especifica cuál es el nombre de archivo de su capa. Si el archivo llamado ''anchor_target_layer.py'' se encuentra dentro de una carpeta llamada ''rpn'', el parámetro sería ''rpn.anchor_target_layer''. El parámetro ''capa'' es el nombre de su clase, en este caso es ''AnchorTargetLayer''. ''param_str'' es un parámetro para la capa, que contiene un valor 16 para la clave ''feat_stride''.

A diferencia de las capas C ++ / CUDA, las capas Python no funcionan en una configuración de múltiples GPU en caffe a partir de ahora, por lo que es una desventaja usarlas.


Las respuestas de Prune y Bharat dan el propósito general de una capa "Python" : una capa de propósito general que se implementa en python en lugar de c ++.

Tengo la intención de que esta respuesta sirva como tutorial para usar la capa "Python" .

Un tutorial para la capa "Python"

¿Qué es una capa "Python" ?

Por favor, vea las excelentes respuestas de Prune y Bharat .

Requisito previo

Para usar ''Python" capa ''Python" , necesita compilar caffe con flag

WITH_PYTHON_LAYER := 1

establecido en ''Makefile.config'' .

¿Cómo implementar una capa "Python" ?

Se debe implementar una capa "Python" como una clase de python derivada de la clase base caffe.Layer . Esta clase debe tener los siguientes cuatro métodos:

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

¿Cuáles son estos métodos?

def setup(self, bottom, top) : este método se llama una vez cuando caffe construye la red. Esta función debe verificar que el número de entradas ( len(bottom) ) y el número de salidas ( len(top) ) sea el esperado.
También debe asignar parámetros internos de la red aquí (es decir, self.add_blobs() ), consulte este hilo para obtener más información.
Este método tiene acceso a self.param_str , una cadena que se pasa del prototipo a la capa. Vea este hilo para más información.

def reshape(self, bottom, top) : este método se llama cada vez que caffe reestructura la red. Esta función debe asignar las salidas (cada uno de los blobs top ). La forma de las salidas generalmente está relacionada con la forma de la bottom .

def forward(self, bottom, top) : Implementando el pase hacia adelante de bottom hacia top .

def backward(self, top, propagate_down, bottom) : este método implementa la propagación def backward(self, top, propagate_down, bottom) , propaga los gradientes de top a bottom . propagate_down es un vector booleano de len(bottom) indica a cuál de las bottom debe propagar el gradiente.

Puede encontrar más información sobre top entradas bottom y top en esta publicación .

Ejemplos
Puede ver algunos ejemplos de capas de Python simplificadas here , aquí y aquí .
Ejemplo de capa de salida de "promedio móvil" se puede encontrar here .

Parámetros entrenables
"Python" capa "Python" puede tener parámetros entrenables (como "Conv" , "InnerProduct" , etc.).
Puede encontrar más información sobre cómo agregar parámetros entrenables en este hilo y en este . También hay un ejemplo muy simplificado en caffe git .

¿Cómo agregar una capa "Python" en un prototipo?

Vea la respuesta de Bharat para más detalles.
Debe agregar lo siguiente a su prototipo:

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 } }

¿Cómo agregar una capa "Python" usando la interfaz Pythonic NetSpec ?

Es muy sencillo:

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"''})

¿Cómo usar una red con una capa "Python" ?

Invocar código python desde caffe no es nada de lo que deba preocuparse. Caffe utiliza la API de impulso para llamar al código python desde c ++ compilado.
¿Qué necesitas hacer?
Asegúrese de que el módulo de Python que implementa su capa esté en $PYTHONPATH para que, cuando se lo import , se pueda encontrar.
Por ejemplo, si su módulo my_python_layer.py está en /path/to/my_python_layer.py entonces

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

debería funcionar bien.

¿Cómo probar mi capa?

Siempre debe probar su capa antes de ponerla en uso.
Probar la función de forward depende totalmente de usted, ya que cada capa tiene una funcionalidad diferente.
Probar el método backward es fácil , ya que este método solo implementa un gradiente de forward se puede probar numéricamente automáticamente!
Echa un vistazo a la utilidad de prueba 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!

Aviso especial

Vale la pena señalar que el código de Python se ejecuta solo en la CPU. Por lo tanto, si planea tener una capa de Python en el medio de su red, verá una degradación significativa en el rendimiento si planea usar GPU. Esto sucede porque caffe necesita copiar blobs de la GPU a la CPU antes de llamar a la capa de Python y luego copiar de nuevo a la GPU para continuar con el pase hacia adelante / hacia atrás.
Esta degradación es mucho menos significativa si la capa de Python es una capa de entrada o la capa de pérdida superior.
Actualización: El 19 de septiembre de 2017, PR # 5904 se fusionó en master. Este PR expone punteros de GPU de blobs a través de la interfaz de Python. Puede acceder a blob._gpu_data_ptr y blob._gpu_diff_ptr directamente desde python bajo su propio riesgo .


Muy simple, es una capa en la que proporciona el código de implementación, en lugar de utilizar uno de los tipos predefinidos, todos respaldados por funciones eficientes.

Si desea definir una función de pérdida personalizada, continúe: escríbala usted mismo y cree la capa con el tipo Python . Si tiene necesidades de entrada no estándar, quizás algún preprocesamiento específico de datos, no hay problema: escríbalo usted mismo y cree la capa con el tipo Python .