Python, dalle fondamenta Lezione 55 / 60

Neural network spiegate semplice

Cos'è davvero una neural network, perché la backpropagation funziona, e dove il deep learning batte sul serio il machine learning classico.

Se hai passato un po’ di tempo su internet nell’ultimo decennio, hai assorbito l’impressione che “neural network” voglia dire “magia”. Non è così. Una neural network è una funzione. Gli input entrano da un lato, gli output escono dall’altro, e una grossa pila di numeri regolabili in mezzo decide come gli input diventano output. Tutta la premessa è qui. Tutto il resto, la backpropagation, il gradient descent, l’intero canone del deep learning, è impalcatura intorno a questa singola idea.

Questa lezione è volutamente povera di codice. Il modulo 10 avrà un sacco di PyTorch, un sacco di training loop, un sacco di ansia da memoria GPU. Prima che tutto questo arrivi, voglio che il modello mentale clicchi. Se capisci cosa una neural network è, la matematica al suo nucleo, perché la non linearità è importante, cosa la backpropagation sta davvero facendo, ogni decisione di framework nelle prossime due lezioni sembrerà ovvia invece che misteriosa.

Una neural network è una funzione

Pensa al classifier più semplice possibile. Input: un vettore x con due numeri. Output: una probabilità, un singolo numero tra 0 e 1. La funzione che vogliamo è f(x) -> p. Se la scriviamo come una catena di operazioni, potrebbe sembrare così:

z1 = W1 @ x + b1     # linear: matrice per vettore, piu' bias
a1 = relu(z1)        # non linearita'
z2 = W2 @ a1 + b2    # un'altra linear
p  = sigmoid(z2)     # schiaccia a [0, 1]

W1, W2, b1, b2 sono i parametri. Tutto il resto è fissato. Allenare una neural network vuol dire: trovare valori per quei parametri tali che, in media, f(x) sia vicino alla risposta giusta per ogni esempio di training che abbiamo.

È tutto qui il gioco. La loss function, il gradient descent, tutto quanto, esiste per trovare buoni valori per quelle matrici W e b.

Il neuron, demistificato

Un “neuron” è l’unità più piccola di tutta questa costruzione. Prende un vettore di input x = [x1, x2, ..., xn], moltiplica ognuno per un weight, aggiunge un bias, e fa passare il risultato attraverso una funzione non lineare:

output = activation(w1*x1 + w2*x2 + ... + wn*xn + b)

La somma pesata è solo un dot product. Il bias è solo un numero. La non linearità è una di queste:

  • ReLU: max(0, z). Economica, il cavallo di battaglia del deep learning. Se l’input è negativo, l’output è zero. Altrimenti, lascialo passare.
  • GELU: curva liscia a forma di ReLU. Standard nei transformer dal 2018 circa.
  • Sigmoid: 1 / (1 + exp(-z)). Schiaccia a (0, 1). Usata all’output dei classifier binari; raramente usata dentro la rete ormai perché ammazza i gradient.
  • Tanh: come la sigmoid ma schiaccia a (-1, 1). Stesso problema.

Un “layer” è semplicemente molti neuron che condividono lo stesso vettore di input ma con weight diversi. Se l’input è un vettore a 100 dimensioni e un layer ha 64 neuron, la weight matrix del layer è (64, 100). Un layer è una moltiplicazione di matrici seguita da una non linearità. Una rete è diversi layer impilati.

Perché la non linearità è il punto centrale

Ecco la cosa che suona sempre come un tecnicismo ma in realtà è portante. Supponi di impilare due linear layer senza una non linearità in mezzo:

y = W2 @ (W1 @ x + b1) + b2
  = W2 @ W1 @ x + W2 @ b1 + b2
  = W' @ x + b'

Dove W' = W2 @ W1 e b' = W2 @ b1 + b2. Questo è solo un linear layer. Puoi impilare mille linear layer e l’intera pila collassa a una singola funzione lineare. Non hai imparato niente andando in profondità. Il modello può solo tracciare linee rette nello spazio degli input, e la maggior parte dei problemi reali non ha frontiere di decisione a linea retta.

