Per chi inizia con PyTorch, un ottimo punto di partenza è la creazione di un Multilayer Perceptron (MLP), una rete neurale semplice ma fondamentale per comprendere i principi alla base del deep learning. In questo articolo, guideremo passo passo nella costruzione di un MLP in PyTorch, spiegando i concetti chiave lungo il percorso.
Prima di iniziare a scrivere codice, è importante comprendere cosa sia un MLP. In sostanza, un MLP è una rete neurale composta da più strati di neuroni interconnessi. Questi strati sono tipicamente divisi in tre categorie: lo strato di input, uno o più strati nascosti e lo strato di output. Lo strato di input riceve i dati di ingresso, ogni strato nascosto elabora i dati ricevuti dallo strato precedente, e lo strato di output fornisce il risultato finale del modello.
Ogni connessione tra i neuroni ha un peso associato, che rappresenta la forza della connessione. Durante l'addestramento, questi pesi vengono modificati per minimizzare l'errore tra la predizione del modello e il valore reale. Questa modifica dei pesi avviene attraverso un algoritmo di ottimizzazione, spesso l'algoritmo di discesa del gradiente, che utilizza il calcolo del gradiente dell'errore rispetto ai pesi per aggiornare questi ultimi iterativamente.
In PyTorch, la costruzione di un MLP coinvolge l'utilizzo di due componenti principali: torch.nn
per definire l'architettura della rete e torch.optim
per definire l'ottimizzatore. torch.nn
fornisce classi per creare strati di neuroni, come nn.Linear
per gli strati completamente connessi (fully connected), e funzioni di attivazione, come nn.ReLU
(Rectified Linear Unit) o nn.Sigmoid
. torch.optim
offre diverse implementazioni di algoritmi di ottimizzazione, tra cui Adam, SGD (Stochastic Gradient Descent) e RMSprop.
Cominciamo creando un semplice MLP con un singolo strato nascosto. Supponiamo di voler creare un modello per un problema di classificazione binaria (es. classificare immagini come "gatto" o "cane"). Il nostro modello avrà uno strato di input, uno strato nascosto con, ad esempio, 64 neuroni, e uno strato di output con un singolo neurone (per la probabilità di appartenenza a una delle due classi).
import torch
import torch.nn as nn
import torch.optim as optim
class MLP(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(MLP, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_size, output_size)
self.sigmoid = nn.Sigmoid() # Funzione di attivazione per la classificazione binaria
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
out = self.sigmoid(out)
return out
# Definiamo le dimensioni degli strati
input_size = 784 # Esempio: immagini 28x28
hidden_size = 64
output_size = 1
# Creiamo un'istanza del modello
model = MLP(input_size, hidden_size, output_size)
# Definiamo l'ottimizzatore (Adam in questo caso)
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Definiamo la funzione di loss (Binary Cross Entropy per la classificazione binaria)
criterion = nn.BCELoss()
Questo codice definisce una classe MLP
che eredita da nn.Module
. Il metodo __init__
inizializza i due strati completamente connessi (fc1
e fc2
) e le funzioni di attivazione ReLU e Sigmoid. Il metodo forward
definisce il flusso dei dati attraverso la rete. Notiamo l'utilizzo di nn.Sigmoid
nello strato di output, appropriato per la classificazione binaria in quanto fornisce un output compreso tra 0 e 1, interpretabile come probabilità.
Successivamente, vengono definiti l'ottimizzatore (Adam con un learning rate di 0.001) e la funzione di loss (Binary Cross Entropy, adatta per problemi di classificazione binaria). La scelta dell'ottimizzatore e della funzione di loss è cruciale e dipende dal tipo di problema e dal dataset.
Il codice sopra mostra solo la parte di definizione del modello. Per addestrare il modello, è necessario iterare sui dati di training, calcolare la loss, calcolare il gradiente e aggiornare i pesi usando l'ottimizzatore. Questo processo, spesso chiamato backpropagation, è automatizzato da PyTorch grazie al meccanismo di autograd. L'addestramento richiede l'utilizzo di un dataset e un ciclo di training appropriato, che non vengono mostrati qui per semplicità, ma sono essenziali per completare il processo di apprendimento del modello.
In conclusione, la costruzione di un MLP in PyTorch è un processo relativamente semplice, ma richiede una comprensione dei concetti fondamentali delle reti neurali e delle tecniche di ottimizzazione. Questo esempio fornisce una solida base per iniziare a esplorare il mondo del deep learning con PyTorch, aprendo la strada a modelli più complessi e potenti. Ricorda che questo è solo un punto di partenza: la sperimentazione con diverse architetture, funzioni di attivazione, ottimizzatori e iperparametri è fondamentale per ottenere risultati ottimali. Buon lavoro!