Salta al contenuto
Note per Studenti Reti neurali convolutive (CNN)

Reti neurali convolutive (CNN)

In questa pagina 8

Le immagini, i video e in generale i dati su una griglia sono il campo in cui il deep learning ha cambiato di più lo stato dell'arte (computer vision, CV). Le reti feed-forward di Reti neurali - neuroni e funzioni di attivazioneUn neurone calcola $\hat y=g(w_0+w^\top x)$: somma pesata degli ingressi più bias, poi una funzione di attivazione $g$ non lineare (Perceptron a soglia, sigmoide, tanh, ReLU e varianti). Senza non linearità ogni rete è equivalente a un solo modello lineare. Una rete feed-forward impila strati di neuroni: $a^{(k)}=g(W^{(k)}a^{(k-1)}+b^{(k)})$; con uno strato nascosto è già un approssimatore universale, ma più strati rappresentano funzioni complesse con molti meno neuroni e imparano feature gerarchiche (bordi, parti, oggetti). Lo strato di uscita e la loss si scelgono dal compito: lineare+MSE (regressione), sigmoide+cross-entropy binaria, softmax+cross-entropy (multiclasse). Il numero di parametri di uno strato denso è $n_{in}n_{out}+n_{out}$. Nel lab (Keras, MNIST) una rete 784-512-10 ha 407 050 parametri e supera il 98% di accuratezza.Reti neurali - neuroni e funzioni di attivazione → non sono adatte a trattarle direttamente; le reti neurali convolutive (convolutional neural networks, CNN) sono nate per questo.

1. I compiti della visione artificiale

  • Classificazione: un'etichetta per tutta l'immagine (per esempio cane o muffin).
  • Segmentazione semantica: un'etichetta per ogni pixel (con operazioni di downsampling e upsampling).
  • Rilevamento di oggetti (object detection): trovare le regioni (region proposals) e classificare ciò che contengono.
  • Image captioning (descrizione testuale, con CNN e modelli di sequenze), style transfer (contenuto di un'immagine con lo stile di un'altra), generazione di immagini, anomaly detection visiva (difetti in un pattern).

Il successo di ImageNet misura i progressi: la metrica top-5 error è la frequenza con cui l'etichetta corretta non è tra le 55 predizioni più probabili.

2. Perché non basta una rete densa

Un'immagine a colori 260×194260\times194 è un array 260×194×3260\times194\times3. Con una rete densa:

  • si deve appiattire in un vettore e si perde la struttura spaziale (due pixel vicini e due lontani sono ingressi equivalenti);
  • ogni neurone nascosto è collegato a tutti gli ingressi, quindi i parametri esplodono: un solo strato 784→128784\to128 su un'immagine 28×2828\times28 ha già 784⋅128+128=100 480784\cdot128+128=100\,480 parametri; su un'immagine 224×224×3=150 528224\times224\times3=150\,528 ingressi lo stesso strato ne avrebbe oltre 1919 milioni.

Nella visione classica le feature (bordi, angoli, texture) si costruivano a mano, con conoscenza del dominio per gestire cambi di punto di vista, illuminazione, deformazioni. Una CNN le impara, con la stessa gerarchia vista nel capitolo precedente: bordi e linee, poi parti (occhi, naso), poi oggetti interi.

3. La convoluzione 2D

Idea. Sfruttare la struttura spaziale con patch locali: un neurone dello strato successivo è collegato solo a una piccola finestra dell'ingresso, che scorre su tutta l'immagine (sliding window). I pesi della finestra, il filtro o kernel hh, sono gli stessi in ogni posizione (condivisione dei parametri).

Definizione (convoluzione 2D discreta). Dati un'immagine xx e un filtro hh, y[n,m]=∑j∑ix[i,j]  h[n−i, m−j].y[n,m]=\sum_j\sum_ix[i,j]\;h[n-i,\,m-j]. Si moltiplicano elemento per elemento l'immagine e il filtro posizionato in (n,m)(n,m) e si sommano i risultati (una combinazione lineare locale).

Con h[n−i,m−j]h[n-i,m-j] il filtro è ribaltato (specchiato) rispetto agli assi: è la definizione di convoluzione della teoria dei segnali (Calcolo della convoluzione e sue proprietàIl supporto della convoluzione è la somma dei supporti, $\operatorname{rect}*\operatorname{rect}=\Lambda$, e due esponenziali causali danno $(e^{-bt}-e^{-at})/(a-b)$. Si calcola con il metodo grafico a casi (ribaltare, traslare, individuare gli intervalli di sovrapposizione). Proprietà: lineare, commutativa, associativa, $\delta$ è l'elemento neutro, la traslazione si somma, l'area è il prodotto delle aree.Calcolo della convoluzione e sue proprietà →, Segnali e sistemi in Python - campioni, convoluzione e filtriAl calcolatore un segnale continuo è un vettore di campioni con un asse dei tempi. Con numpy si definiscono i segnali, si approssimano area ed energia con somme moltiplicate per il passo, si calcola la convoluzione continua con np.convolve(x, y)*dt (asse = somma degli istanti iniziali), si simulano filtri con equazioni alle differenze e si verificano numericamente linearità e tempo-invarianza.Segnali e sistemi in Python - campioni, convoluzione e filtri →), estesa a due indici. Le librerie di deep learning (Keras, PyTorch) calcolano in realtà la correlazione incrociata, cioè senza ribaltare il filtro, y[n,m]=∑a,bx[n+a,m+b] h[a,b]y[n,m]=\sum_{a,b}x[n+a,m+b]\,h[a,b]: è equivalente, perché i pesi del filtro si imparano e un filtro ribaltato è un altro filtro qualsiasi. L'esempio delle slide calcola la correlazione (filtro non ribaltato); sotto i valori sono quelli di quel calcolo.

Esempio completo

Immagine x=[123456789]x=\begin{bmatrix}1&2&3\\4&5&6\\7&8&9\end{bmatrix}, filtro h=[121000−1−2−1]h=\begin{bmatrix}1&2&1\\0&0&0\\-1&-2&-1\end{bmatrix} (rivelatore di bordi orizzontali), padding di 11 (cornice di zeri) per ottenere un'uscita 3×33\times3.

Posizione in alto a sinistra: il filtro centrato su x[0,0]=1x[0,0]=1 copre la patch (con gli zeri del padding) [000012045]\begin{bmatrix}0&0&0\\0&1&2\\0&4&5\end{bmatrix}. Prodotto elemento per elemento con hh e somma: 0⋅1+0⋅2+0⋅1+0⋅0+1⋅0+2⋅0+0⋅(−1)+4⋅(−2)+5⋅(−1)=−8−5=−13.0\cdot1+0\cdot2+0\cdot1+0\cdot0+1\cdot0+2\cdot0+0\cdot(-1)+4\cdot(-2)+5\cdot(-1)=-8-5=-13. Spostando di un passo a destra la patch diventa [000123456]\begin{bmatrix}0&0&0\\1&2&3\\4&5&6\end{bmatrix} e il risultato è 4⋅(−1)+5⋅(−2)+6⋅(−1)=−204\cdot(-1)+5\cdot(-2)+6\cdot(-1)=-20. Ripetendo in tutte le nove posizioni si ottiene

y=[−13−20−17−18−24−18132017].y=\begin{bmatrix}-13&-20&-17\\-18&-24&-18\\13&20&17\end{bmatrix}.

Il segno cambia tra la riga superiore (valori negativi: sotto i pixel crescono) e quella inferiore: il filtro risponde a variazioni verticali di luminosità, cioè a bordi orizzontali. Con il filtro ribaltato (convoluzione vera) il risultato avrebbe i segni opposti.

