Búsqueda de sitios web

Implemente Deep Autoencoder en PyTorch para la reconstrucción de imágenes


El aprendizaje automático es una de las ramas de la inteligencia artificial que implica el desarrollo de modelos estadísticos y algoritmos que pueden permitir que una computadora aprenda de los datos de entrada y tome decisiones o predicciones sin estar programada. Implica entrenar los algoritmos de ML con grandes conjuntos de datos para que la máquina pueda identificar patrones y relaciones en los datos.

¿Qué es un codificador automático?

Las arquitecturas de redes neuronales con codificadores automáticos se utilizan para tareas de aprendizaje no supervisadas. Está formado por una red de codificadores y decodificadores que han sido entrenados para reconstruir los datos de entrada comprimiéndolos en una representación de dimensiones inferiores (codificación) y luego decodificandolos para restaurarlos a su forma original.

Para alentar a la red a aprender características o representaciones valiosas de los datos, el objetivo es minimizar el error de reconstrucción entre la entrada y la salida. La compresión de datos, la eliminación de ruido de imágenes y la detección de anomalías son usos destacados de los codificadores automáticos. Esto reduce mucho esfuerzo y costos asociados con la transferencia de datos.

En este artículo, exploraremos cómo utilizar Deep Autoencoder de PyTorch para la reconstrucción de imágenes. Este modelo de aprendizaje profundo se entrenará en los dígitos escritos a mano de MNIST y, después de aprender la representación de las imágenes de entrada, reconstruirá las imágenes de los dígitos. Un codificador automático básico consta de dos funciones principales:

  • El codificador

  • el decodificador

El codificador toma la entrada y convierte los datos de dimensiones superiores en la representación latente de dimensiones bajas de los mismos valores a través de una secuencia de capas. El decodificador utiliza esta representación latente para producir los datos reconstruidos utilizando las bibliotecas de Python torch, las bibliotecas de visión de torch del flujo de trabajo de PyTorch y bibliotecas generales como numpy y matplotlib.

Algoritmo

  • Importe todas las bibliotecas necesarias.

  • Inicialice la operación de transformación que se aplicará a cada entrada en el conjunto de datos obtenido.

  • Dado que los tensores son necesarios para que Pytorch funcione, primero convertimos cada elemento en un tensor y lo normalizamos para preservar el rango de valores de píxeles entre 0 y 1.

  • Usando el programa torchvision.datasets, descargue el conjunto de datos y guárdelo localmente en las carpetas./MNIST/train y./MNIST/test para los conjuntos de entrenamiento y prueba, respectivamente.

  • Para un aprendizaje más rápido, convierta estos conjuntos de datos en cargadores de datos con tamaños de lote iguales a 64.

  • Imprime aleatoriamente 25 fotografías de la colección para que podamos comprender mejor la información con la que estamos trabajando.

Paso 1: inicialización

Este paso implica importar todas las bibliotecas necesarias, como numpy, matplotlib, pytorch y torchvision.

Sintaxis

torchvision.transforms.ToTensor():

convierte la imagen de entrada (en formato PIL o numpy) a un formato tensor de PyTorch. Esta transformación también escala las intensidades de los píxeles desde el rango [0, 255] a [0, 1].

torchvision.transforms.Normalize(mean, std)

normaliza el tensor de la imagen de entrada con un valor de desviación estándar y media. Esta transformación ayuda a mejorar la tasa de convergencia del modelo de aprendizaje profundo durante el entrenamiento. Los valores medios y estándar generalmente se calculan a partir del conjunto de datos de entrenamiento.

torchvision.transforms.Compose(transforms)

permite encadenar múltiples transformaciones de imágenes en un solo objeto. Este objeto se puede pasar al objeto PyTorch Dataset para aplicar las transformaciones sobre la marcha durante el entrenamiento o la inferencia.

Ejemplo

#importing modules
import numpy as np
import matplotlib.pyplot as plt
import torch
from torchvision import datasets, transforms
plt.rcParams['figure.figsize'] = 15, 10

# Initialize the transform operation
transform = torchvision.transforms.Compose([
   torchvision.transforms.ToTensor(),
   torchvision.transforms.Normalize((0.5), (0.5))
])

