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 ( immagini in grigio di articoli di abbigliamento, classi) e la si confronti con la rete feed-forward del laboratorio precedente. Poi si implementi una CNN per CIFAR-10 ( immagini a colori , classi bilanciate da , divise in training e 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 : una CNN vuole anche la dimensione dei canali, quindi np.expand_dims(x_train, axis=3) le porta a . Si dividono i pixel per .
Modello (ispirato a LeNet): Conv2D(32,3), MaxPool2D, Conv2D(64,3), MaxPool2D, Conv2D(128,3), Flatten, Dense(128), Dense(10, softmax). Dimensioni: , vettore di ; parametri (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 ( campioni di training: 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 |
|---|---|---|---|---|
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 ( contro in validazione). Su immagini 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
(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: , quindi valori in ingresso allo strato denso. Parametri: ; ; ; ; : totale . Lo strato denso ne contiene il .
Risultati. Dopo dieci epoche: accuratezza di training , di validazione ; accuratezza di test . La loss di validazione scende fino alla settima epoca () e poi risale a , mentre quella di training continua a scendere: overfitting. Il modello è piccolo per un dataset difficile (il caso casuale darebbe ); 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.