Filtri classici (a mano): sharpen [0−10−15−10−10]\begin{bmatrix}0&-1&0\\-1&5&-1\\0&-1&0\end{bmatrix}, edge detect [0101−41010]\begin{bmatrix}0&1&0\\1&-4&1\\0&1&0\end{bmatrix}, bordi forti [−1−2−1000121]\begin{bmatrix}-1&-2&-1\\0&0&0\\1&2&1\end{bmatrix}. In una CNN i valori dei filtri non si scelgono: sono pesi e si imparano con la backpropagation (Addestramento delle reti neurali - backpropagation e ottimizzatoriAddestrare una rete significa minimizzare la loss empirica $J(W)=\frac1n\sum_i\mathcal L(f(x^{(i)};W),y^{(i)})$ con la discesa del gradiente $W\leftarrow W-\eta,\partial J/\partial W$; in pratica a mini-batch (SGD). Il gradiente di tutti i pesi si ottiene con la backpropagation, cioè la regola della catena applicata all'indietro: $\delta^{(L)}=\partial J/\partial a^{(L)}\odot g'(z^{(L)})$, $\delta^{(l)}=(W^{(l+1)\top}\delta^{(l+1)})\odot g'(z^{(l)})$, $\partial J/\partial W^{(l)}=\delta^{(l)}a^{(l-1)\top}$ (con sigmoide e cross-entropy $\delta=\hat y-y$). Per far funzionare reti profonde: attivazioni ReLU, inizializzazione di Xavier o He (varianza $2/(n_{in}+n_{out})$ e $2/n_{in}$), batch normalization, ottimizzatori con momento o adattivi (Momentum, AdaGrad, RMSProp, Adam con $\beta_1=0{,}9$, $\beta_2=0{,}999$, lr $10^{-3}$) e un learning rate che varia nel tempo (a gradini, coseno). Si addestra tenendo d'occhio la loss di training e di validazione.Addestramento delle reti neurali - backpropagation e ottimizzatori →). Si usano molti filtri per strato, ciascuno una feature diversa, e ognuno produce una mappa di attivazione (feature map).

Padding, stride, dimensione dell'uscita

  • Padding PP: cornice di pixel (zeri) attorno all'immagine; dà ai pixel di bordo la stessa importanza degli altri ed evita che l'immagine si restringa.
  • Stride SS: passo di spostamento del filtro. Stride >1>1 riduce la dimensione dell'uscita.

Formula (dimensione dell'uscita). Con ingresso di lato WW, filtro di lato KK, padding PP, stride SS: O=⌊W−K+2PS⌋+1.O=\Big\lfloor\frac{W-K+2P}{S}\Big\rfloor+1.

Perché. Con il padding il lato diventa W+2PW+2P. Il filtro (largo KK) parte dalla posizione 00 e l'ultima posizione utile ha l'inizio in W+2P−KW+2P-K (oltre sporgerebbe). Con passo SS le posizioni sono 0,S,2S,…0,S,2S,\dots, e il numero di quelle che non superano W+2P−KW+2P-K è ⌊(W+2P−K)/S⌋+1\lfloor(W+2P-K)/S\rfloor+1 (il +1+1 conta la posizione 00).

Esempio. W=28W=28, K=3K=3, P=0P=0, S=1S=1: O=25+1=26O=25+1=26. Con P=1P=1: O=(28−3+2)/1+1=28O=(28-3+2)/1+1=28 (padding «same»: la dimensione si conserva). AlexNet: ingresso 227227, filtro 1111, stride 44: O=(227−11)/4+1=55O=(227-11)/4+1=55.

Campo recettivo

Il campo recettivo (receptive field) di un neurone è la regione dell'ingresso da cui dipende. Un neurone dopo un filtro 3×33\times3 vede 3×33\times3 pixel. Un secondo strato 3×33\times3 vede una patch 3×33\times3 di neuroni del primo strato, ciascuno dei quali ne vede 3×33\times3: la regione totale è 3+2=53+2=5 (i neuroni vicini si sovrappongono: ogni strato aggiuntivo con stride 11 aggiunge K−1=2K-1=2 pixel). Con un terzo strato si arriva a 5+2=75+2=7. In generale per LL strati con filtro KK e stride 11: RF=1+L (K−1)\text{RF}=1+L\,(K-1).

Parametri

Formula (parametri di uno strato convolutivo). Con CinC_{in} canali in ingresso e CoutC_{out} filtri K×KK\times K: K2 Cin Cout+Cout.K^2\,C_{in}\,C_{out}+C_{out}. Ogni filtro ha K⋅K⋅CinK\cdot K\cdot C_{in} pesi (si estende in profondità a tutti i canali) più un bias.

Il numero di parametri non dipende dalle dimensioni dell'immagine: è questo il vantaggio della condivisione dei pesi. Esempio: 3232 filtri 3×33\times3 su un'immagine in scala di grigi hanno 3⋅3⋅1⋅32+32=3203\cdot3\cdot1\cdot32+32=320 parametri, contro i 100 480100\,480 dello strato denso 784→128784\to128.

4. Non linearità, pooling e filtri 1×1

  • Non linearità: dopo la convoluzione si applica una ReLU, g(z)=max⁡(0,z)g(z)=\max(0,z), come negli altri strati.
  • Pooling (sottocampionamento, downsampling): riduce le dimensioni spaziali e dà invarianza a piccole traslazioni. Il max pooling 2×22\times2 con stride 22 prende il massimo di ogni blocco 2×22\times2. Non ha parametri.

Esempio. [1320421501322611]→[max⁡(1,3,4,2)max⁡(2,0,1,5)max⁡(0,1,2,6)max⁡(3,2,1,1)]=[4563]\begin{bmatrix}1&3&2&0\\4&2&1&5\\0&1&3&2\\2&6&1&1\end{bmatrix}\to\begin{bmatrix}\max(1,3,4,2)&\max(2,0,1,5)\\\max(0,1,2,6)&\max(3,2,1,1)\end{bmatrix}=\begin{bmatrix}4&5\\6&3\end{bmatrix}. Il lato si dimezza: O=⌊(4−2)/2⌋+1=2O=\lfloor(4-2)/2\rfloor+1=2.

  • Convoluzioni 1×11\times1: non cambiano larghezza e altezza ma combinano i canali con una somma pesata, quindi servono a ridurre la profondità (numero di canali) o a mescolarli.

Esempio. Un'immagine di feature 28×28×12828\times28\times128 e 3232 filtri 5×55\times5 costano 28⋅28⋅32⋅(5⋅5⋅128)≈80,328\cdot28\cdot32\cdot(5\cdot5\cdot128)\approx80{,}3 milioni di moltiplicazioni. Se prima si riducono i canali da 128128 a 3232 con un filtro 1×11\times1 (28⋅28⋅32⋅128=3,228\cdot28\cdot32\cdot128=3{,}2 M) e poi si applicano i 3232 filtri 5×55\times5 su 3232 canali (28⋅28⋅32⋅25⋅32=20,128\cdot28\cdot32\cdot25\cdot32=20{,}1 M) il totale è 23,323{,}3 milioni: circa 3,43{,}4 volte meno. È l'idea del modulo Inception.

5. Architettura tipica per la classificazione

INPUT→[CONV+ReLU→POOL]×k→FLATTEN→FC→SOFTMAX.\text{INPUT}\to[\text{CONV}+\text{ReLU}\to\text{POOL}]\times k\to\text{FLATTEN}\to\text{FC}\to\text{SOFTMAX}.

La parte convolutiva estrae feature gerarchiche, la parte densa finale (fully connected) le combina e la softmax dà le probabilità di classe (Reti neurali - neuroni e funzioni di attivazioneUn neurone calcola $\hat y=g(w_0+w^\top x)$: somma pesata degli ingressi più bias, poi una funzione di attivazione $g$ non lineare (Perceptron a soglia, sigmoide, tanh, ReLU e varianti). Senza non linearità ogni rete è equivalente a un solo modello lineare. Una rete feed-forward impila strati di neuroni: $a^{(k)}=g(W^{(k)}a^{(k-1)}+b^{(k)})$; con uno strato nascosto è già un approssimatore universale, ma più strati rappresentano funzioni complesse con molti meno neuroni e imparano feature gerarchiche (bordi, parti, oggetti). Lo strato di uscita e la loss si scelgono dal compito: lineare+MSE (regressione), sigmoide+cross-entropy binaria, softmax+cross-entropy (multiclasse). Il numero di parametri di uno strato denso è $n_{in}n_{out}+n_{out}$. Nel lab (Keras, MNIST) una rete 784-512-10 ha 407 050 parametri e supera il 98% di accuratezza.Reti neurali - neuroni e funzioni di attivazione →). Si addestra con la cross-entropy J=−∑iyilog⁡y^iJ=-\sum_iy_i\log\hat y_i e la backpropagation (il gradiente rispetto ai pesi condivisi di un filtro è la somma dei contributi di tutte le posizioni in cui il filtro è stato applicato: regola della catena con un peso che compare più volte, Regola della catena in più variabiliSe x(t) è una curva derivabile e f è differenziabile in x(t₀), allora (f∘x)'(t₀) = ∇f(x(t₀))·x'(t₀) = Σ ∂ᵢf(x(t₀)) xᵢ'(t₀): la variazione di f lungo il moto è il gradiente per la velocità. Serve per derivare composte come f(2t, t²), per ricavare il gradiente da informazioni lungo curve, per le derivate di f(g(s,t)) e per provare che il gradiente è ortogonale alle curve di livello.Regola della catena in più variabili →).

Esempio del laboratorio: Fashion-MNIST

Fashion-MNIST: 70 00070\,000 immagini 28×2828\times28 in grigio di articoli di abbigliamento (T-shirt, pantaloni, pullover, vestito, cappotto, sandalo, camicia, sneaker, borsa, stivaletto), 60 00060\,000 per il training e 10 00010\,000 per il test, 1010 classi. Più difficile di MNIST. La rete del lab (ispirata a LeNet):

python
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten, Dense

def crea_cnn():
    m = Sequential()
    m.add(Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)))
    m.add(MaxPool2D((2, 2)))
    m.add(Conv2D(64, (3, 3), activation="relu"))
    m.add(MaxPool2D((2, 2)))
    m.add(Conv2D(128, (3, 3), activation="relu"))
    m.add(Flatten())
    m.add(Dense(128, activation="relu"))
    m.add(Dense(10, activation="softmax"))
    m.compile(optimizer="adam", loss="sparse_categorical_crossentropy",
              metrics=["accuracy"])
    return m
# le immagini vanno portate a (28, 28, 1): np.expand_dims(x_train, axis=3)

Dimensioni e parametri strato per strato (si usano le formule precedenti, P=0P=0, S=1S=1):

strato uscita parametri
Conv 3232 filtri 3×33\times3 26×26×3226\times26\times32 3⋅3⋅1⋅32+32=3203\cdot3\cdot1\cdot32+32=320
MaxPool 2×22\times2 13×13×3213\times13\times32 00
Conv 6464 filtri 3×33\times3 11×11×6411\times11\times64 3⋅3⋅32⋅64+64=18 4963\cdot3\cdot32\cdot64+64=18\,496
MaxPool 2×22\times2 5×5×645\times5\times64 00
Conv 128128 filtri 3×33\times3 3×3×1283\times3\times128 3⋅3⋅64⋅128+128=73 8563\cdot3\cdot64\cdot128+128=73\,856
Flatten 11521152 00
Dense 128128 128128 1152⋅128+128=147 5841152\cdot128+128=147\,584
Dense 1010 1010 128⋅10+10=1 290128\cdot10+10=1\,290

Totale 320+18 496+73 856+147 584+1 290=241 546320+18\,496+73\,856+147\,584+1\,290=241\,546 parametri, come riporta summary(). Si nota che oltre il 60%60\% dei parametri è nello strato denso, dove si perde la condivisione. Il pooling da 1111 a 55 scarta l'ultima riga/colonna (⌊11/2⌋=5\lfloor11/2\rfloor=5).

