Las operaciones de agrupación y convolución deslizan una "ventana" a través del tensor de entrada. Usando tf.nn.conv2d
como ejemplo: Si el tensor de entrada tiene 4 dimensiones:, [batch, height, width, channels]
entonces la convolución opera en una ventana 2D en las height, width
dimensiones.
strides
determina cuánto se desplaza la ventana en cada una de las dimensiones. El uso típico establece el primer (el lote) y el último (la profundidad) zancada en 1.
Usemos un ejemplo muy concreto: ejecutar una convolución 2-d sobre una imagen de entrada en escala de grises de 32x32. Digo escala de grises porque entonces la imagen de entrada tiene profundidad = 1, lo que ayuda a que sea simple. Deja que esa imagen se vea así:
00 01 02 03 04 ...
10 11 12 13 14 ...
20 21 22 23 24 ...
30 31 32 33 34 ...
...
Ejecutemos una ventana de convolución de 2x2 sobre un solo ejemplo (tamaño de lote = 1). Le daremos a la convolución una profundidad de canal de salida de 8.
La entrada a la convolución tiene shape=[1, 32, 32, 1]
.
Si especifica strides=[1,1,1,1]
con padding=SAME
, la salida del filtro será [1, 32, 32, 8].
El filtro primero creará una salida para:
F(00 01
10 11)
Y luego para:
F(01 02
11 12)
y así. Luego pasará a la segunda fila, calculando:
F(10, 11
20, 21)
luego
F(11, 12
21, 22)
Si especifica un paso de [1, 2, 2, 1], no se superpondrán ventanas. Calculará:
F(00, 01
10, 11)
y entonces
F(02, 03
12, 13)
El paso funciona de manera similar para los operadores de agrupación.
Pregunta 2: Por qué los pasos [1, x, y, 1] para convnets
El primero es el lote: por lo general, no desea omitir ejemplos en su lote, o no debería haberlos incluido en primer lugar. :)
El último 1 es la profundidad de la convolución: por lo general, no desea omitir las entradas, por la misma razón.
El operador conv2d es más general, por lo que podría crear convoluciones que deslizan la ventana a lo largo de otras dimensiones, pero ese no es un uso típico en convnets. El uso típico es utilizarlos espacialmente.
Por qué remodelar a -1 -1 es un marcador de posición que dice "ajustar según sea necesario para que coincida con el tamaño necesario para el tensor completo". Es una forma de hacer que el código sea independiente del tamaño del lote de entrada, de modo que pueda cambiar su canalización y no tener que ajustar el tamaño del lote en todas partes del código.
Las entradas son de 4 dimensiones y tienen la forma:
[batch_size, image_rows, image_cols, number_of_colors]
Las zancadas, en general, definen una superposición entre las operaciones de aplicación. En el caso de conv2d, especifica cuál es la distancia entre aplicaciones consecutivas de filtros convolucionales. El valor de 1 en una dimensión específica significa que aplicamos el operador en cada fila / columna, el valor de 2 significa cada segundo, y así sucesivamente.
Re 1) Los valores que importan para las convoluciones son 2º y 3º y representan la superposición en la aplicación de los filtros convolucionales a lo largo de filas y columnas. El valor de [1, 2, 2, 1] dice que queremos aplicar los filtros en cada segunda fila y columna.
Con respecto a 2) No conozco las limitaciones técnicas (podría ser un requisito de CuDNN) pero normalmente la gente usa zancadas a lo largo de las dimensiones de las filas o columnas. No necesariamente tiene sentido hacerlo sobre el tamaño del lote. No estoy seguro de la última dimensión.
Con respecto a 3) Establecer -1 para una de las dimensiones significa, "establecer el valor de la primera dimensión de modo que el número total de elementos en el tensor no cambie". En nuestro caso, -1 será igual a batch_size.
fuente
Comencemos con lo que hace la zancada en el caso de 1 atenuación.
Supongamos que su
input = [1, 0, 2, 3, 0, 1, 1]
ykernel = [2, 1, 3]
el resultado de la convolución es[8, 11, 7, 9, 4]
, que se calcula deslizando su kernel sobre la entrada, realizando una multiplicación por elementos y sumando todo. Así :Aquí nos deslizamos por un elemento, pero nada lo detiene al usar cualquier otro número. Este número es tu paso. Puede pensar en ello como reducir la resolución del resultado de la convolución de 1 paso simplemente tomando cada resultado s-ésimo.
Conociendo el tamaño de entrada i , el tamaño del kernel k , la zancada sy el relleno p , puede calcular fácilmente el tamaño de salida de la convolución como:
Aquí || operador significa operación de techo. Para una capa de agrupación s = 1.
Estuche N-dim.
Conocer las matemáticas para un caso 1-dim, el caso n-dim es fácil una vez que ve que cada dim es independiente. Así que deslice cada dimensión por separado. A continuación se muestra un ejemplo de 2-d . Tenga en cuenta que no es necesario que tenga el mismo paso en todas las dimensiones. Entonces, para una entrada / kernel N-dim, debe proporcionar N pasos.
Así que ahora es fácil responder a todas sus preguntas:
fuente
@dga ha hecho un trabajo maravilloso explicando y no puedo estar lo suficientemente agradecido de lo útil que ha sido. De la misma manera, me gustaría compartir mis hallazgos sobre cómo
stride
funciona la convolución 3D.Según la documentación de TensorFlow sobre conv3d, la forma de la entrada debe estar en este orden:
[batch, in_depth, in_height, in_width, in_channels]
Expliquemos las variables de la extrema derecha a la izquierda usando un ejemplo. Suponiendo que la forma de entrada es
input_shape = [1000,16,112,112,3]
A continuación se muestra una documentación resumida sobre cómo se usa Stride.
Como se indica en muchos trabajos, los pasos simplemente significan cuántos pasos de distancia una ventana o kernel salta del elemento más cercano, ya sea un marco de datos o un píxel (esto está parafraseado por cierto).
De la documentación anterior, una zancada en 3D se verá así zancadas = (1, X , Y , Z , 1).
La documentación enfatiza eso
strides[0] = strides[4] = 1
.zancadas [X] significa cuántos saltos debemos hacer en los fotogramas agrupados. Entonces, por ejemplo, si tenemos 16 cuadros, X = 1 significa usar todos los cuadros. X = 2 significa usar cada segundo fotograma y sigue y sigue
strides [y] y strides [z] siguen la explicación de @dga, así que no volveré a hacer esa parte.
Sin embargo, en keras, solo necesita especificar una tupla / lista de 3 enteros, especificando los pasos de la convolución a lo largo de cada dimensión espacial, donde la dimensión espacial es paso [x], pasos [y] y pasos [z]. strides [0] y strides [4] ya están predeterminados en 1.
¡Espero que alguien encuentre esto útil!
fuente