# Download the inbuilt MNIST data
train_dataset = torchvision.datasets.MNIST(
   root="./MNIST/train", train=True,
   transform=torchvision.transforms.ToTensor(),
   download=True)
test_dataset = torchvision.datasets.MNIST(
   root="./MNIST/test", train=False,
   transform=torchvision.transforms.ToTensor(),
   download=True)

Producción

Paso 2: inicializando el codificador automático

Comenzamos inicializando la clase Autoencoder, una subclase de torch.nn.Module. Ahora podemos concentrarnos en crear nuestra arquitectura modelo, que es la siguiente, porque esto nos abstrae gran parte del código repetitivo.

Sintaxis

torch.nn.Linear()

Un módulo que aplica una transformación lineal al tensor de entrada.

my_linear_layer=nn.Linear(in_features, out_features, sesgo=True)

torch.nn.ReLU() 

Una función de activación que aplica la función de unidad lineal rectificada (ReLU) al tensor de entrada.

torch.nn.Sigmoid() 

Una función de activación que aplica la función sigmoidea al tensor de entrada.

Ejemplo

#Creating the autoencoder classes
class Autoencoder(torch.nn.Module):
   def __init__(self):
      super().__init__()
      self.encoder=torch.nn.Sequential(
         torch.nn.Linear(28*28,128), #N, 784 -> 128
         torch.nn.ReLU(),
         torch.nn.Linear(128,64),
         torch.nn.ReLU(),
         torch.nn.Linear(64,12),
         torch.nn.ReLU(),
         torch.nn.Linear(12,3), # --> N, 3
         torch.nn.ReLU()
      )
        
      self.decoder=torch.nn.Sequential(
         torch.nn.Linear(3,12), #N, 3 -> 12
         torch.nn.ReLU(),
         torch.nn.Linear(12,64),
         torch.nn.ReLU(),
         torch.nn.Linear(64,128),
         torch.nn.ReLU(),
         torch.nn.Linear(128,28*28), # --> N, 28*28
         torch.nn.Sigmoid()
      )
        
   def forward(self,x):
      encoded=self.encoder(x)
      decoded = self.decoder(encoded)
      return decoded

# Instantiating the model and hyperparameters
model = Autoencoder()
criterion = torch.nn.MSELoss()
num_epochs = 10
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

Paso 3: crear un circuito de entrenamiento

Estamos entrenando un modelo de codificador automático para aprender una representación comprimida de imágenes. El ciclo de entrenamiento recorrió el conjunto de datos 10 veces en total.

  • La salida del modelo se calcula para cada lote de fotografías, iterando sobre cada lote de imágenes.

  • Luego se calcula la diferencia de calidad entre las fotografías resultantes y las originales.

  • Promedia la pérdida de cada lote y almacena las imágenes y sus resultados para cada época.

  • Representamos la pérdida de entrenamiento cuando se completa el ciclo para ayudar a comprender el proceso de entrenamiento.

El gráfico demuestra que la pérdida disminuye con cada época que pasa, lo que demuestra que el modelo está recopilando nueva información y que el procedimiento de entrenamiento fue exitoso.

El bucle de entrenamiento entrena el modelo del codificador automático para aprender una representación comprimida de imágenes minimizando la pérdida entre las imágenes de salida y las imágenes originales. La pérdida disminuye con cada época, lo que indica un entrenamiento exitoso.

Ejemplo

# Create empty list to store the training loss
train_loss = []
# Create empty dictionary to store the images and their reconstructed outputs
outputs = {}
# Loop through each epoch
for epoch in range(num_epochs):      
   # Initialize variable for storing the running loss
   running_loss = 0      
   # Loop through each batch in the training data
   for batch in train_loader:
            
      # Load the images and their labels
      img, _ = batch
      # Flatten the images into a 1D tensor
      img = img.view(img.size(0), -1)  
      # Generate the output for the autoencoder model
      out = model(img)     
      # Calculate the loss between the input and output images
      loss = criterion(out, img)          
      # Reset the gradients
      optimizer.zero_grad()          
      # Compute the gradients
      loss.backward()          
      # Update the weights
      optimizer.step()         
      # Increment the running loss by the batch loss
      running_loss += loss.item()      
   # Calculate the average running loss over the entire dataset
   running_loss /= len(train_loader)      
   # Add the running loss to the list of training losses
   train_loss.append(running_loss)      
   # Store the input and output images for the last batch
   outputs[epoch+1] = {'input': img, 'output': out}
  
