Argumento de Tensorflow Strides

115

Estoy tratando de entender el argumento de pasos en tf.nn.avg_pool, tf.nn.max_pool, tf.nn.conv2d.

La documentación dice repetidamente

zancadas: una lista de entradas que tiene una longitud> = 4. La zancada de la ventana deslizante para cada dimensión del tensor de entrada.

Mis preguntas son:

  1. ¿Qué representan cada uno de los 4+ enteros?
  2. ¿Por qué deben tener zancadas [0] = zancadas [3] = 1 para convnets?
  3. En este ejemplo vemos tf.reshape(_X,shape=[-1, 28, 28, 1]). ¿Por qué -1?

Lamentablemente, los ejemplos en los documentos para remodelar usando -1 no se traducen demasiado bien en este escenario.

jfbeltran
fuente

Respuestas:

224

Las operaciones de agrupación y convolución deslizan una "ventana" a través del tensor de entrada. Usando tf.nn.conv2dcomo 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, widthdimensiones.

stridesdetermina 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.

dga
fuente
5
@derek porque (del texto) "Le daremos a la convolución una profundidad de canal de salida de 8.". Es algo que puede elegir al configurar la convolución, y el respondedor eligió 8.
etarion
17

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.

Rafał Józefowicz
fuente
11

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]y kernel = [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í :

  • 8 = 1 * 2 + 0 * 1 + 2 * 3
  • 11 = 0 * 2 + 2 * 1 + 3 * 3
  • 7 = 2 * 2 + 3 * 1 + 0 * 3
  • 9 = 3 * 2 + 0 * 1 + 1 * 3
  • 4 = 0 * 2 + 1 * 1 + 1 * 3

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:

ingrese la descripción de la imagen aquí

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:

  1. ¿Qué representan cada uno de los 4+ enteros? . conv2d , pool le dice que esta lista representa los avances entre cada dimensión. Observe que la longitud de la lista de pasos es la misma que el rango del tensor del núcleo.
  2. ¿Por qué deben tener zancadas [0] = zancadas 3 = 1 para convnets? . La primera dimensión es el tamaño del lote, la última son los canales. No tiene sentido saltarse ni el lote ni el canal. Así que los convierte en 1. Para ancho / alto, puede omitir algo y es por eso que puede que no sean 1.
  3. tf.reshape (_X, shape = [- 1, 28, 28, 1]). ¿Por qué -1? tf.reshape lo tiene cubierto para usted:

    Si un componente de la forma es el valor especial -1, el tamaño de esa dimensión se calcula para que el tamaño total permanezca constante. En particular, una forma de [-1] se aplana en 1-D. Como máximo, un componente de la forma puede ser -1.

Salvador Dalí
fuente
2

@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 stridefunciona 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]

input_shape[4] is the number of colour channels (RGB or whichever format it is extracted in)
input_shape[3] is the width of the image
input_shape[2] is the height of the image
input_shape[1] is the number of frames that have been lumped into 1 complete data
input_shape[0] is the number of lumped frames of images we have.

A continuación se muestra una documentación resumida sobre cómo se usa Stride.

strides: Una lista de ints que tiene longitud> = 5. Tensor 1-D de longitud 5. El paso de la ventana deslizante para cada dimensión de entrada. Debe tenerstrides[0] = strides[4] = 1

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.

strides[0]=1 means that we do not want to skip any data in the batch 
strides[4]=1 means that we do not want to skip in the channel 

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!

Rocksyne
fuente