Salta al contenuto
Note per Studenti Esercizio - CNN su Fashion-MNIST e CIFAR-10 con Keras

Esercizio - CNN su Fashion-MNIST e CIFAR-10 con Keras

Questa pagina non ha ancora la versione ripasso: qui sotto c'è il testo completo.

Testo (laboratorio sulle reti neurali, seconda parte). Si addestri una CNN su Fashion-MNIST (70 00070\,000 immagini 28×2828\times28 in grigio di articoli di abbigliamento, 1010 classi) e la si confronti con la rete feed-forward del laboratorio precedente. Poi si implementi una CNN per CIFAR-10 (60 00060\,000 immagini a colori 32×3232\times32, 1010 classi bilanciate da 6 0006\,000, divise in 50 00050\,000 training e 10 00010\,000 test): Conv-MaxPool-Conv-MaxPool-Conv, poi gli strati densi adatti alla classificazione, con le callback EarlyStopping, TensorBoard e ModelCheckpoint.

Teoria usata: Reti neurali convolutive (CNN)approfondimento: non nel programma di Telecomunicazioni. Una rete convolutiva (CNN) sostituisce gli strati densi con filtri piccoli che scorrono sull'immagine: ogni neurone vede solo una patch locale (campo recettivo) e i pesi del filtro sono condivisi in tutta l'immagine, quindi i parametri non dipendono dalla dimensione dell'immagine ($K^2C_{in}C_{out}+C_{out}$ per strato) e si conserva l'informazione spaziale. Dimensione dell'uscita: $\lfloor(W-K+2P)/S\rfloor+1$. Pooling (max 2x2, stride 2) sottocampiona e dà invarianza locale; i filtri 1x1 riducono i canali; struttura tipica CONV+ReLU, POOL, ..., FLATTEN, FC, SOFTMAX, addestrata con cross-entropy e backpropagation. Tre strati 3x3 hanno il campo recettivo di un 7x7 con meno parametri e più non linearità (VGG). Architetture: LeNet, AlexNet (ReLU, dropout, data augmentation), VGG, GoogLeNet (moduli Inception), ResNet (blocchi residui $H(x)=F(x)+x$), EfficientNet. Nel lab: CNN su Fashion-MNIST (241 546 parametri) e su CIFAR-10 (122 570).Reti neurali convolutive (CNN) →, 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 →, Metriche di classificazioneIn classificazione binaria ogni previsione è vero positivo (TP), vero negativo (TN), falso positivo (FP, errore di tipo I) o falso negativo (FN, errore di tipo II). Da queste quattro quantità: accuracy $=\frac{TP+TN}{TP+TN+FP+FN}$, specificità $=\frac{TN}{TN+FP}$, precision $=\frac{TP}{TP+FP}$, recall $=\frac{TP}{TP+FN}$, e la loro media armonica $F_1=\frac{2PR}{P+R}$. Con dati sbilanciati l'accuracy inganna (un modello che predice sempre la classe maggioritaria ha 99%): si usano precision, recall, F1, ROC-AUC, la cross-validation stratificata e il riequilibrio con undersampling o oversampling (non SMOTE). Cambiando la soglia sulla probabilità si ottiene la curva ROC (TPR contro FPR) e l'area AUC. Approfondimento: non nel programma di Telecomunicazioni.Metriche di classificazione →.

Fashion-MNIST

Preparazione. Le immagini hanno forma (28,28)(28,28): una CNN vuole anche la dimensione dei canali, quindi np.expand_dims(x_train, axis=3) le porta a (28,28,1)(28,28,1). Si dividono i pixel per 255255.

