¿Qué es un Autoencoder?
Un Autoencoder es una herramienta para aprender a codificar datos de manera eficiente y sin supervisión. Es un tipo de red neuronal artificial que le ayuda a aprender la representación de conjuntos de datos para la reducción de dimensionalidad al entrenar la red neuronal para ignorar el ruido de la señal. Es una gran herramienta para recrear una entrada.
En palabras simples, la máquina toma, digamos una imagen, y puede producir una imagen estrechamente relacionada. La entrada en este tipo de red neuronal no está etiquetada, lo que significa que la red es capaz de aprender sin supervisión. Más precisamente, la entrada es codificada por la red para enfocarse solo en la característica más crítica. Esta es una de las razones por las que el codificador automático es popular para la reducción de dimensionalidad. Además, los autocodificadores se pueden utilizar para producir modelos de aprendizaje generativo . Por ejemplo, la red neuronal se puede entrenar con un conjunto de caras y luego puede producir caras nuevas.
En este tutorial del codificador automático de TensorFlow, aprenderá:
- ¿Qué es un Autoencoder?
- ¿Cómo funciona Autoencoder?
- Ejemplo de codificador automático apilado
- Crea un codificador automático con TensorFlow
- Preprocesamiento de imágenes
- Establecer estimador de conjunto de datos
- Construye la red
¿Cómo funciona Autoencoder?
El propósito de un codificador automático es producir una aproximación de la entrada centrándose solo en las características esenciales. Puede pensar por qué no aprender simplemente a copiar y pegar la entrada para producir la salida. De hecho, un codificador automático es un conjunto de restricciones que obligan a la red a aprender nuevas formas de representar los datos, diferentes de simplemente copiar la salida.
Un autoencoder típico se define con una entrada, una representación interna y una salida (una aproximación de la entrada). El aprendizaje ocurre en las capas adjuntas a la representación interna. De hecho, hay dos bloques principales de capas que parecen una red neuronal tradicional. La ligera diferencia es que la capa que contiene la salida debe ser igual a la entrada. En la imagen de abajo, la entrada original va al primer bloque llamado codificador . Esta representación interna comprime (reduce) el tamaño de la entrada. En el segundo bloque se produce la reconstrucción de la entrada. Esta es la fase de decodificación.
El modelo actualizará los pesos minimizando la función de pérdida. El modelo se penaliza si la salida de la reconstrucción es diferente de la entrada.
Concretamente, imagine una imagen con un tamaño de 50x50 (es decir, 250 píxeles) y una red neuronal con una sola capa oculta compuesta por cien neuronas. El aprendizaje se realiza en un mapa de características que es dos veces más pequeño que la entrada. Significa que la red necesita encontrar una manera de reconstruir 250 píxeles con solo un vector de neuronas igual a 100.
Ejemplo de codificador automático apilado
En este tutorial de Autoencoder, aprenderá a utilizar un autoencoder apilado. La arquitectura es similar a una red neuronal tradicional. La entrada va a una capa oculta para comprimirla, o reducir su tamaño, y luego llega a las capas de reconstrucción. El objetivo es producir una imagen de salida tan cercana como la original. El modelo tiene que aprender una forma de lograr su tarea bajo un conjunto de restricciones, es decir, con una dimensión menor.
Hoy en día, los Autoencoders en Deep Learning se utilizan principalmente para eliminar el ruido de una imagen. Imagina una imagen con rayas; un humano todavía puede reconocer el contenido. La idea de eliminar el ruido del codificador automático es agregar ruido a la imagen para obligar a la red a aprender el patrón detrás de los datos.
La otra familia útil de Autoencoder Deep Learning es el autoencoder variacional. Este tipo de red puede generar nuevas imágenes. Imagina que entrenas una red con la imagen de un hombre; una red de este tipo puede producir caras nuevas.
Crea un codificador automático con TensorFlow
En este tutorial, aprenderá a crear un codificador automático apilado para reconstruir una imagen.
Utilizará el conjunto de datos CIFAR-10 que contiene 60000 imágenes en color de 32x32. El conjunto de datos de Autoencoder ya está dividido entre 50000 imágenes para entrenamiento y 10000 para pruebas. Hay hasta diez clases:
- Avión
- Automóvil
- Pájaro
- Gato
- Ciervo
- Perro
- Rana
- Caballo
- Barco
- Camión
Necesita descargar las imágenes en esta URL https://www.cs.toronto.edu/~kriz/cifar.html y descomprimirlo. La carpeta for-10-batches-py contiene cinco lotes de datos con 10000 imágenes cada uno en un orden aleatorio.
Antes de construir y entrenar su modelo, necesita aplicar algún procesamiento de datos. Procederá de la siguiente manera:
- Importar los datos
- Convierta los datos a formato blanco y negro
- Anexar todos los lotes
- Construya el conjunto de datos de entrenamiento
- Construye un visualizador de imágenes
Preprocesamiento de imágenes
Paso 1) Importe los datos.
Según el sitio web oficial, puede cargar los datos con el siguiente código. El código del Autoencoder cargará los datos en un diccionario con los datos y la etiqueta . Tenga en cuenta que el código es una función.
import numpy as npimport tensorflow as tfimport pickledef unpickle(file):import picklewith open(file, 'rb') as fo:dict = pickle.load(fo, encoding='latin1')return dict
Paso 2) Convierta los datos a formato blanco y negro
Para simplificar, convertirá los datos a una escala de grises. Es decir, con una sola dimensión frente a tres para la imagen de colores. La mayor parte de la red neuronal funciona solo con una entrada de dimensión.
def grayscale(im):return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
Paso 3) Agregue todos los lotes
Ahora que se crearon ambas funciones y se cargó el conjunto de datos, puede escribir un bucle para agregar los datos en la memoria. Si lo comprueba con atención, el archivo descomprimido con los datos se llama data_batch_ con un número del 1 al 5. Puede recorrer los archivos y agregarlos a los datos.
Cuando finaliza este paso, convierte los datos de colores a un formato de escala de grises. Como puede ver, la forma de los datos es 50000 y 1024. Los 32 * 32 píxeles ahora se aplanan a 2014.
# Load the data into memorydata, labels = [], []## Loop over the bfor i in range(1, 6):filename = './cifar-10-batches-py/data_batch_' + str(i)open_data = unpickle(filename)if len(data)> 0:data = np.vstack((data, open_data['data']))labels = np.hstack((labels, open_data['labels']))else:data = open_data['data']labels = open_data['labels']data = grayscale(data)x = np.matrix(data)y = np.array(labels)print(x.shape)(50000, 1024)
Nota: Cambie './cifar-10-batches-py/data_batch_' a la ubicación real de su archivo. Por ejemplo, para una máquina con Windows, la ruta podría ser filename = 'E: \ cifar-10-batches-py \ data_batch_' + str (i)
Paso 4) Construya el conjunto de datos de entrenamiento
Para que el entrenamiento sea más rápido y fácil, entrenarás a un modelo solo en las imágenes del caballo. Los caballos son la séptima clase en los datos de la etiqueta. Como se menciona en la documentación del conjunto de datos CIFAR-10, cada clase contiene 5000 imágenes. Puede imprimir la forma de los datos para confirmar que hay 5000 imágenes con 1024 columnas, como se muestra en el siguiente paso de ejemplo del codificador automático de TensorFlow.
horse_i = np.where(y == 7)[0]horse_x = x[horse_i]print(np.shape(horse_x))(5000, 1024)
Paso 5) Construya un visualizador de imágenes
Finalmente, construyes una función para trazar las imágenes. Necesitará esta función para imprimir la imagen reconstruida desde el codificador automático.
Una forma fácil de imprimir imágenes es usar el objeto imshow de la biblioteca matplotlib. Tenga en cuenta que debe convertir la forma de los datos de 1024 a 32 * 32 (es decir, el formato de una imagen).
# To plot pretty figures%matplotlib inlineimport matplotlibimport matplotlib.pyplot as pltdef plot_image(image, shape=[32, 32], cmap = "Greys_r"):plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest")plt.axis("off")
La función toma 3 argumentos:
- Imagen: la entrada
- Forma: lista, la dimensión de la imagen.
- Cmap: elige el mapa de colores. Por defecto, gris
Puede intentar trazar la primera imagen del conjunto de datos. Deberías ver a un hombre a caballo.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Establecer estimador de conjunto de datos
Muy bien, ahora que el conjunto de datos está listo para usar, puede comenzar a usar Tensorflow. Antes de construir el modelo, usemos el estimador de conjunto de datos de Tensorflow para alimentar la red.
Construirá un conjunto de datos con el estimador de TensorFlow. Para refrescar su mente, necesita usar:
- from_tensor_slices
- repetir
- lote
El código completo para construir el conjunto de datos es:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
Tenga en cuenta que x es un marcador de posición con la siguiente forma:
- [Ninguno, n_inputs]: se establece en Ninguno porque el número de imágenes alimentadas a la red es igual al tamaño del lote.
para obtener más información, consulte el tutorial sobre regresión lineal.
Después de eso, debe crear el iterador. Sin esta línea de código, ningún dato pasará por la canalización.
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
Ahora que la tubería está lista, puede verificar si la primera imagen es la misma que antes (es decir, un hombre a caballo).
Establece el tamaño del lote en 1 porque solo desea alimentar el conjunto de datos con una imagen. Puede ver la dimensión de los datos con print (sess.run (características) .shape). Es igual a (1, 1024). 1 significa que solo se alimenta una imagen con 1024 cada una. Si el tamaño del lote se establece en dos, dos imágenes pasarán por la canalización. (No cambie el tamaño del lote. De lo contrario, arrojará un error. Solo una imagen a la vez puede ir a la función plot_image ().
## Parametersn_inputs = 32 * 32BATCH_SIZE = 1batch_size = tf.placeholder(tf.int64)# using a placeholderx = tf.placeholder(tf.float32, shape=[None,n_inputs])## Datasetdataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()## Print the imagewith tf.Session() as sess:# feed the placeholder with datasess.run(iter.initializer, feed_dict={x: horse_x,batch_size: BATCH_SIZE})print(sess.run(features).shape)plot_image(sess.run(features), shape=[32, 32], cmap = "Greys_r")(1, 1024)
Construye la red
Es hora de construir la red. Entrenará un codificador automático apilado, es decir, una red con múltiples capas ocultas.
Su red tendrá una capa de entrada con 1024 puntos, es decir, 32x32, la forma de la imagen.
El bloque codificador tendrá una capa superior oculta con 300 neuronas, una capa central con 150 neuronas. El bloque del decodificador es simétrico al codificador. Puede visualizar la red en la imagen de abajo. Tenga en cuenta que puede cambiar los valores de las capas centrales y ocultas.
La construcción de un codificador automático es muy similar a cualquier otro modelo de aprendizaje profundo.
Construirá el modelo siguiendo estos pasos:
- Definir los parámetros
- Definir las capas
- Definir la arquitectura
- Definir la optimización
- Ejecuta el modelo
- Evaluar el modelo
En la sección anterior, aprendió cómo crear una canalización para alimentar el modelo, por lo que no es necesario crear una vez más el conjunto de datos. Construirá un codificador automático con cuatro capas. Utiliza la inicialización de Xavier. Esta es una técnica para establecer los pesos iniciales iguales a la varianza tanto de la entrada como de la salida. Finalmente, usa la función de activación elu. Regulariza la función de pérdida con el regularizador L2.
Paso 1) Defina los parámetros
El primer paso implica definir el número de neuronas en cada capa, la tasa de aprendizaje y el hiperparámetro del regularizador.
Antes de eso, importa la función parcialmente. Es un método mejor para definir los parámetros de las capas densas. El siguiente código define los valores de la arquitectura del codificador automático. Como se mencionó anteriormente, el autocodificador tiene dos capas, con 300 neuronas en las primeras capas y 150 en las segundas capas. Sus valores se almacenan en n_hidden_1 y n_hidden_2.
Debe definir la tasa de aprendizaje y el hiperparámetro L2. Los valores se almacenan en learning_rate y l2_reg
from functools import partial## Encodern_hidden_1 = 300n_hidden_2 = 150 # codings## Decodern_hidden_3 = n_hidden_1n_outputs = n_inputslearning_rate = 0.01l2_reg = 0.0001
La técnica de inicialización de Xavier se llama con el objeto xavier_initializer del estimador contrib. En el mismo estimador, puede agregar el regularizador con l2_regularizer
## Define the Xavier initializationxav_init = tf.contrib.layers.xavier_initializer()## Define the L2 regularizerl2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
Paso 2) Defina las capas
Se han configurado todos los parámetros de las capas densas; puede empaquetar todo en la variable dense_layer usando el objeto parcial. dense_layer que utiliza la activación de ELU, la inicialización de Xavier y la regularización de L2.
## Create the dense layerdense_layer = partial(tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer)
Paso 3) Definir la arquitectura
Si observa la imagen de la arquitectura, observará que la red apila tres capas con una capa de salida. En el siguiente código, conectas las capas adecuadas. Por ejemplo, la primera capa calcula el producto escalar entre las características de la matriz de entrada y las matrices que contienen los 300 pesos. Una vez calculado el producto escalar, la salida va a la función de activación de Elu. La salida se convierte en la entrada de la siguiente capa, es por eso que la usa para calcular hidden_2 y así sucesivamente. La multiplicación de matrices es la misma para cada capa porque usa la misma función de activación. Tenga en cuenta que la última capa, salidas, no aplica una función de activación. Tiene sentido porque esta es la entrada reconstruida
## Make the mat mulhidden_1 = dense_layer(features, n_hidden_1)hidden_2 = dense_layer(hidden_1, n_hidden_2)hidden_3 = dense_layer(hidden_2, n_hidden_3)outputs = dense_layer(hidden_3, n_outputs, activation=None)
Paso 4) Defina la optimización
El último paso es construir el optimizador. Utiliza el error cuadrático medio como una función de pérdida. Si recuerda el tutorial sobre regresión lineal, sabrá que el MSE se calcula con la diferencia entre la salida prevista y la etiqueta real. Aquí, la etiqueta es la característica porque el modelo intenta reconstruir la entrada. Por lo tanto, desea la media de la suma de la diferencia del cuadrado entre la salida y la entrada previstas. Con TensorFlow, puede codificar la función de pérdida de la siguiente manera:
loss = tf.reduce_mean(tf.square(outputs - features))
Entonces, necesita optimizar la función de pérdida. Utiliza el optimizador de Adam para calcular los gradientes. La función objetivo es minimizar la pérdida.
## Optimizeloss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Un ajuste más antes de entrenar al modelo. Desea utilizar un tamaño de lote de 150, es decir, alimentar la canalización con 150 imágenes en cada iteración. Necesita calcular el número de iteraciones manualmente. Esto es trivial de hacer:
Si desea pasar 150 imágenes cada vez y sabe que hay 5000 imágenes en el conjunto de datos, el número de iteraciones es igual a. En Python puede ejecutar los siguientes códigos y asegurarse de que la salida sea 33:
BATCH_SIZE = 150### Number of batches : length dataset / batch sizen_batches = horse_x.shape[0] // BATCH_SIZEprint(n_batches)33
Paso 5) Ejecute el modelo
Por último, pero no menos importante, entrena al modelo. Estás entrenando el modelo con 100 épocas. Es decir, el modelo verá 100 veces las imágenes con pesos optimizados.
Ya estás familiarizado con los códigos para entrenar un modelo en Tensorflow. La pequeña diferencia es canalizar los datos antes de ejecutar el entrenamiento. De esta forma, el modelo se entrena más rápido.
Está interesado en imprimir la pérdida después de diez épocas para ver si el modelo está aprendiendo algo (es decir, la pérdida está disminuyendo). La capacitación toma de 2 a 5 minutos, dependiendo del hardware de su máquina.
## Set paramsn_epochs = 100## Call Saver to save the model and re-use it later during evaluationsaver = tf.train.Saver()with tf.Session() as sess:sess.run(tf.global_variables_initializer())# initialise iterator with train datasess.run(iter.initializer, feed_dict={x: horse_x,batch_size: BATCH_SIZE})print('Training… ')print(sess.run(features).shape)for epoch in range(n_epochs):for iteration in range(n_batches):sess.run(train)if epoch % 10 == 0:loss_train = loss.eval() # not shownprint("\r{}".format(epoch), "Train MSE:", loss_train)#saver.save(sess, "./my_model_all_layers.ckpt")save_path = saver.save(sess, "./model.ckpt")print("Model saved in path: %s" % save_path)Training… (150, 1024)0 Train MSE: 2934.45510 Train MSE: 1672.67620 Train MSE: 1514.70930 Train MSE: 1404.311840 Train MSE: 1425.05850 Train MSE: 1479.063160 Train MSE: 1609.525970 Train MSE: 1482.322380 Train MSE: 1445.703590 Train MSE: 1453.8597Model saved in path: ./model.ckpt
Paso 6) Evaluar el modelo
Ahora que ha entrenado su modelo, es hora de evaluarlo. Necesita importar el sert de prueba desde el archivo / cifar-10-batches-py /.
test_data = unpickle('./cifar-10-batches-py/test_batch')test_x = grayscale(test_data['data'])#test_labels = np.array(test_data['labels'])
NOTA: Para una máquina con Windows, el código se convierte en test_data = unpickle (r "E: \ cifar-10-batches-py \ test_batch")
Puedes intentar imprimir las imágenes 13, que es un caballo.
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
Para evaluar el modelo, utilizará el valor de píxel de esta imagen y verá si el codificador puede reconstruir la misma imagen después de reducir 1024 píxeles. Tenga en cuenta que define una función para evaluar el modelo en diferentes imágenes. El modelo debería funcionar mejor solo en caballos.
La función toma dos argumentos:
- df: importar los datos de prueba
- image_number: indica qué imagen importar
La función se divide en tres partes:
- Cambie la forma de la imagen a la dimensión correcta, es decir 1, 1024
- Alimente al modelo con la imagen invisible, codifique / decodifique la imagen
- Imprime la imagen real y reconstruida
def reconstruct_image(df, image_number = 1):## Part 1: Reshape the image to the correct dimension i.e 1, 1024x_test = df[image_number]x_test_1 = x_test.reshape((1, 32*32))## Part 2: Feed the model with the unseen image, encode/decode the imagewith tf.Session() as sess:sess.run(tf.global_variables_initializer())sess.run(iter.initializer, feed_dict={x: x_test_1,batch_size: 1})## Part 3: Print the real and reconstructed image# Restore variables from disk.saver.restore(sess, "./model.ckpt")print("Model restored.")# Reconstruct imageoutputs_val = outputs.eval()print(outputs_val.shape)fig = plt.figure()# Plot realax1 = fig.add_subplot(121)plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r")# Plot estimatedax2 = fig.add_subplot(122)plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r")plt.tight_layout()fig = plt.gcf()
Ahora que la función de evaluación está definida, puede echar un vistazo a la imagen reconstruida número trece.
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckptModel restored.(1, 1024)
Resumen
El propósito principal de un codificador automático es comprimir los datos de entrada y luego descomprimirlos en una salida que se parezca mucho a los datos originales.
La arquitectura de un codificador automático simétrico con una capa de pivote denominada capa central.
Puede crear el codificador automático usando:
- Parcial: para crear las capas densas con la configuración típica:
-
tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer
- dense_layer (): para hacer la multiplicación de matrices
puede definir la función de pérdida y la optimización con:
loss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Ejecute por última vez una sesión para entrenar al modelo.