tutorial seq2seq raspberry neural network instalar español ejemplos como python tensorflow deep-learning

python - raspberry - tensorflow seq2seq



¿Cuál es la diferencia entre el relleno ''SAME'' y ''VALID'' en tf.nn.max_pool de tensorflow? (13)

Acolchado activado / desactivado. Determina el tamaño efectivo de su entrada.

VALID: sin relleno. Las operaciones de convolución, etc., solo se realizan en ubicaciones "válidas", es decir, no demasiado cerca de los bordes de su tensor.
Con un núcleo de 3x3 y una imagen de 10x10, estaría realizando una convolución en el área de 8x8 dentro de los bordes.

SAME: Se proporciona relleno. Siempre que su operación haga referencia a un vecindario (no importa cuán grande), se proporcionan valores cero cuando ese vecindario se extiende fuera del tensor original para permitir que esa operación funcione también en valores de borde.
Con un núcleo de 3x3 y una imagen de 10x10, estaría realizando una convolución en el área completa de 10x10.

¿Cuál es la diferencia entre el relleno ''SAME'' y ''VALID'' en tf.nn.max_pool de tensorflow ?

En mi opinión, ''VÁLIDO'' significa que no habrá relleno cero fuera de los bordes cuando hagamos el grupo máximo.

De acuerdo con una guía de aritmética de convolución para el aprendizaje profundo , dice que no habrá relleno en el operador de la piscina, es decir, solo use ''VÁLIDO'' de tensorflow . Pero, ¿qué es el relleno ''MISMO'' de la agrupación máxima en tensorflow ?


Basado en la explicación here y siguiendo la respuesta de Tristan, usualmente uso estas funciones rápidas para controles de cordura.

# a function to help us stay clean def getPaddings(pad_along_height,pad_along_width): # if even.. easy.. if pad_along_height%2 == 0: pad_top = pad_along_height / 2 pad_bottom = pad_top # if odd else: pad_top = np.floor( pad_along_height / 2 ) pad_bottom = np.floor( pad_along_height / 2 ) +1 # check if width padding is odd or even # if even.. easy.. if pad_along_width%2 == 0: pad_left = pad_along_width / 2 pad_right= pad_left # if odd else: pad_left = np.floor( pad_along_width / 2 ) pad_right = np.floor( pad_along_width / 2 ) +1 # return pad_top,pad_bottom,pad_left,pad_right # strides [image index, y, x, depth] # padding ''SAME'' or ''VALID'' # bottom and right sides always get the one additional padded pixel (if padding is odd) def getOutputDim (inputWidth,inputHeight,filterWidth,filterHeight,strides,padding): if padding == ''SAME'': out_height = np.ceil(float(inputHeight) / float(strides[1])) out_width = np.ceil(float(inputWidth) / float(strides[2])) # pad_along_height = ((out_height - 1) * strides[1] + filterHeight - inputHeight) pad_along_width = ((out_width - 1) * strides[2] + filterWidth - inputWidth) # # now get padding pad_top,pad_bottom,pad_left,pad_right = getPaddings(pad_along_height,pad_along_width) # print ''output height'', out_height print ''output width'' , out_width print ''total pad along height'' , pad_along_height print ''total pad along width'' , pad_along_width print ''pad at top'' , pad_top print ''pad at bottom'' ,pad_bottom print ''pad at left'' , pad_left print ''pad at right'' ,pad_right elif padding == ''VALID'': out_height = np.ceil(float(inputHeight - filterHeight + 1) / float(strides[1])) out_width = np.ceil(float(inputWidth - filterWidth + 1) / float(strides[2])) # print ''output height'', out_height print ''output width'' , out_width print ''no padding'' # use like so getOutputDim (80,80,4,4,[1,1,1,1],''SAME'')


Cito esta respuesta de los documentos oficiales de Tensorflow https://www.tensorflow.org/api_guides/python/nn#Convolution Para el relleno ''SAME'', la altura y el ancho de salida se calculan como:

out_height = ceil(float(in_height) / float(strides[1])) out_width = ceil(float(in_width) / float(strides[2]))

y el relleno en la parte superior e izquierda se calculan como:

pad_along_height = max((out_height - 1) * strides[1] + filter_height - in_height, 0) pad_along_width = max((out_width - 1) * strides[2] + filter_width - in_width, 0) pad_top = pad_along_height // 2 pad_bottom = pad_along_height - pad_top pad_left = pad_along_width // 2 pad_right = pad_along_width - pad_left

