tutorial redes neuronal libreria instalar imagenes funciones entrenar convolucionales convolucional clasificador aplicaciones tensorflow conv-neural-network

redes - tensorflow entrenar



VisualizaciĆ³n de la salida de la capa convolucional en tensorflow (4)

En caso de que alguien quiera "saltar" al numpy y visualizar "allí", aquí hay un ejemplo de cómo mostrar tanto los Weights como el processing result . Todas las transformaciones se basan en respuesta mdaoust por mdaoust .

# to visualize 1st conv layer Weights vv1 = sess.run(W_conv1) # to visualize 1st conv layer output vv2 = sess.run(h_conv1,feed_dict = {img_ph:x, keep_prob: 1.0}) vv2 = vv2[0,:,:,:] # in case of bunch out - slice first img def vis_conv(v,ix,iy,ch,cy,cx, p = 0) : v = np.reshape(v,(iy,ix,ch)) ix += 2 iy += 2 npad = ((1,1), (1,1), (0,0)) v = np.pad(v, pad_width=npad, mode=''constant'', constant_values=p) v = np.reshape(v,(iy,ix,cy,cx)) v = np.transpose(v,(2,0,3,1)) #cy,iy,cx,ix v = np.reshape(v,(cy*iy,cx*ix)) return v # W_conv1 - weights ix = 5 # data size iy = 5 ch = 32 cy = 4 # grid from channels: 32 = 4x8 cx = 8 v = vis_conv(vv1,ix,iy,ch,cy,cx) plt.figure(figsize = (8,8)) plt.imshow(v,cmap="Greys_r",interpolation=''nearest'') # h_conv1 - processed image ix = 30 # data size iy = 30 v = vis_conv(vv2,ix,iy,ch,cy,cx) plt.figure(figsize = (8,8)) plt.imshow(v,cmap="Greys_r",interpolation=''nearest'')

Estoy tratando de visualizar el resultado de una capa convolucional en tensorflow usando la función tf.image_summary . Ya lo estoy usando con éxito en otras instancias (por ejemplo, visualizando la imagen de entrada), pero tengo algunas dificultades para rediseñar el resultado aquí correctamente. Tengo la siguiente capa de conv:

img_size = 256 x_image = tf.reshape(x, [-1,img_size, img_size,1], "sketch_image") W_conv1 = weight_variable([5, 5, 1, 32]) b_conv1 = bias_variable([32]) h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

Entonces la salida de h_conv1 tendría la forma [-1, img_size, img_size, 32] . Solo usando tf.image_summary("first_conv", tf.reshape(h_conv1, [-1, img_size, img_size, 1])) No tiene en cuenta los 32 kernels diferentes, así que básicamente estoy revisando diferentes mapas de características aquí.

¿Cómo puedo remodelarlos correctamente? ¿O hay otra función de ayuda que podría utilizar para incluir esta salida en el resumen?


No sé de una función de ayuda pero si quiere ver todos los filtros, puede empacarlos en una imagen con algunos usos sofisticados de tf.transpose .

Entonces, si tienes un tensor que es images x ix x iy x channels

>>> V = tf.Variable() >>> print V.get_shape() TensorShape([Dimension(-1), Dimension(256), Dimension(256), Dimension(32)])

Entonces en este ejemplo ix = 256 , iy=256 , channels=32

primero corta 1 imagen y elimina la dimensión de la image

V = tf.slice(V,(0,0,0,0),(1,-1,-1,-1)) #V[0,...] V = tf.reshape(V,(iy,ix,channels))

A continuación, agregue un par de píxeles de relleno cero alrededor de la imagen

ix += 4 iy += 4 V = tf.image.resize_image_with_crop_or_pad(image, iy, ix)

Luego modifique la forma para que en lugar de 32 canales tenga 4x8 canales, vamos a llamarlos cy=4 y cx=8 .

V = tf.reshape(V,(iy,ix,cy,cx))

Ahora la parte difícil. tf parece devolver los resultados en orden C, numpy es el predeterminado.

El orden actual, si se aplana, enumeraría todos los canales para el primer píxel (iterando sobre cx y cy ), antes de enumerar los canales del segundo píxel (incrementando ix ). Pasando por las filas de píxeles ( ix ) antes de incrementar a la siguiente fila ( iy ).

Queremos el orden que establecería las imágenes en una grilla. Entonces, cruza una fila de una imagen ( ix ), antes de pasar por la fila de canales ( cx ), cuando tocas el final de la fila de canales, pasas a la siguiente fila de la imagen ( iy ) y cuando corres o filas en la imagen que incremente a la siguiente fila de canales ( cy ). asi que:

V = tf.transpose(V,(2,0,3,1)) #cy,iy,cx,ix

Personalmente prefiero np.einsum para transposiciones elegantes, para legibilidad, pero aún no está disponible.

newtensor = np.einsum(''yxYX->YyXx'',oldtensor)

De todos modos, ahora que los píxeles están en el orden correcto, podemos aplanarlo con seguridad en un tensor 2d:

# image_summary needs 4d input V = tf.reshape(V,(1,cy*iy,cx*ix,1))

prueba tf.image_summary sobre eso, deberías obtener una grilla de pequeñas imágenes.

A continuación se muestra una imagen de lo que se obtiene después de seguir todos los pasos aquí.


Personalmente trato de colocar cada 2d-filtro en una sola imagen.

Para hacer esto -si no estoy terriblemente equivocado ya que soy bastante nuevo en DL- descubrí que podría ser útil explotar la función depth_to_space , ya que toma un tensor 4d

[batch, height, width, depth]

y produce una salida de forma

[batch, height*block_size, width*block_size, depth/(block_size*block_size)]

Donde block_size es el número de "tiles" en la imagen de salida. La única limitación a esto es que la profundidad debe ser el cuadrado de block_size, que es un número entero, de lo contrario no puede "llenar" correctamente la imagen resultante. Una posible solución podría ser rellenar la profundidad del tensor de entrada hasta una profundidad que sea aceptada por el método, pero todavía no lo he intentado.


puede tratar de obtener la imagen de activación de la capa de convolución de esta manera:

h_conv1_features = tf.unpack(h_conv1, axis=3) h_conv1_imgs = tf.expand_dims(tf.concat(1, h_conv1_features_padded), -1)

esto obtiene una franja vertical con todas las imágenes concatenadas verticalmente.

si quieres acolchado (en mi caso de activaciones relu para rellenar con línea blanca):

h_conv1_features = tf.unpack(h_conv1, axis=3) h_conv1_max = tf.reduce_max(h_conv1) h_conv1_features_padded = map(lambda t: tf.pad(t-h_conv1_max, [[0,0],[0,1],[0,0]])+h_conv1_max, h_conv1_features) h_conv1_imgs = tf.expand_dims(tf.concat(1, h_conv1_features_padded), -1)