La non linearità tra i layer è ciò che impedisce il collasso. ReLU basta. Il “teorema di approssimazione universale” dice, grosso modo: una neural network con almeno un hidden layer e una non linearità può approssimare qualsiasi funzione continua, dati abbastanza neuron. In pratica, più layer sono drammaticamente più efficienti di singoli layer più larghi, è l’osservazione empirica che ha dato i natali al “deep” learning.

Backpropagation, in parole semplici

Hai una rete. Produce predizioni. Confronti le predizioni con la verità e calcoli una loss, un singolo numero che dice quanto la rete si è sbagliata. Per la classificazione, è di solito cross-entropy. Per la regressione, mean squared error.

Vuoi spostare ogni parametro in una direzione che riduce la loss. Il gradient della loss rispetto a un parametro ti dice in che direzione spostarlo: se il gradient è positivo, diminuire il parametro diminuisce la loss. Se è negativo, aumentarlo diminuisce la loss. Fai un piccolo passo nella direzione del gradient negativo. Quello è il gradient descent.

La backpropagation è solo l’algoritmo per calcolare quei gradient in modo efficiente usando la chain rule del calcolo. L’osservazione intelligente dietro la backprop, fatta da gente negli anni ‘70 e ‘80, è che non serve calcolare il gradient di ogni parametro indipendentemente. Calcoli il gradient all’output, poi lo propaghi all’indietro attraverso la rete un layer alla volta, riutilizzando i risultati intermedi. Il costo di calcolare tutti i gradient è all’incirca il costo di un forward pass. Senza questo trucco, il deep learning è computazionalmente senza speranza. Con esso, puoi allenare reti con centinaia di miliardi di parametri.

In pratica non scriverai mai backprop a mano. Ogni framework moderno, PyTorch, JAX, TensorFlow, lo fa per te tramite automatic differentiation. Definisci il forward pass; il framework registra le operazioni e le percorre all’indietro. La lezione 56 mostra che aspetto ha in PyTorch.

Cosa ti compra “deep”

Perché preoccuparsi di impilare molti layer invece di un singolo layer largo? Perché la profondità permette alla rete di imparare feature gerarchiche. L’esempio classico è il riconoscimento di immagini: il primo layer impara a rilevare gli edge. Il secondo layer impara a combinare gli edge in angoli e texture. Il terzo layer combina quelli in occhi, ruote, foglie. Più profondo è il layer, più astratta è la feature.

Non sei tu a progettare quelle feature. La rete le scopre da sola dal segnale di training. Quella è la magia, se ce n’è una: il deep learning sostituisce la dolorosa, domain-specific feature engineering del ML classico con compute grezzo e tanti dati. Il modulo 9 ha dedicato un’intera lezione (la 50) alla feature engineering per dati tabulari. Per le immagini, quell’intero passaggio sparisce, le convolutional network imparano le feature giuste dai pixel.

Quando il deep learning vince davvero

Il deep learning è lo strumento giusto quando:

  • L’input è ad alta dimensione e strutturato. Immagini (milioni di pixel, struttura spaziale). Audio (waveform, struttura in frequenza). Testo (sequenze, struttura sintattica). Video (spaziale + temporale). Sono domini dove non c’è un modo buono di costruire feature a mano, e dove l’architettura giusta (CNN per immagini, transformer per sequenze) può sfruttare la struttura direttamente.
  • Hai un sacco di dati. Le deep network hanno milioni o miliardi di parametri. Vanno in overfitting all’istante su dataset piccoli. Regola del pollice: sotto i ~10.000 esempi, probabilmente vuoi un modello tree-based dalla lezione 51. Sopra ~1 milione, il deep learning di solito vale un tentativo.
  • Le performance contano più dell’interpretabilità. Una CNN allenata che classifica immagini mediche con accuratezza da radiologo umano è preziosa anche se nessuno può spiegare appieno perché prende una decisione specifica. In altri contesti, decisioni di credito, decisioni mediche dove ci sono di mezzo i regolatori, domande causali scientifiche, l’opacità è squalificante.