Para el relleno ''VÁLIDO'', la altura y el ancho de salida se calculan como:

out_height = ceil(float(in_height - filter_height + 1) / float(strides[1])) out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))

y los valores de relleno son siempre cero.


Cuando el stride es 1 (más típico con convolución que agrupación), podemos pensar en la siguiente distinción:

  • "SAME" : el tamaño de salida es el mismo que el tamaño de entrada. Esto requiere que la ventana del filtro se deslice fuera del mapa de entrada, de ahí la necesidad de rellenar.
  • "VALID" : la ventana de filtro permanece en una posición válida dentro del mapa de entrada, por lo que el tamaño de salida se reduce por filter_size - 1 . No se produce relleno.

Daré un ejemplo para aclararlo:

  • x : imagen de entrada de forma [2, 3], 1 canal
  • valid_pad : grupo máximo con 2x2 kernel, stride 2 y relleno VÁLIDO.
  • same_pad : grupo máximo con kernel 2x2, stride 2 y el mismo relleno (esta es la forma clásica de hacerlo)

Las formas de salida son:

  • valid_pad : aquí, sin relleno, por lo que la forma de salida es [1, 1]
  • same_pad : aquí, rellenamos la imagen a la forma [2, 4] (con -inf y luego aplicamos el grupo máximo), por lo que la forma de salida es [1, 2]

x = tf.constant([[1., 2., 3.], [4., 5., 6.]]) x = tf.reshape(x, [1, 2, 3, 1]) # give a shape accepted by tf.nn.max_pool valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding=''VALID'') same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding=''SAME'') valid_pad.get_shape() == [1, 1, 1, 1] # valid_pad is [5.] same_pad.get_shape() == [1, 1, 2, 1] # same_pad is [5., 6.]


El ejemplo de convolución TensorFlow ofrece una visión general sobre la diferencia entre SAME y VALID :

  • Para el SAME relleno, la altura y el ancho de salida se calculan como:

    out_height = ceil(float(in_height) / float(strides[1])) out_width = ceil(float(in_width) / float(strides[2]))

Y

  • Para el relleno VALID , la altura y el ancho de salida se calculan como:

    out_height = ceil(float(in_height - filter_height + 1) / float(strides[1])) out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))


El relleno es una operación para aumentar el tamaño de los datos de entrada. En el caso de datos unidimensionales, simplemente agrega / antepone la matriz con una constante, en 2-dim rodea la matriz envolvente con estas constantes. En n-dim rodeas tu hipercubo n-dim con la constante. En la mayoría de los casos, esta constante es cero y se llama relleno de cero.

Aquí hay un ejemplo de relleno cero con p=1 aplicado al tensor 2-d:

Puede usar relleno arbitrario para su núcleo, pero algunos de los valores de relleno se usan con más frecuencia que otros:

  • Relleno VÁLIDO . El caso más fácil, significa que no hay relleno en absoluto. Simplemente deje sus datos como estaban.
  • El mismo relleno a veces llamado MEDIO relleno . Se llama MISMO porque para una convolución con una zancada = 1, (o para agrupar) debería producir una salida del mismo tamaño que la entrada. Se llama MEDIO porque para un núcleo de tamaño k
  • El relleno COMPLETO es el relleno máximo que no da como resultado una convolución sobre solo elementos rellenados. Para un núcleo de tamaño k , este relleno es igual a k - 1 .

Para usar relleno arbitrario en TF, puede usar tf.pad()


En resumen, el relleno "válido" significa que no hay relleno. El tamaño de salida de la capa convolucional se reduce según el tamaño de entrada y el tamaño del núcleo.

Por el contrario, el "relleno" significa usar relleno. El tamaño de salida de la capa convolucional se mantiene como el tamaño de entrada al agregar un cierto número de ''borde 0'' alrededor de los datos de entrada al calcular la convolución.

Espero que esta descripción intuitiva ayude.


Hay tres opciones de relleno: válido (sin relleno), igual (o medio), completo. Puede encontrar explicaciones (en Theano) aquí: http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html

  • Válido o sin relleno:

El relleno válido no implica relleno cero, por lo que cubre solo la entrada válida, sin incluir ceros generados artificialmente. La longitud de salida es ((la longitud de entrada) - (k-1)) para el tamaño de kernel k si la zancada s = 1.

  • Mismo o medio relleno:

El mismo relleno hace que el tamaño de las salidas sea el mismo que el de las entradas cuando s = 1. Si s = 1, el número de ceros rellenos es (k-1).

  • Relleno completo:

El relleno completo significa que el núcleo se ejecuta sobre todas las entradas, por lo que en los extremos, el núcleo puede cumplir con la única entrada y ceros más. El número de ceros rellenos es 2 (k-1) si s = 1. La longitud de salida es ((la longitud de entrada) + (k-1)) si s = 1.

Por lo tanto, el número de rellenos: (válido) <= (igual) <= (completo)


Si te gusta el arte ascii:

  • "VALID" = sin relleno:

    inputs: 1 2 3 4 5 6 7 8 9 10 11 (12 13) |________________| dropped |_________________|

  • "SAME" = con cero relleno:

    pad| |pad inputs: 0 |1 2 3 4 5 6 7 8 9 10 11 12 13|0 0 |________________| |_________________| |________________|

En este ejemplo:

  • Ancho de entrada = 13
  • Ancho del filtro = 6
  • Zancada = 5

Notas:

  • "VALID" solo elimina las columnas del extremo derecho (o las filas del extremo inferior).
  • "SAME" intenta rellenar uniformemente hacia la izquierda y hacia la derecha, pero si la cantidad de columnas que se agregarán es impar, agregará la columna adicional a la derecha, como es el caso en este ejemplo (la misma lógica se aplica verticalmente: puede haber una fila adicional de ceros en la parte inferior).

Editar :

Sobre el nombre

  • Con el relleno "SAME" , si usa un paso de 1, las salidas de la capa tendrán las mismas dimensiones espaciales que sus entradas.
  • Con el relleno "VALID" , no hay entradas de relleno "inventadas". La capa solo usa datos de entrada válidos .

Aquí, W y H son el ancho y la altura de la entrada, F son las dimensiones del filtro, P es el tamaño del relleno (es decir, el número de filas o columnas a rellenar)

Para el mismo relleno:

Para relleno VÁLIDO:


Explicacion rapida

VALID : no aplique ningún relleno, es decir, suponga que todas las dimensiones son válidas para que la imagen de entrada quede completamente cubierta por el filtro y la zancada que especificó.

SAME : aplique relleno a la entrada (si es necesario) para que la imagen de entrada quede completamente cubierta por el filtro y la zancada que especificó. Para el paso 1, esto asegurará que el tamaño de la imagen de salida sea el mismo que el de la entrada.

Notas

  • Esto se aplica a las capas conv, así como a las capas de grupo máximo de la misma manera
  • El término "válido" es un nombre poco apropiado porque las cosas no se vuelven "inválidas" si suelta parte de la imagen. En algún momento incluso podrías querer eso. Probablemente debería haberse llamado NO_PADDING en NO_PADDING lugar.
  • El término "igual" también es incorrecto porque solo tiene sentido para el paso 1 cuando la dimensión de salida es igual a la dimensión de entrada. Para zancadas de 2, las dimensiones de salida serán la mitad, por ejemplo. Probablemente debería haberse llamado AUTO_PADDING en AUTO_PADDING lugar.
  • En SAME (es decir, el modo de relleno automático), Tensorflow intentará distribuir el relleno de manera uniforme tanto a la izquierda como a la derecha.
  • En VALID (es decir, sin modo de relleno), Tensorflow soltará las celdas derecha y / o inferior si su filtro y zancada no cubren por completo la imagen de entrada.

Relleno VÁLIDO : esto es con relleno cero. Espero que no haya confusión.

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]]) x = tf.reshape(x, [1, 4, 3, 1]) valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding=''VALID'') print (valid_pad.get_shape()) # output-->(1, 2, 1, 1)

El mismo relleno: es un poco difícil de entender en primer lugar porque tenemos que considerar dos condiciones por separado como se menciona en los documentos oficiales .

Tomemos entrada como , salida como , relleno como andar como y el tamaño del grano como (solo se considera una sola dimensión)

Caso 01: :

Caso 02: :

se calcula de tal manera que el valor mínimo que se puede tomar para el relleno. Como valor de es conocido, valor de se puede encontrar usando esta fórmula .

Analicemos este ejemplo:

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]]) x = tf.reshape(x, [1, 4, 3, 1]) same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding=''SAME'') print (same_pad.get_shape()) # --> output (1, 2, 2, 1)

Aquí la dimensión de x es (3,4). Entonces, si se toma la dirección horizontal (3):

Si se toma la dirección vertical (4):

Espero que esto ayude a comprender cómo funciona realmente el mismo relleno en TF.