xlabel - Construyendo una capa de Caffe personalizada en python
seaborn (2)
Después de analizar muchos enlaces relacionados con la creación de capas de Caffe en Python, todavía tengo dificultades para comprender algunos conceptos. ¿Puede alguien aclararlos por favor?
- Las estructuras de python de blobs y pesos para la red se explican aquí: Cómo encontrar el gradiente de un conv-filter de Caffe con respecto a la entrada .
- La estructura de Red y Solver se explica aquí: ¿ Hoja de trucos para caffe / pycaffe? .
- El ejemplo de la definición de la capa python está aquí: pyloss.py en git .
- Pruebas de capa aquí: prueba de capa en git .
- El desarrollo de nuevas capas para C ++ se describe aquí: git wiki .
Lo que todavía me falta es:
- Método
setup()
: ¿Qué debo hacer aquí? ¿Por qué en el ejemplo debería comparar la longitud del parámetro ''inferior'' con ''2''? ¿Por qué debería ser 2? ¿No parece un tamaño de lote porque es arbitrario? Y el fondo, según entiendo, es blob, y luego, ¿la primera dimensión es el tamaño del lote? - método
reshape()
: según entiendo, el parámetro de entrada "inferior" es un blob de la capa inferior, y el parámetro "superior" es un blob de la capa superior, y debo cambiar la capa superior de acuerdo con la forma de salida de mis cálculos con el avance. Pero, ¿por qué tengo que hacer esto cada paso hacia adelante si estas formas no cambian de un paso a otro, solo cambian los pesos? -
reshape
métodos dereshape
yforward
tienen 0 índices para el parámetro de entrada ''superior'' utilizado. ¿Por qué tendría que usartop[0].data=...
otop[0].input=...
lugar detop.data=...
ytop.input=...
? ¿De qué se trata este índice? Si no utilizamos otra parte de esta lista superior, ¿por qué se expone de esta manera? Puedo sospechar que es una coincidencia de la red troncal o C ++, pero sería bueno saberlo exactamente. método de
reshape()
, línea con:if bottom[0].count != bottom[1].count
que hago aqui ¿Por qué su dimensión es 2 de nuevo? ¿Y qué estoy contando aquí? ¿Por qué ambas partes de blobs (0 y 1) deben ser iguales en cantidad de algunos miembros (
count
)?Método
forward()
, lo que defino por esta línea:self.diff[...] = bottom[0].data - bottom[1].data
¿Cuándo se usa después del camino hacia delante si lo defino? Podemos simplemente usar
diff = bottom[0].data - bottom[1].data
en lugar de contar la pérdida más adelante en este método, sin asignarse a
self
, o ¿se hace con algún propósito?Método
backward()
: de qué se trata:for i in range(2):
:? ¿Por qué de nuevo el rango es 2?- Método
backward()
, parámetropropagate_down
: ¿por qué está definido? Quiero decir que si es verdadero, el gradiente debería asignarse a labottom[X].diff
como veo, pero ¿por qué alguien llamaría al método que no haría nada conpropagate_down = False
, si no hace nada y sigue avanzando?
Lo siento si esas preguntas son demasiado obvias, simplemente no pude encontrar una buena guía para entenderlas y pedir ayuda aquí.
Hiciste muchas preguntas aquí, te daré algunos puntos destacados y sugerencias que espero que te aclaren las cosas. No responderé explícitamente a todas sus preguntas.
Parece que estás más confundido acerca de la diferencia entre un blob y la entrada / salida de una capa. De hecho, la mayoría de las capas tiene un solo blob como entrada y un solo blob como salida, pero no siempre es así. Considere una capa de pérdida: tiene dos entradas: predicciones y etiquetas de verdad de fondo. Por lo tanto, en este caso, la bottom
es un vector de longitud 2 (!) Donde la bottom[0]
es un blob (4-D) que representa predicciones, mientras que la bottom[1]
es otra burbuja con las etiquetas. Por lo tanto, al construir una capa de este tipo, debe asegurarse de que tiene exactamente 2 blobs de entrada (codificados) (consulte, por ejemplo, ExactNumBottomBlobs()
en la definición de AccuracyLayer
).
Lo mismo ocurre con top
blobs top
: de hecho, en la mayoría de los casos hay un solo top
para cada capa, pero no siempre es así (consulte, por ejemplo, AccuracyLayer
). Por lo tanto, la top
también es un vector de manchas 4-D, una para cada top
de la capa. La mayoría de las veces habrá un solo elemento en ese vector, pero a veces es posible que encuentre más de uno.
Creo que esto cubre sus preguntas 1,3,4 y 6.
A partir de reshape()
(Q.2), esta función no se llama en cada paso hacia adelante, se llama solo cuando la red está configurada para asignar espacio para entradas / salidas y parámetros.
De vez en cuando, es posible que desee cambiar el tamaño de entrada para su red (por ejemplo, para redes de detección), entonces necesita llamar a reshape()
para que todas las capas de la red se adapten al nuevo tamaño de entrada.
En cuanto al parámetro propagate_down
(Q.7): como una capa puede tener más de un bottom
, en principio, necesitaría pasar el gradiente a todos los bottom
durante backprop. Sin embargo, ¿cuál es el significado de un degradado en la parte inferior de la label
de una capa de pérdida? Hay casos en los que no desea propagarse a todas las bottom
: este es el objetivo de esta bandera. (Aquí hay un example con una capa de pérdida con tres bottom
que esperan un gradiente para todos ellos).
Para obtener más información, consulte este tutorial de capas "Python"
.
¿Por qué debería ser 2?
Esa esencia específica está hablando de la capa de pérdida euclidiana. La pérdida euclidiana es el error cuadrático medio entre 2 vectores. Por lo tanto, debe haber 2 vectores en el blob de entrada a esta capa. La longitud de cada vector debe ser la misma porque es una diferencia de elementos. Puedes ver esta comprobación en el método de remodelación .
Gracias.