Quando il deep learning perde

La lezione 51 aveva una nota che ripeto: per dati tabulari, i gradient-boosted tree vincono ancora. XGBoost, LightGBM, CatBoost battono le neural network sul tipo di dati strutturati che trovi negli spreadsheet, nei database e nella maggior parte dei problemi business, anche nel 2026. C’è stato un flusso costante di paper che provano a invertire questa cosa, e il riassunto onesto è che sulla maggior parte dei benchmark tabulari, gli alberi sono ancora avanti o in pareggio. Si allenano in pochi secondi su una CPU e non richiedono cluster GPU. Usali.

Altri posti dove il deep learning è la scelta sbagliata:

  • Dataset piccoli (sotto qualche migliaio di esempi). Alberi, modelli lineari, o transfer learning da una rete pre-allenata.
  • Requisiti stringenti di interpretabilità. Puoi interpretare i coefficienti di una logistic regression. Non puoi interpretare in modo significativo una rete da 100 milioni di parametri.
  • Budget di latenza stretti su hardware piccolo. Un microcontrollore che fa inference a 1ms, vuoi un piccolo albero o un modello lineare ottimizzato a mano, non un transformer.
  • Problemi dove il costo di sbagliare è enorme e il costo di essere lenti è piccolo. Una banca che prende una decisione su un prestito da $50M può prendersi un’ora e mettere un umano nel loop. Non gli serve un’inference a 5ms.

La realtà del compute

Allenare un modello di deep learning serio significa usare una GPU o una TPU. Non opzionale. Un training run di un transformer moderno è essenzialmente impossibile su CPU in un tempo ragionevole. Il mercato dell’hardware nel 2026 è dominato dalle NVIDIA H100 e dalle più nuove B200, con le AMD MI300 che cercano di recuperare e Apple Silicon (chip serie M con il backend MPS) sempre più valido per lo sviluppo e il training su piccola scala.

Se stai imparando, usa il free tier di Google Colab, i notebook di Kaggle, o Lightning Studios. Non comprare una GPU prima di sapere che ti serve.

La lezione “scale is most of it”

La scoperta più importante e meno lusinghiera dell’ultimo decennio di ricerca nel deep learning: l’architettura conta meno della scala. La stessa architettura transformer del 2017 è quella che alimenta i modelli di frontiera nel 2026. Quello che è cambiato è la quantità di dati, la quantità di compute, e la quantità di training. L’ingegnosità nel design dell’architettura ha prodotto guadagni modesti. Buttare 10x più dati e 10x più compute alla stessa architettura ha prodotto quasi tutto ciò di drammatico che è successo nell’AI dal 2018.

L’implicazione pratica per te, che costruisci sistemi di deep learning nel 2026: non innovare sull’architettura prima di aver spinto al massimo le cose noiose. Più dati, dati più puliti, training più lungo, modello più grande, optimizer migliore, learning rate schedule migliore. La trovata architetturale ingegnosa che ti dà uno 0,5% in più di accuratezza raramente vale il costo di engineering rispetto al dare allo stesso modello più dati.

Il piano da qui in avanti

La lezione 56 introduce PyTorch, tensor, autograd, l’API nn.Module. Definiremo una piccola rete di classificazione nel modo giusto e ispezioneremo cosa fa ogni pezzo. La lezione 57 mette tutto insieme con il training loop: le cinque righe che trasformano una rete inizializzata a caso in un modello allenato, più la contabilità di produzione (checkpointing, mixed precision, distributed training) che trasforma un prototipo da notebook in un sistema reale. Per la fine del modulo 10, avrai scritto un sistema di deep learning funzionante da zero e saprai esattamente a cosa serve ogni riga.

Avanti.

Cerca