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.

Funcionamiento del codificador automático
Funcionamiento del codificador automático

Funcionamiento del codificador automático

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:

  1. Importar los datos
  2. Convierta los datos a formato blanco y negro.
  3. Agregar todos los lotes
  4. Construir el conjunto de datos de entrenamiento
  5. 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")

Construir un visualizador de imágenes

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)

Establecer estimador de conjunto de datos

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.

Construya la red
Construyendo la red para Autoencoder

Crear un codificador automático es muy similar a cualquier otro modelo de aprendizaje profundo.

Construirás el modelo siguiente.wing Estos pasos:

  1. Definir los parámetros
  2. Definir las capas
  3. Definir el architectura
  4. Definir la optimización
  5. Ejecute el modelo
  6. 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")

Evaluar el modelo

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:

  1. Cambie la forma de la imagen a la dimensión correcta, es decir, 1, 1024
  2. Alimente el modelo con la imagen invisible, codifique/decodifique la imagen
  3. 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)

Evaluar el modelo

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

  • 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 el modelo.