# Plot the training loss over epochs
plt.plot(range(1, num_epochs+1), train_loss)
plt.xlabel("Number of epochs")
plt.ylabel("Training Loss")
plt.show()

Producción

Paso 4: Visualizar

Las imágenes originales y reconstruidas de un modelo de codificador automático entrenado se trazan utilizando este código. Las salidas variables incluyen datos sobre la salida del modelo, como las imágenes reconstruidas y los valores de pérdida, que se registraron durante varias épocas de entrenamiento. Para trazar las imágenes reconstruidas de épocas particulares, utilice la variable list_epochs.

El programa traza las primeras cinco imágenes reconstruidas del lote más reciente para cada una de las épocas dadas.

Ejemplo

# Plot the re-constructed images
# Initializing the counter
count = 1
# Plotting the reconstructed images
list_epochs = [1, 5, 10]
  
# Iterate over specified epochs
for val in list_epochs:
    
   # Extract recorded information
   temp = outputs[val]['out'].detach().numpy()
   title_text = f"Epoch = {val}"
      
   # Plot first 5 images of the last batch
   for idx in range(5):
      plt.subplot(7, 5, count)
      plt.title(title_text)
      plt.imshow(temp[idx].reshape(28,28), cmap= 'gray')
      plt.axis('off')
          
      # Increment the count
      count+=1
  
# Plot of the original images
  
# Iterating over first five
# images of the last batch
for idx in range(5):
      
   # Obtaining image from the dictionary
   val = outputs[10]['img']
      
   # Plotting image
   plt.subplot(7,5,count)
   plt.imshow(val[idx].reshape(28, 28),
               cmap = 'gray')
   plt.title("Original Image")
   plt.axis('off')
      
   # Increment the count
   count+=1
  
plt.tight_layout()
plt.show()

Producción

Paso 5: Evaluación del rendimiento del conjunto de pruebas

Este código es un ejemplo de cómo evaluar el rendimiento de un modelo de codificador automático entrenado en un conjunto de prueba.

El código concluye que el modelo del codificador automático funcionó bien en el conjunto de prueba según la inspección visual de las imágenes reconstruidas. Si el modelo funciona bien en el conjunto de prueba, es probable que funcione bien con datos nuevos e invisibles.

Ejemplo

outputs = {}
  
# Extract the last batch dataset
img, _ = list(test_loader)[-1]

img = img.reshape(-1, 28 * 28)

#Generating output
out = model(img)
  
# Storing results in the dictionary
outputs['img'] = img
outputs['out'] = out
  
# Initialize subplot count
count = 1
val = outputs['out'].detach().numpy()
  
# Plot first 10 images of the batch
for idx in range(10):
   plt.subplot(2, 10, count)
   plt.title("Reconstructed \n image")
   plt.imshow(val[idx].reshape(28, 28), cmap='gray')
   plt.axis('off')
  
   # Increment subplot count
   count += 1
# Plotting original images
# Plotting first 10 images
for idx in range(10):
   val = outputs['img']
   plt.subplot(2, 10, count)
   plt.imshow(val[idx].reshape(28, 28), cmap='gray')
   plt.title("Original Image")
   plt.axis('off')
   count += 1
  
plt.tight_layout()
plt.show()

Producción

Conclusión

En conclusión, los codificadores automáticos son redes neuronales potentes que se pueden aplicar a muchas tareas diferentes, incluida la compresión de datos, la detección de anomalías y la creación de imágenes. TensorFlow, Keras y PyTorch son algunas herramientas de Python que simplifican el desarrollo del codificador automático. Puede desarrollar modelos de codificadores automáticos extremadamente potentes comprendiendo la arquitectura y modificando la configuración. Los codificadores automáticos probablemente seguirán siendo una herramienta útil para una variedad de aplicaciones a medida que mejore el aprendizaje automático.

Artículos relacionados: