Guida Pratica a PyTorch: Come Creare e Addestrare la Tua Prima Rete Neurale in Python

Negli ultimi anni l’Intelligenza Artificiale ha rivoluzionato il mondo della tecnologia: dai generatori di immagini ai modelli linguistici come ChatGPT. Alla base di quasi tutte queste innovazioni c’è un framework fondamentale: PyTorch. Sviluppato originariamente da Meta e adottato oggi da giganti come Apple, Tesla e OpenAI, PyTorch è diventato lo standard de facto per ricercatori e sviluppatori di Deep Learning .

In questa guida pratica vedremo passo dopo passo come costruire e addestrare la tua prima rete neurale in Python, comprendendo cosa succede davvero “sotto il cofano”.


1. Cos’è un Modello AI e Come Impara?

A livello concettuale, possiamo pensare a un modello di Intelligenza Artificiale come a una scatola nera: riceve un dato in input (X) (un numero, un testo o un’immagine) e restituisce un dato in output (Y).

Perché il modello sia in grado di svolgere questo compito, deve essere addestrato fornendogli degli esempi storici di coppie (X, Y).

L’addestramento si basa su un ciclo continuo (chiamato Training Loop) composto da 4 passaggi chiave :

  1. Forward Pass: Il modello riceve l’input X e calcola una previsione Y .
  2. Funzione di Loss (o di Perdita): Si confronta la previsione del modello con il valore reale Y per calcolare l’errore commesso .
  3. Backward Pass (Retropropagazione): Si calcolano i gradienti, ovvero la direzione e l’intensità con cui ciascun parametro del modello ha contribuito all’errore .
  4. Ottimizzatore (Optimizer): Un algoritmo (come Adam o SGD) aggiorna i parametri del modello per ridurre progressivamente l’errore, sfruttando un parametro chiamato Learning Rate .

2. Il Nostro Problema Pratico: Calcolare il Costo di una Corsa

Nel mondo reale spesso vogliamo prevedere una grandezza a partire da un’altra. Immagina di voler stimare il costo finale in euro (Y) di un servizio di trasporto o consegna espressa a partire dai chilometri percorsi (X).

Generalmente, il costo segue una formula lineare:

{Costo} = ({Costo al km} X {Distanza}) + {Tariffa fissa di partenza}

Supponiamo di non conoscere in anticipo questi valori e di avere a disposizione soltanto uno storico di corse con le relative distanze e i prezzi pagati (con un pizzico di rumore dovuto al traffico). Chiederemo alla nostra rete neurale di scoprire da sola questa relazione!


3. Preparazione dell’Ambiente e Creazione dei Dati

Se non hai PyTorch installato, puoi farlo in un attimo tramite terminale:

pip install torch matplotlib

(In alternativa, puoi eseguire il codice gratuitamente su Google Colab senza dover installare nulla sul tuo computer).

Iniziamo importando le librerie necessarie e creando i nostri dati di addestramento:

import torch
import torch.nn as nn
import matplotlib.pyplot as plt

# Dati di esempio: Distanza percorsa in km (Input X)
x_km = torch.tensor([[2.0], [5.0], [8.0], [12.0], [15.0], [20.0], [25.0]], dtype=torch.float32)

# Costo effettivo registrato in € (Output reale Y)
# Relazione reale nascosta: ~ 1.80€/km + 3.50€ di scatto fisso (con minime variazioni)
y_prezzo = torch.tensor([[7.2], [12.6], [17.8], [25.0], [30.4], [39.6], [48.3]], dtype=torch.float32)

Nota sui Tensori: In PyTorch i dati non vengono gestiti come normali liste Python, ma sotto forma di Tensori (torch.Tensor) . I tensori sono matrici multidimensionali ottimizzate per eseguire calcoli matematici ad altissima velocità su CPU o schede video (GPU).


4. Definire il Modello: Un Singolo Neurone Artificiale

La forma più elementare di rete neurale è costituita da un singolo neurone lineare . Matematicamente, un neurone lineare esegue l’operazione:

Y = W * X + B

Dove:

  • W (Weight / Peso): rappresenta il coefficiente angolare (nel nostro caso, la tariffa al km).
  • B (Bias): rappresenta l’intercetta (nel nostro caso, la tariffa fissa di partenza).

In PyTorch, possiamo definire questo modello con una sola riga di codice tramite nn.Linear:

# 1 input (km) -> 1 output (prezzo in €)
model = nn.Linear(in_features=1, out_features=1)

All’inizio, PyTorch assegna a W e B dei valori casuali. Se provassimo a chiedere una stima adesso, il risultato sarebbe completamente sballato. Dobbiamo quindi addestrarlo!


5. Loss Function e Ottimizzatore

Prima di avviare l’addestramento, dobbiamo stabilire come misurare l’errore e come aggiornare i pesi:

# 1. Funzione di Loss: Mean Squared Error (errore quadratico medio)
criterion = nn.MSELoss()

# 2. Ottimizzatore: Adam, con un Learning Rate di 0.05
optimizer = torch.optim.Adam(model.parameters(), lr=0.05)
  • nn.MSELoss: Calcola la media dei quadrati delle differenze tra i prezzi previsti e quelli effettivi.
  • torch.optim.Adam: È uno degli ottimizzatori più efficienti e diffusi nel Deep Learning .
  • lr (Learning Rate): La velocità di apprendimento. Se è troppo basso, il modello impiegherà troppo tempo a convergere; se è troppo alto, l’apprendimento potrebbe diventare instabile. Un valore compreso tra 0.01 e 0.1 è solitamente un ottimo punto di partenza .

6. Il Training Loop: Addestriamo la Rete

Ecco il ciclo di addestramento che ripete i 4 step fondamentali per un certo numero di epoche (ripetizioni):

epochs = 800

for epoch in range(epochs):
    # STEP 1: Forward pass (calcolo delle previsioni)
    y_pred = model(x_km)
    
    # STEP 2: Calcolo della loss (errore)
    loss = criterion(y_pred, y_prezzo)
    
    # STEP 3: Backward pass (azzeramento gradienti precedenti e calcolo dei nuovi)
    optimizer.zero_grad()
    loss.backward()
    
    # STEP 4: Aggiornamento dei parametri del modello
    optimizer.step()
    
    # Monitoraggio ogni 100 epoche
    if (epoch + 1) % 100 == 0:
        print(f"Epoca [{epoch+1}/{epochs}] - Errore (Loss): {loss.item():.4f}")

Vedrai il valore della Loss scendere drasticamente da valori elevati fino a valori vicini allo zero: il modello sta imparando a interpretare i dati!


7. Verifica dei Risultati e Ispezione dei Parametri

Ora che il modello è addestrato, proviamo a stimare il costo di una corsa di 18 km (un valore che il modello non ha mai visto durante l’addestramento):

# Convertiamo il valore 18 in tensore
distanza_nuova = torch.tensor([[18.0]])

# Chiediamo al modello la previsione (disattivando il calcolo dei gradienti per risparmiare risorse)
with torch.no_grad():
    prezzo_stimato = model(distanza_nuova)

print(f"Prezzo stimato per 18 km: {prezzo_stimato.item():.2f} €")

Il modello restituirà un valore attorno a 35.90 €.

Ma cosa ha effettivamente imparato il nostro neurone artificiale? Andiamo a leggere direttamente i parametri W e B:

peso_w = model.weight.item()
bias_b = model.bias.item()

print(f"Peso appreso (W - Costo stimato al km): {peso_w:.2f} €")
print(f"Bias appreso (B - Tariffa fissa stimata): {bias_b:.2f} €")

Troverai valori vicinissimi a:

  • W ~ 1.80 (circa 1.80 € al km)
  • B ~ 3.50 (circa 3.50 € di tariffa iniziale)

Senza che nessuno gli abbia mai scritto le regole esplicite, la rete neurale ha scoperto da sola la formula analizzando i dati!


8. Oltre il Neurone Singolo: Perché Serve il Deep Learning?

In questo esempio la relazione tra chilometri e costo era pressoché lineare (una linea retta) .

Ma cosa succede se il fenomeno che vogliamo descrivere non è lineare? Immagina ad esempio:

  • Il tempo di frenata o di caduta libera di un corpo (che segue leggi quadratiche) .
  • Le tariffe a scaglioni o con sovrapprezzo notturno/festivo ad andamento irregolare.
  • Riconoscere un animale in una foto o generare testo.

In tutti questi scenari complessi, una singola linea retta non basta più . Per risolvere problemi non lineari è necessario passare a vere e proprie reti multistrato (Deep Learning), aggiungendo:

  1. Hidden Layers (Strati Nascosti): Più strati di neuroni collegati in sequenza .
  2. Funzioni di Attivazione Non Lineari (come ReLU o Sigmoide): Permettono alla rete di piegare e curvare la linea di decisione per adattarsi a forme e andamenti arbitrari.

Conclusione

Congratulazioni! Hai appena costruito, configurato e addestrato la tua prima rete neurale in PyTorch. Sebbene si tratti di un modello a singolo neurone, il processo concettuale e il ciclo di addestramento che hai appena implementato (Forward, Loss, Backward, Optimizer) sono gli stessi identici mattoni utilizzati per addestrare i modelli di Intelligenza Artificiale più avanzati del pianeta .

Ti interessa acquistare un dominio a prezzi ultraconvenienti? clicca qui

Se hai trovato utili le informazioni su questo blog,
Fai una donazione!
Clicca sul bottone qui sotto o almeno clicca sul banner pubblicitario 🙂



Commenta