Codificador automático en TensorFlow con ejemplo
¿Qué es el codificador automático en el aprendizaje profundo?
An Codificador automático 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 entrenando la red neuronal para que ignore 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 red codifica la entrada para centrarse solo en la característica más crítica. Ésta es una de las razones por las que el codificador automático es popular para la reducción de dimensionalidad. Además, los codificadores automáticos se pueden utilizar para producir modelos de aprendizaje generativo. Por ejemplo, la red neuronal se puede entrenar con un conjunto de caras y luego producir caras nuevas.
¿Cómo funciona el codificador automático TensorFlow?
El propósito de un codificador automático es producir una aproximación de la entrada centrándose sólo en las características esenciales. Quizás pienses por qué no simplemente aprender 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, distintas de simplemente copiar la salida.
Un codificador automático típico se define con una entrada, una representación interna y una salida (una aproximación de la entrada). El aprendizaje se produce 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 siguiente, 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 es penalizado si el resultado de la reconstrucción es diferente de la entrada.
Concretamente, imaginemos una imagen con un tamaño de 50×50 (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. Esto 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 codificador automático apilado. El archiLa tecnología es similar a una red neuronal tradicional. La entrada pasa a una capa oculta para ser comprimida, o reducir su tamaño, y luego llega a las capas de reconstrucción. El objetivo es producir una imagen de salida tan parecida a la original. El modelo tiene que aprender una manera de lograr su tarea bajo un conjunto de restricciones, es decir, con una dimensión más baja.
Hoy en día, los codificadores automáticos en Aprendizaje profundo Se utilizan principalmente para eliminar el ruido de una imagen. Imagina una imagen con rayones; un humano todavía es capaz de 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 así puede producir caras nuevas.
Cómo construir un codificador automático con TensorFlow
En este tutorial, aprenderá cómo construir un codificador automático apilado para reconstruir una imagen.
Usarás el Conjunto de datos CIFAR-10 que contiene 60000 imágenes en color de 32 × 32. El conjunto de datos de Autoencoder ya está dividido entre 50000 imágenes para entrenamiento y 10000 para prueba. Hay hasta diez clases:
- Avión
- Automobile
- Pájaro
- Gato
- Ciervo
- Perro
- rana
- caballo
- Enviar
- Camión
Necesita descargar las imágenes en esta URL https://www.cs.toronto.edu/~kriz/cifar.html y descomprimirlas. La carpeta for-10-batches-py contiene cinco lotes de datos con 10000 imágenes cada uno en orden aleatorio.
Antes de construir y entrenar su modelo, debe aplicar algo de procesamiento de datos. Procederá de la siguiente manera:
- Importar los datos
- Convierta los datos a formato blanco y negro.
- Agregar todos los lotes
- Construir el conjunto de datos de entrenamiento
- Construir un visualizador de imágenes.
Preprocesamiento de imágenes
Paso 1) Importar los datos
Según el sitio web oficial, puedes subir los datos con el siguientewing código. El código Autoencoder cargará los datos en un diccionario con el datos y Label. Tenga en cuenta que el código es una función.
import numpy as np import tensorflow as tf import pickle def unpickle(file): import pickle with open(file, 'rb') as fo: dict = pickle.load(fo, encoding='latin1') return dict
Paso 2) Convertir los datos a formato blanco y negro
Para simplificar, convertirá los datos a escala de grises. Es decir, con una sola dimensión frente a tres para la imagen de colores. La mayor parte de las redes neuronales funcionan 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 ambas funciones están creadas y el conjunto de datos cargado, puede escribir un bucle para agregar los datos en la memoria. Si revisa cuidadosamente, 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 memory data, labels = [], [] ## Loop over the b for 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 Windows máquina, 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 sencillo, entrenará un modelo únicamente con las imágenes de los caballos. 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 5.000 imágenes con 1024 columnas como se muestra a continuación TensorFlow Paso de ejemplo del codificador automático.
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 sencilla de imprimir imágenes es utilizar 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 inline import matplotlib import matplotlib.pyplot as plt def 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, puedes comenzar a usar Tensorflow. Antes de construir el modelo, usemos el estimador de conjunto de datos de Tensorflow para alimentar la red.
Construirás un conjunto de datos con el estimador TensorFlow. Para refrescar tu mente, necesitas 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 el siguientewing forma:
- [Ninguno, n_inputs]: establecido en Ninguno porque el número de imágenes enviadas a la red es igual al tamaño del lote.
para details, consulte el tutorial sobre regresión lineal.
Después de eso, necesitas crear el iterador. Sin esta línea de código, ningún dato pasará por el proceso.
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(features).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, entonces pasarán dos imágenes por el proceso. (No cambie el tamaño del lote. Otroswise, arrojará un error. Sólo una imagen a la vez puede ir a la función plot_image().
## Parameters n_inputs = 32 * 32 BATCH_SIZE = 1 batch_size = tf.placeholder(tf.int64) # using a placeholder x = tf.placeholder(tf.float32, shape=[None,n_inputs]) ## Dataset dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size) iter = dataset.make_initializable_iterator() # create the iterator features = iter.get_next() ## Print the image with tf.Session() as sess: # feed the placeholder with data sess.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ás 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, 32×32, la forma de la imagen.
El bloque codificador tendrá una capa superior oculta con 300 neuronas y una capa central con 150 neuronas. El bloque decodificador es simétrico al codificador. Puedes visualizar la red en la imagen de abajo. Tenga en cuenta que puede cambiar los valores de las capas central y oculta.
Crear un codificador automático es muy similar a cualquier otro modelo de aprendizaje profundo.
Construirás el modelo siguiente.wing Estos pasos:
- Definir los parámetros
- Definir las capas
- Definir el architectura
- Definir la optimización
- Ejecute el modelo
- Evaluar el modelo
En la sección anterior, aprendiste 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ás 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, utiliza la función de activación elu. Regularizas la función de pérdida con el regularizador L2.
Paso 1) Definir 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 mejor método para definir los parámetros de las capas densas. El siguiente código define los valores del codificador automático. architectura. Como se mencionó anteriormente, el codificador automático tiene dos capas, con 300 neuronas en la primera capa y 150 en la segunda capa. 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 ## Encoder n_hidden_1 = 300 n_hidden_2 = 150 # codings ## Decoder n_hidden_3 = n_hidden_1 n_outputs = n_inputs learning_rate = 0.01 l2_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, puedes agregar el regularizador con l2_regularizer
## Define the Xavier initialization xav_init = tf.contrib.layers.xavier_initializer() ## Define the L2 regularizer l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
Paso 2) Definir las capas
Se han establecido todos los parámetros de las capas densas; puedes empaquetar todo en la variable densa_layer usando el objeto parcial. densa_capa que utiliza la activación ELU, la inicialización de Xavier y la regularización L2.
## Create the dense layer dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer)
Paso 3) Definir el architectura
Si miras la foto del architecture, observa que la red apila tres capas con una capa de salida. En el código siguiente, conecta las capas apropiadas. 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 pasa 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 usas para calcular oculto_2 y así sucesivamente. La multiplicación de matrices es la misma para cada capa porque usas 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 mul hidden_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) Definir la optimización
El último paso es construir el optimizador. Se utiliza el error cuadrático medio como 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 obtener la media de la suma de la diferencia del cuadrado entre la salida y la entrada previstas. Con TensorFlow, puedes codificar la función de pérdida de la siguiente manera:
loss = tf.reduce_mean(tf.square(outputs - features))
Luego, es necesario optimizar la función de pérdida. Utiliza el optimizador Adam para calcular los gradientes. La función objetivo es minimizar la pérdida.
## Optimize loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)
Una configuración más antes de entrenar el modelo. Desea utilizar un tamaño de lote de 150, es decir, alimentar la canalización con 150 imágenes en cada iteración. Debe 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 puedes ejecutar lo siguiente.wing códigos y asegúrese de que la salida sea 33:
BATCH_SIZE = 150 ### Number of batches : length dataset / batch size n_batches = horse_x.shape[0] // BATCH_SIZE print(n_batches) 33
Paso 5) Ejecute el modelo
Por último, pero no menos importante, entrena el 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 ligera diferencia es canalizar los datos antes de ejecutar el entrenamiento. De esta forma, el modelo se entrena más rápido.
Le interesa 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 dura de 2 a 5 minutos, dependiendo del hardware de su máquina.
## Set params n_epochs = 100 ## Call Saver to save the model and re-use it later during evaluation saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # initialise iterator with train data sess.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 shown print("\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.455 10 Train MSE: 1672.676 20 Train MSE: 1514.709 30 Train MSE: 1404.3118 40 Train MSE: 1425.058 50 Train MSE: 1479.0631 60 Train MSE: 1609.5259 70 Train MSE: 1482.3223 80 Train MSE: 1445.7035 90 Train MSE: 1453.8597 Model saved in path: ./model.ckpt
Paso 6) Evaluar el modelo
Ahora que ya tiene su modelo entrenado, es momento de evaluarlo. Debe importar el servidor 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 Windows máquina, 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 usted define una función para evaluar el modelo en diferentes imágenes. El modelo debería funcionar mejor sólo en caballos.
La función toma dos argumentos:
- df: Importar los datos de prueba
- número_imagen: 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 el 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, 1024 x_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 image with 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 image outputs_val = outputs.eval() print(outputs_val.shape) fig = plt.figure() # Plot real ax1 = fig.add_subplot(121) plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r") # Plot estimated ax2 = 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.ckpt Model restored. (1, 1024)
Resumen
- El objetivo 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.
- En archiEstructura de un codificador automático simétrico con una capa 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
capa_densa(): para hacer la multiplicación de matrices
loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)