Riconoscimento Immagini
Reti Conv2D con Keras
Riconoscimento Immagini
Di seguito trovi un articolo che analizza in modo dettagliato ogni pezzo di un codice Python per il riconoscimento delle immagini tramite una rete neurale convoluzionale (CNN).In questo tutorial andremo a spiegare, riga per riga, come il codice carica e pre-elabora i dati, costruisce il modello CNN e lo utilizza per addestrare, valutare e fare previsioni.
L'articolo si concentra particolarmente sui layer Conv2D (con 32 e 64 filtri), MaxPooling2D, Flatten, Dense, nonché sulle funzioni model.predict, evaluate e l'uso di argmax per l'interpretazione dei risultati.
Introduzione
Il riconoscimento delle immagini è uno dei campi più affascinanti del deep learning e trova applicazioni in numerosi settori, dalla diagnostica medica alla guida autonoma.Grazie alle reti neurali convoluzionali (CNN) è possibile estrarre automaticamente caratteristiche dalle immagini, semplificando il compito di classificazione.
In questo articolo spiegheremo in dettaglio un codice che utilizza il dataset MNIST (immagini di cifre scritte a mano) per addestrare una CNN utilizzando TensorFlow e Keras.
Importazione delle Librerie
# Importa le librerie necessarie
import numpy as np # Libreria fondamentale per la manipolazione di array e operazioni matematiche
from tensorflow.keras.models import Sequential # Importa il modello sequenziale per costruire la rete a strati
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense # Importa i layer necessari per la CNN
from tensorflow.keras.utils import to_categorical # Funzione per convertire le etichette in one-hot encoding
from tensorflow.keras.datasets import mnist # Importa il dataset MNIST, contenente immagini di cifre scritte a mano
Spiegazione
Queste righe importano le librerie e i moduli necessari.NumPy è essenziale per le operazioni numeriche; Sequential serve per costruire il modello strato per strato; Conv2D, MaxPooling2D, Flatten e Dense sono i layer che comporranno la nostra rete.
to_categorical converte le etichette numeriche in vettori one-hot; infine, mnist fornisce il dataset di immagini utilizzato per il training e il test.
Caricamento e Pre-elaborazione dei Dati
# Carica il dataset MNIST (immagini di cifre scritte a mano)
(x_train, y_train), (x_test, y_test) = mnist.load_data()
Spiegazione
Questa riga carica il dataset MNIST, dividendolo in dati di training (`x_train`, `y_train`) e dati di test (`x_test`, `y_test`).Le immagini originali sono in formato 28x28 pixel e le etichette rappresentano le cifre da 0 a 9.
# Ridimensiona le immagini per aggiungere il canale (in questo caso 1 per immagini in scala di grigi)
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
Spiegazione
I dati vengono riformattati per includere una dimensione del canale.Anche se le immagini sono in scala di grigi (quindi hanno un solo canale), i layer convoluzionali richiedono un input con forma `(altezza, larghezza, canali)`.
Qui, `1` indica che c'è un solo canale.
# Normalizza i dati: i valori dei pixel passano da [0, 255] a [0, 1]
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
Spiegazione
La normalizzazione dei pixel è importante per velocizzare il processo di apprendimento.Convertendo i valori in numeri in virgola mobile e dividendo per 255, i pixel vengono riportati in un intervallo compreso tra 0 e 1.
# Converte le etichette in formato one-hot encoding
y_train = to_categorical(y_train, num_classes=10)
y_test = to_categorical(y_test, num_classes=10)
Spiegazione
Le etichette (che inizialmente sono numeri interi da 0 a 9) vengono trasformate in vettori one-hot.Ad esempio, l'etichetta `3` diventa `[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]`. Questo formato è necessario per la funzione di perdita `categorical_crossentropy` utilizzata in problemi di classificazione multi-classe.
Creazione del Modello CNN
# Creazione del modello CNN per il riconoscimento delle immagini
model = Sequential()
Spiegazione
Qui viene creato un modello vuoto in cui verranno aggiunti i layer in sequenza.Primo Layer di Convoluzione
# Aggiungi un layer di convoluzione con 32 filtri, kernel 3x3, funzione di attivazione ReLU e definizione dell'input
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
Spiegazione
- Conv2D(32, (3, 3)): Applica 32 filtri (o kernel) di dimensione 3x3 all'immagine di input.- activation='relu': Utilizza la funzione di attivazione ReLU (Rectified Linear Unit) per introdurre non linearità, fondamentale per permettere al modello di apprendere relazioni complesse.
- input_shape=(28, 28, 1): Specifica la forma delle immagini in ingresso (28x28 pixel con 1 canale).
Primo Layer di Pooling
# Aggiungi un layer di pooling massimo per ridurre le dimensioni spaziali
model.add(MaxPooling2D(pool_size=(2, 2)))
Spiegazione
Il layer **MaxPooling2D** riduce le dimensioni spaziali (altezza e larghezza) dell'output del layer di convoluzione. Il parametro `pool_size=(2, 2)` indica che la finestra di pooling è di dimensioni 2x2, e viene scelto il valore massimo in ogni finestra. Questo riduce il numero di parametri e il rischio di overfitting.Secondo Layer di Convoluzione
# Aggiungi un secondo layer di convoluzione con 64 filtri, kernel 3x3 e funzione di attivazione ReLU
model.add(Conv2D(64, (3, 3), activation='relu'))
Spiegazione
In questo secondo layer la rete applica 64 filtri di dimensione 3x3. Con un numero maggiore di filtri, il modello è in grado di catturare caratteristiche più complesse e dettagliate rispetto al primo layer.Secondo Layer di Pooling
# Aggiungi un secondo layer di pooling massimo
model.add(MaxPooling2D(pool_size=(2, 2)))
Spiegazione
Ancora una volta, il layer di pooling riduce ulteriormente le dimensioni spaziali dell'output, concentrandosi sulle informazioni più rilevanti e semplificando il compito dei layer successivi.Appiattimento dell'Output
# Appiattisci l'output per trasformarlo in un vettore che possa essere utilizzato dai layer fully connected
model.add(Flatten())
Spiegazione
Il layer Flatten trasforma l'output multidimensionale dei layer precedenti in un vettore 1D.Questa operazione è necessaria per collegare i layer convoluzionali ai layer fully connected (densi) che seguono, i quali richiedono input in formato vettoriale.
Layer Denso (Fully Connected)
# Aggiungi un layer denso (fully connected) con 128 neuroni e funzione di attivazione ReLU
model.add(Dense(128, activation='relu'))
Spiegazione
Questo layer fully connected, composto da 128 neuroni, è responsabile dell'apprendimento di combinazioni complesse delle caratteristiche estratte dai layer precedenti.La funzione di attivazione ReLU aiuta a introdurre non linearità e a migliorare la capacità del modello di apprendere.
Layer di Output
# Aggiungi il layer di output con 10 neuroni (una per ogni classe) e funzione di attivazione softmax
model.add(Dense(10, activation='softmax'))
Spiegazione
Il layer finale ha 10 neuroni, uno per ciascuna delle 10 classi del dataset MNIST.La funzione di attivazione **softmax** converte i valori di output in una distribuzione di probabilità, indicando quanto il modello sia sicuro che l'immagine appartenga a ciascuna classe.
Compilazione del Modello
# Compila il modello specificando l'ottimizzatore, la funzione di perdita e la metrica da monitorare
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
Spiegazione
- optimizer='adam': L'ottimizzatore Adam aggiorna i pesi del modello in modo efficiente durante l'addestramento.- loss='categorical_crossentropy': Questa funzione di perdita è adatta per problemi di classificazione multi-classe, dove le etichette sono in formato one-hot.
- metrics=['accuracy']: Specifica che durante l'addestramento e la valutazione verrà monitorata l'accuratezza, ovvero la percentuale di previsioni corrette.
Addestramento del Modello
# Addestra il modello sui dati di training per 10 epoche con una dimensione di batch di 32
model.fit(x_train, y_train, epochs=10, batch_size=32, validation_data=(x_test, y_test))
Spiegazione
Il metodo fit addestra il modello sui dati di training:- epochs=10: Il modello passa per 10 iterazioni complete sull'intero set di dati.
- batch_size=32: I dati vengono suddivisi in lotti (batch) di 32 campioni; dopo ogni batch, i pesi del modello vengono aggiornati.
- validation_data=(x_test, y_test): Durante l'addestramento, il modello valuta anche le sue prestazioni sul set di test per monitorare il rischio di overfitting.
Valutazione del Modello
# Valuta le prestazioni del modello sui dati di test
score = model.evaluate(x_test, y_test, verbose=0)
print("Perdita sul test:", score[0])
print("Accuratezza sul test:", score[1])
Spiegazione
- model.evaluate: Questa funzione calcola la perdita e l'accuratezza del modello sui dati di test.- verbose=0: Impostato a 0 per eseguire la valutazione in modalità silenziosa (senza output intermedio).
- score: È una lista in cui `score[0]` rappresenta la perdita (loss) e `score[1]` l'accuratezza (accuracy) sul set di test.
- print: Vengono stampati i risultati per verificare quanto il modello generalizzi su dati non visti durante l'addestramento.
Previsione e Interpretazione dei Risultati
# Effettua una previsione sulle immagini di test
predizioni = model.predict(x_test)
Spiegazione
La funzione predict applica il modello alle immagini di test e restituisce, per ogni immagine, un array di probabilità che indica quanto il modello sia sicuro che l'immagine appartenga a ciascuna delle 10 classi.
# Usa argmax per ottenere l'indice della classe con la massima probabilità per ogni previsione
classi_predette = np.argmax(predizioni, axis=1)
print("Classi predette per i primi 10 campioni:", classi_predette[:10])
Spiegazione
- np.argmax(predizioni, axis=1): La funzione `argmax` di NumPy esamina ciascun array di probabilità (uno per ogni immagine) e restituisce l'indice della classe con il valore più alto.- classi_predette: Contiene, per ogni immagine, il numero (da 0 a 9) della classe che il modello ritiene più probabile.
- print: Vengono stampate le classi predette per i primi 10 campioni, offrendo un'istantanea della performance del modello.
Conclusioni
Questo articolo ha fornito una spiegazione dettagliata, riga per riga, di un codice Python per il riconoscimento delle immagini utilizzando una rete neurale convoluzionale (CNN).
- Importate le librerie necessarie per il deep learning.
- Caricati e pre-elaborati i dati (incluso il ridimensionamento, la normalizzazione e il one-hot encoding).
- Costruita l'architettura della rete aggiungendo layer di convoluzione (Conv2D con 32 e 64 filtri), pooling (MaxPooling2D), appiattimento (Flatten) e layer densi (Dense) per la classificazione.
- Compilato e addestrato il modello utilizzando l'ottimizzatore Adam e la funzione di perdita categorical crossentropy.
- Valutato e interpretato i risultati mediante l'utilizzo di model.evaluate, model.predict e np.argmax.