Nel lab si addestra con batch_size=1024 e callback (EarlyStopping(patience=3), TensorBoard, ModelCheckpoint) e si confronta con la rete densa 784→512→10784\to512\to10 (con dropout): dopo dieci epoche l'accuratezza di validazione è 0,8890{,}889 per la CNN (training 0,8950{,}895) e 0,8840{,}884 per la FFNN (training 0,8900{,}890). Su immagini piccole in scala di grigi e con poche epoche il vantaggio è modesto; le note del lab avvertono che con immagini a colori e più epoche la CNN si stacca di più. Con CIFAR-10 (60 00060\,000 immagini a colori 32×3232\times32 in 1010 classi bilanciate, 50 00050\,000 training e 10 00010\,000 test) il lab propone Conv-Pool-Conv-Pool-Conv (32,64,6432,64,64 filtri 3×33\times3), poi Flatten, Dense 6464 e Dense 1010: ingressi 32×32×332\times32\times3, lati 30→15→13→6→430\to15\to13\to6\to4, parametri 896+18 496+36 928+65 600+650=122 570896+18\,496+36\,928+65\,600+650=122\,570; accuratezza di test 0,7090{,}709 dopo 1010 epoche. Qui l'overfitting è visibile: l'accuratezza di training sale a 0,8050{,}805 mentre quella di validazione si ferma intorno a 0,710{,}71-0,720{,}72 e la loss di validazione, minima alla settima epoca (0,8220{,}822), risale fino a 0,8540{,}854 (Regolarizzazione delle reti neuraliUna rete con tanti parametri tende a memorizzare il training set (overfitting): la loss di training scende ma quella di validazione risale. Le tecniche di regolarizzazione limitano la capacità effettiva: penalità sui pesi ($\ell_2$: $J+\lambda|W|_2^2$, il passo diventa $W\leftarrow(1-2\eta\lambda)W-\eta\nabla J$; $\ell_1$: $J+\lambda|W|_1$, porta pesi esattamente a zero), early stopping (si ferma l'addestramento quando la validation loss smette di scendere, con pazienza e ripristino dei pesi migliori), dropout (in training si azzera a caso una frazione $p$ delle attivazioni e si riscala per $1/(1-p)$; in inferenza è spento), batch normalization (effetto collaterale) e data augmentation. Nel lab MNIST con $\lambda=0{,}01$ la penalità $\ell_1$ è troppo forte (accuratezza di test 0,844 contro 0,9815 senza regolarizzazione), mentre dropout e early stopping non peggiorano e tengono la validation loss più bassa.Regolarizzazione delle reti neurali →: servono dropout, augmentation o early stopping).

6. Dataset e architetture classiche

dataset anno note
MNIST 1998 cifre 28×2828\times28 in grigio, 1010 classi, 6060k+1010k, facile
Fashion-MNIST 2017 stessa forma, articoli di moda
CIFAR-10/100 2010 color 32×3232\times32, 1010 o 100100 classi, bilanciati
ImageNet 2009 circa 1414 milioni di immagini, oltre 20 00020\,000 categorie (1 0001\,000 nella sfida), sbilanciato, ridimensionate a 256×256256\times256
  • LeNet-5 (1998). La prima vera CNN: CONV-POOL-CONV-POOL-FC-FC, filtri 5×55\times5, pooling 2×22\times2.
  • AlexNet (2012). Vincitrice di ImageNet 2012: 88 strati, 62,362{,}3 milioni di parametri (ingresso 227×227×3227\times227\times3, 55 strati conv e 33 densi con FC6 e FC7 da 40964096 neuroni e FC8 da 10001000). Primo uso su larga scala di ReLU, dropout, data augmentation (ribaltamento e ritaglio portano da 11 a 22 o 1010 immagini per campione), momento; resa possibile dalle GPU. Dimostra che la profondità è essenziale.
  • VGG (2014). 1616-1919 strati con soli filtri 3×33\times3 impilati. Perché: tre strati 3×33\times3 hanno lo stesso campo recettivo di un solo 7×77\times7 (paragrafo 3), ma meno parametri e più non linearità. Per un filtro che guarda CC canali: un 7×77\times7 ha 72C=49C7^2C=49C pesi, tre 3×33\times3 ne hanno 3⋅32C=27C3\cdot3^2C=27C (C=3C=3: 147147 contro 8181); con CC filtri per strato 49C249C^2 contro 27C227C^2. Resta un modello pesante: 138138 milioni di parametri.

Grafico interattivo: Parametri di uno strato 7×7 (49C²) contro tre strati 3×3 (27C²) con C canali in ingresso e in uscita: lo stack 3×3 costa meno, con lo stesso campo recettivo

7. Cosa vede una CNN

Esercizi: Esercizio - Dimensioni e parametri di una CNN, Esercizio - CNN su Fashion-MNIST e CIFAR-10 con Keras, Esercizio - Convoluzione 2D a mano.

8. Errori tipici

  • Dimenticare i bias o la profondità del filtro (CinC_{in}) nel conteggio dei parametri.
  • Dimensione dell'uscita senza +1+1 o senza il floor; dimenticare che il padding "valid" in Keras è P=0P=0.
  • Dimenticare la dimensione dei canali (expand_dims) per immagini in grigio.
  • Credere che la «convoluzione» di Keras ribalti il filtro (non lo fa).
  • Pensare che il pooling abbia parametri da addestrare.

Versione ripasso

Esercizi su questo argomento

Lezioni in cui compare

Teoria collegata