Codice migliorato
Uso di dropout, batch normalization, data augmentation e un learning rate scheduler per strutture complesse
Codice Python
Codice Python completo per il riconoscimento delle immagini
# Importa le librerie necessarie
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.datasets import mnist
from tensorflow.keras.callbacks import ReduceLROnPlateau
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Carica il dataset MNIST (immagini di cifre scritte a mano)
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 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)
# 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
# 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)
# Creazione del modello CNN per il riconoscimento delle immagini
model = Sequential()
# Aggiungi il primo 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)))
# Aggiungi BatchNormalization per migliorare la convergenza
model.add(BatchNormalization())
# Aggiungi un layer di pooling massimo per ridurre le dimensioni spaziali
model.add(MaxPooling2D(pool_size=(2, 2)))
# Aggiungi un secondo layer di convoluzione con 64 filtri, kernel 3x3 e funzione di attivazione ReLU
model.add(Conv2D(64, (3, 3), activation='relu'))
# Aggiungi BatchNormalization
model.add(BatchNormalization())
# Aggiungi un secondo layer di pooling massimo
model.add(MaxPooling2D(pool_size=(2, 2)))
# Appiattisci l'output per trasformarlo in un vettore che possa essere utilizzato dai layer fully connected
model.add(Flatten())
# Aggiungi un layer denso (fully connected) con 128 neuroni e funzione di attivazione ReLU
model.add(Dense(128, activation='relu'))
# Aggiungi un layer di dropout per prevenire l'overfitting
model.add(Dropout(0.5))
# Aggiungi il layer di output con 10 neuroni (una per ogni classe) e funzione di attivazione softmax
model.add(Dense(10, activation='softmax'))
# Compila il modello specificando l'ottimizzatore, la funzione di perdita e la metrica da monitorare
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Aggiungi il learning rate scheduler per ridurre dinamicamente il learning rate
lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, min_lr=1e-6)
# Imposta il data augmentation per aumentare la varietà delle immagini di training
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
# Esegui il fitting del data generator sul training set
datagen.fit(x_train)
# Addestra il modello con il data augmentation e il learning rate scheduler
model.fit(datagen.flow(x_train, y_train, batch_size=32), epochs=10, validation_data=(x_test, y_test), callbacks=[lr_scheduler])
# 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])
# Effettua una previsione sulle immagini di test
predizioni = model.predict(x_test)
# 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])