Modello (ispirato a LeNet): Conv2D(32,3), MaxPool2D, Conv2D(64,3), MaxPool2D, Conv2D(128,3), Flatten, Dense(128), Dense(10, softmax). Dimensioni: 26→13→11→5→326\to13\to11\to5\to3, vettore di 3⋅3⋅128=1 1523\cdot3\cdot128=1\,152; parametri 320+18 496+73 856+147 584+1 290=241 546320+18\,496+73\,856+147\,584+1\,290=241\,546 (si veda il calcolo strato per strato in Reti neurali convolutive (CNN)approfondimento: non nel programma di Telecomunicazioni. Una rete convolutiva (CNN) sostituisce gli strati densi con filtri piccoli che scorrono sull'immagine: ogni neurone vede solo una patch locale (campo recettivo) e i pesi del filtro sono condivisi in tutta l'immagine, quindi i parametri non dipendono dalla dimensione dell'immagine ($K^2C_{in}C_{out}+C_{out}$ per strato) e si conserva l'informazione spaziale. Dimensione dell'uscita: $\lfloor(W-K+2P)/S\rfloor+1$. Pooling (max 2x2, stride 2) sottocampiona e dà invarianza locale; i filtri 1x1 riducono i canali; struttura tipica CONV+ReLU, POOL, ..., FLATTEN, FC, SOFTMAX, addestrata con cross-entropy e backpropagation. Tre strati 3x3 hanno il campo recettivo di un 7x7 con meno parametri e più non linearità (VGG). Architetture: LeNet, AlexNet (ReLU, dropout, data augmentation), VGG, GoogLeNet (moduli Inception), ResNet (blocchi residui $H(x)=F(x)+x$), EfficientNet. Nel lab: CNN su Fashion-MNIST (241 546 parametri) e su CIFAR-10 (122 570).Reti neurali convolutive (CNN) →).

Addestramento. batch_size=1024, dieci epoche, validation_split=0.1 (54 00054\,000 campioni di training: ⌈54 000/1024⌉=53\lceil54\,000/1024\rceil=53 iterazioni per epoca, quante ne mostra Keras), con EarlyStopping(monitor="val_loss", patience=3).

Risultati del laboratorio (accuratezza al passare delle epoche, CNN contro rete densa):

epoca CNN train CNN val FFNN train FFNN val
11 0,5360{,}536 0,7580{,}758 0,6410{,}641 0,8240{,}824
55 0,8610{,}861 0,8600{,}860 0,8700{,}870 0,8700{,}870
1010 0,8950{,}895 0,8890{,}889 0,8900{,}890 0,8840{,}884

Lettura: alla prima epoca la rete densa è più avanti (la CNN parte più lentamente), poi le due convergono e alla decima la CNN è di poco migliore (0,8890{,}889 contro 0,8840{,}884 in validazione). Su immagini 28×2828\times28 in grigio e con soli dieci passaggi il vantaggio è piccolo; il laboratorio nota che migliora con immagini a colori e più epoche (le curve sono ancora in salita). Training e validazione sono vicine: nessun overfitting rilevante.

Valutazione per classe. y_pred = np.argmax(model.predict(x_test), axis=1), percentuale di errore per classe e matrice di confusione (in scala logaritmica, np.log(1 + cm), per vedere gli errori rari). Ci si aspetta (da verificare sul grafico) che le classi con più confusioni siano quelle visivamente simili: camicia, T-shirt, pullover e cappotto tra loro; sandalo, sneaker e stivaletto tra loro.

CIFAR-10

python
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
train_images, test_images = train_images / 255.0, test_images / 255.0

model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation="relu", input_shape=(32, 32, 3)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation="relu"),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation="relu"),
    layers.Flatten(),
    layers.Dense(64, activation="relu"),
    layers.Dense(10, activation="softmax"),
])
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
history = model.fit(train_images, train_labels, epochs=10, validation_split=0.1)

Dimensioni dei lati: 32→30→15→13→6→432\to30\to15\to13\to6\to4, quindi 4⋅4⋅64=1 0244\cdot4\cdot64=1\,024 valori in ingresso allo strato denso. Parametri: 3⋅3⋅3⋅32+32=8963\cdot3\cdot3\cdot32+32=896; 3⋅3⋅32⋅64+64=18 4963\cdot3\cdot32\cdot64+64=18\,496; 3⋅3⋅64⋅64+64=36 9283\cdot3\cdot64\cdot64+64=36\,928; 1 024⋅64+64=65 6001\,024\cdot64+64=65\,600; 64⋅10+10=65064\cdot10+10=650: totale 122 570122\,570. Lo strato denso ne contiene il 54%54\%.

Risultati. Dopo dieci epoche: accuratezza di training 0,8050{,}805, di validazione 0,7180{,}718; accuratezza di test 0,7090{,}709. La loss di validazione scende fino alla settima epoca (0,8220{,}822) e poi risale a 0,8540{,}854, mentre quella di training continua a scendere: overfitting. Il modello è piccolo per un dataset difficile (il caso casuale darebbe 0,100{,}10); per migliorare: più strati o filtri, data augmentation (ribaltamenti, ritagli), dropout, batch normalization, early stopping con ripristino dei pesi migliori.

Callback. ModelCheckpoint(save_weights_only=True, save_freq="epoch", filepath=...weights.{epoch:02d}-{val_loss:.2f}.weights.h5) salva i pesi a ogni epoca, con epoca e validation loss nel nome; TensorBoard(log_dir=...) registra le curve (si apre con tensorboard --logdir); EarlyStopping interrompe quando la validation loss non migliora per patience epoche.

Lezioni in cui compare

Teoria collegata