Ricerca nel sito web

Implementa Deep Autoencoder in PyTorch per la ricostruzione delle immagini


L'apprendimento automatico è uno dei rami dell'intelligenza artificiale che prevede lo sviluppo di modelli statistici e algoritmi che possano consentire a un computer di apprendere dai dati di input e prendere decisioni o previsioni senza essere fortemente programmato. Implica l’addestramento degli algoritmi ML con set di dati di grandi dimensioni in modo che la macchina possa identificare modelli e relazioni nei dati.

Cos'è un codificatore automatico?

Le architetture di rete neurale con codificatori automatici vengono utilizzate per attività di apprendimento non supervisionato. È costituito da una rete di codificatori e decodificatori che sono stati addestrati a ricostruire i dati di input comprimendoli in una rappresentazione dimensionale inferiore (codifica) e quindi decodificandoli per riportarli alla sua forma originale.

Per incoraggiare la rete ad apprendere caratteristiche o rappresentazioni preziose dei dati, l'obiettivo è ridurre al minimo l'errore di ricostruzione tra input e output. La compressione dei dati, la rimozione del rumore delle immagini e il rilevamento delle anomalie sono usi importanti per gli autoencoder. Ciò riduce molti sforzi e costi associati al trasferimento dei dati.

In questo articolo esploreremo come utilizzare il Deep Autoencoder di PyTorch per la ricostruzione delle immagini. Questo modello di deep learning verrà addestrato sulle cifre scritte a mano del MNIST e, dopo aver appreso la rappresentazione delle immagini di input, ricostruirà le immagini delle cifre. Un autoencoder di base è costituito da due funzioni principali: −

  • Il codificatore

  • Il decodificatore

Il codificatore prende l'input e converte i dati di dimensione superiore nella rappresentazione latente di dimensione bassa degli stessi valori attraverso una sequenza di strati. Questa rappresentazione latente viene utilizzata dal decodificatore per produrre i dati ricostruiti utilizzando le librerie Python torch, le librerie di visione della torcia dal flusso di lavoro PyTorch e le librerie generali come numpy e matplotlib.

Algoritmo

  • Importa tutte le librerie richieste.

  • Inizializza l'operazione di trasformazione che verrà applicata a ogni voce nel set di dati ottenuto.

  • Poiché i tensori sono necessari per il funzionamento di Pytorch, convertiamo prima ogni elemento in un tensore e lo normalizziamo per preservare l'intervallo di valori dei pixel compreso tra 0 e 1.

  • Utilizzando il programma torchvision.datasets, scaricare il set di dati e salvarlo localmente nelle cartelle./MNIST/train e./MNIST/test rispettivamente per i set di addestramento e di test.

  • Per un apprendimento più rapido, converti questi set di dati in caricatori di dati con dimensioni batch pari a 64.

  • Stampa in modo casuale 25 fotografie dalla collezione per permetterci di comprendere meglio le informazioni con cui stiamo lavorando.

Passaggio 1: inizializzazione

Questo passaggio prevede l'importazione di tutte le librerie necessarie, come numpy, matplotlib, pytorch e torchvision.

Sintassi

torchvision.transforms.ToTensor():

converte l'immagine in input (in formato PIL o numpy) in un formato tensore PyTorch. Questa trasformazione scala anche le intensità dei pixel dall'intervallo da [0, 255] a [0, 1].

torchvision.transforms.Normalize(mean, std)

normalizza il tensore dell'immagine in ingresso con un valore medio e deviazione standard. Questa trasformazione aiuta a migliorare il tasso di convergenza del modello di deep learning durante la formazione. I valori medi e std vengono generalmente calcolati dal set di dati di addestramento.

torchvision.transforms.Compose(transforms)

consente di concatenare più trasformazioni di immagini in un singolo oggetto. Questo oggetto può essere passato all'oggetto PyTorch Dataset per applicare le trasformazioni al volo durante il training o l'inferenza.

Esempio

#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)

Produzione

Passaggio 2: inizializzazione dell'autoencoder

Iniziamo inizializzando la classe Autoencoder, una sottoclasse di torch.nn.Module. Ora possiamo concentrarci sulla creazione del nostro modello di architettura, che è il seguente, perché questo astrae gran parte del codice standard per noi.

Sintassi

torch.nn.Linear()

Un modulo che applica una trasformazione lineare al tensore di input.

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

torch.nn.ReLU() 

Una funzione di attivazione che applica la funzione dell'unità lineare rettificata (ReLU) al tensore di ingresso.

torch.nn.Sigmoid() 

Una funzione di attivazione che applica la funzione sigmoidea al tensore di input.

Esempio

#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)

Passaggio 3: creazione di un ciclo di formazione

Stiamo addestrando un modello di codifica automatica per apprendere una rappresentazione compressa delle immagini. Il ciclo di addestramento ha esaminato il set di dati 10 volte in totale.

  • L'output del modello viene calcolato per ogni batch di foto, eseguendo un'iterazione su ogni batch di immagini.

  • Viene quindi calcolata la differenza di qualità tra le foto di output e le immagini originali.

  • Calcola la media della perdita per ciascun lotto e memorizza le immagini e i relativi risultati per ciascuna epoca.

  • Descriviamo la perdita di allenamento quando il ciclo è completo per aiutare a comprendere il processo di allenamento.

Il grafico dimostra che la perdita diminuisce con il passare delle epoche, dimostrando che il modello sta raccogliendo nuove informazioni e che la procedura di addestramento ha avuto successo.

Il ciclo di addestramento addestra il modello di codifica automatica ad apprendere una rappresentazione compressa delle immagini riducendo al minimo la perdita tra le immagini di output e le immagini originali. La perdita diminuisce con ogni epoca, indicando un addestramento di successo.

Esempio

# 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()

Produzione

Passaggio 4: visualizzazione

Le immagini originali e ricostruite di un modello di codifica automatica addestrato vengono tracciate utilizzando questo codice. Gli output variabili includono dati sull'output del modello, come le immagini ricostruite e i valori di perdita, che sono stati registrati durante varie epoche di addestramento. Per tracciare le immagini ricostruite di epoche particolari, utilizzare la variabile list_epochs.

Il programma traccia le prime cinque immagini ricostruite dal lotto più recente per ciascuna delle epoche indicate.

Esempio

# 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()

Produzione

Passaggio 5: valutazione delle prestazioni del set di test

Questo codice è un esempio di come valutare le prestazioni di un modello di codifica automatica addestrato su un set di test.

Il codice conclude che il modello di codifica automatica ha funzionato bene sul set di test basato sull'ispezione visiva delle immagini ricostruite. Se il modello funziona bene sul set di test, è probabile che funzioni bene anche su dati nuovi e invisibili.

Esempio

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()

Produzione

Conclusione

In conclusione, gli autoencoder sono reti neurali potenti che possono essere applicate a molti compiti diversi, tra cui la compressione dei dati, il rilevamento di anomalie e la creazione di immagini. TensorFlow, Keras e PyTorch sono alcuni strumenti Python che semplificano lo sviluppo del codificatore automatico. Puoi sviluppare modelli di codifica automatica estremamente potenti comprendendo l'architettura e modificando le impostazioni. I codificatori automatici probabilmente continueranno a essere uno strumento utile per una varietà di applicazioni man mano che l'apprendimento automatico migliora in questo campo.

Articoli correlati: