Keras Tutorial CNN: Come realizzare una Convolutional Neural Network in python

Utilizzando Keras con backend Tensorflow possiamo facilmente realizzare una rete neurale artificiale CNN ossia Convolutional Neural Network.

Se non conosci la Convolutional Neural Network adesso ti spiego velocemente di che cosa si tratta e rimando gli approfondimenti in un prossimo articolo.

Se non hai dimestichezza con il framework Keras ti invito a leggere il tutorial per cominciare a realizzare modelli deep learning https://www.retineuraliartificiali.net/keras-tutorial-italiano/

Per approfondire l’uso e tutte le potenzialità di Keras io ti consiglio di dare un occhiata a questo libro.

Cos’è una Convolutional Neural Network (CNN) ?

All’interno del sottoinsieme di algoritmi del machine learning, principalmente basato su reti neurali artificiali e chiamato deep learning, troviamo una particolare rete chiamata appunto Convolutional Neural Network.

In keras esiste una struttura di classi e moduli completa per lavorare con le Convolutional Neural Network.

Una CNN è una rete principalmente utilizzato come algoritmo di apprendimento supervisionato ed è in grado di imparare a classificare immagini a partire da un dataset di esempio.

Si basa sul principio del filtro a convoluzione (detto kernel) applicato sulla matrice di pixel che compone l’immagine su i tre livelli RGB.

Il kernel applicato in maniera sequenziale sull’immagine è in grado di evidenziare caratteristiche fondamentali dell’immagine e in questo modo produrre dati significativi per la classificazione dell’immagine stessa.

Andiamo al sodo : creiamo una Convolutional Neural Network con Keras

Per approfondire l’uso e tutte le potenzialità di Keras io ti consiglio di dare un occhiata a questo.

Prima però ti ricordo che puoi trovare diversi libri sull’argomento, in particolare dai un occhio a questo di Ottavio Calzone

Utilizzeremo il popolarissimo dataset MNIST.

MNIST è composto di 70000 immagini 28×28 pixel che rappresentano i numeri da 0 a 9 trascritti manualmente nero su bianco.

Useremo questo dataset per creare la nostra CNN in grado di classificare e infine riconoscere i numeri scritti a mano da 0 a 9 autonomamente con una precisione che va oltre il 98% e con qualche accorgimento possiamo arrivare al 99%.

Alla fine stamperemo alcuni esempi di immagini non predette dal modello per capire se noi, testoline naturali, saremmo riusciti a fare di meglio.

Il nostro obiettivo sarà quello di insegnare al

La prima parte del nostro codice, dopo aver importato i moduli che ci servono avrà lo scopo di scaricare il dataset MNIST e a questo scopo keras ci aiuta moltissimo in quanto ci mette a disposizione il modulo “mnist” che ha lo scopo appunto di fare in automatico il download di tutto il dataset.

Keras fa anche un ulteriore lavoro per noi, ossia fornisce il dataset già splittato in questo modo : 60000 saranno le immagini per la fase di apprendimento della Convolutional Neural Network mentre le restanti 10000 saranno esclusivamente per la fase di test che servirà per testare la bontà del modello.


from keras.datasets import mnist

#scarica i dati e crea il dataset di train e di test
print(“Download in corso…”)
(Xtrain, ytrain), (Xtest, ytest) = mnist.load_data()
print(“Fatto!”)

print(Xtrain[0].flatten())

Verifichiamo i dati : analisi e pre-processing

Proseguiamo il nostro tutorial keras per la realizzazione di un modello di tipo Convolutional Neural Network.

Giusto per avere un idea di come sono fatte le immagini ne stampiamo alcune. Come possiamo notare sono tutte scritte nere su sfondo bianco. Stampando anche il dato contenuto nell’array di byte notiamo appunto che si tratta di un immagine monocromatica (quindi a singolo canale) ed all’interno abbiamo 255 valori.

#verifichiamo il contenuto dell’array che costituisce la prima immagine
print
(Xtrain[0].flatten())

... 0   0   0   0   0   0   0   0   3  18  18  18 126 136 175  26 166 255
 247 127   0   0   0   0   0   0   0   0   0   0   0   0  30  36  94 154
 170 253 253 253 253 253 225 172 253 242 195  64   0   0   0   0   0   0
   0   0   0   0   0  49 238 253 253 253 253 253 253 253 253 251  93  82
  82  56  39   0   0   0   0   0   0   0   0   0   0   0   0  18 219 253
 253 253 253 253 198 182 247 241   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0  80 156 107 253 253 205  11   0  43 154 ...

L’ immagine come ho gia detto è a singolo canale quindi lo shape della matrice sarà 28×28 e singolo canale. Una volta costruito il nostro modello CNN in keras andremo ad alimentarlo in realta con matrici con shape 28x28x1 in quanto il modello convolutional neural network con dimensionalità 2D prevede un input “righe x colonne x strati” ossia nel caso di un immagine bitmap “altezza x larghezza x canali”. Nel caso di un’ immagine RGB i canali sono normalmente 3 cioè R G e B ed ogni canale è codificato con byte da 0 a 255 ma nel nostro caso abbiamo un immagine monocromatica con singolo canale e quindi 28x28x1.


In realtà l’input sarà con shape batch_size x righe x colonne x canali ma questo per noi sarà totalmente trasparente e a questo livello per ora non ci preocuperemo.

Prima di fare il reshape visualizziamo un po’ di immagini!

import matplotlib.pyplot as plt

print(“ORIGINAL SHAPE”,Xtrain[0].shape)

for k in range(0,10):

plt.imshow(Xtrain[k])
plt.figure()

Il dataset MNIST comprende le immagini, tutto sommato, di piccole dimensioni e questo permette ovviamente la possibilità di eseguire dei test abbastanza velocemente. Teoricamente una convolutional neural network è in grado di elaborare anche immagini enormi ma chiaramente la potenza di calcolo necessaria diventa enorme e per questo motivo si utilizzano altre tecniche che comunque comprendono l’uso della CNN.

#definiamo un po’ di variabili

tot_train_examples = 60000
tot_test_examples = 10000
width=28
height=28
channels = 1
f_size1 = 32 #numero filtri primo strato del modello
f_size2= 16  #numero filtri secondo strato del modello

#eseguiamo il reshape del dataset di training e di test

Xtrain_reshaped = Xtrain.reshape(tot_train_examples,width,height,channels)
Xtest_reshaped = Xtest.reshape(tot_test_examples,width,height,channels)

print(“Nuova shape “,Xtrain_reshaped[0].shape)


Nuova shape (28, 28, 1)

Prima di passare all’ implementazione del modello vero e proprio dobbiamo trasformare l’array contenente le risposte o labels, nella fase di training e nella fase di test, da singoli valori interi a vettori one-hot.
Se non conosci la codifica one-hot visita questa pagina

from keras.utils import to_categorical

y_train_cat = to_categorical(ytrain)
y_test_cat = to_categorical(ytest)
print(y_train_cat[0])

Costruiamo la sequenza Keras del modello

Ora costruiamo il modello.

Se non hai dimestichezza con il framework keras e il modello Sequential, ti invito a scoprirlo nella prima parte dei tutorial keras in questo sito

https://www.retineuraliartificiali.net/keras-tutorial-italiano/

#MODELLO CONVOLUTIONAL NEURAL NETWORK CON KERAS

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten,Dropout

#creazione della sequenza keras per il modello Convolutional Neural Network
model = Sequential()
model.add(Conv2D(f_size1, kernel_size=3, activation=‘relu’, input_shape=(width,height,channels)))
model.add(Dropout(0.3))

model.add(Conv2D(f_size2, kernel_size=3, activation=‘relu’))
model.add(Dropout(0.3))

model.add(Flatten())

model.add(Dense(10, activation=’softmax’))

model.compile(optimizer=‘adam’, loss=‘categorical_crossentropy’, metrics=[‘accuracy’])

history = model.fit(Xtrain_reshaped, y_train_cat, validation_data=(Xtest_reshaped, y_test_cat), epochs=10,batch_size=1024,shuffle=True)

Train on 60000 samples, validate on 10000 samples
Epoch 1/10
60000/60000 [==============================] - 5s 79us/step - loss: 3.8395 - acc: 0.7204 - val_loss: 0.5004 - val_acc: 0.8998
Epoch 2/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.4011 - acc: 0.9109 - val_loss: 0.1290 - val_acc: 0.9626
Epoch 3/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.1806 - acc: 0.9483 - val_loss: 0.0937 - val_acc: 0.9705
Epoch 4/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.1341 - acc: 0.9602 - val_loss: 0.0736 - val_acc: 0.9772
Epoch 5/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.1085 - acc: 0.9669 - val_loss: 0.0660 - val_acc: 0.9790
Epoch 6/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.0925 - acc: 0.9716 - val_loss: 0.0599 - val_acc: 0.9801
Epoch 7/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.0844 - acc: 0.9741 - val_loss: 0.0574 - val_acc: 0.9821
Epoch 8/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.0741 - acc: 0.9774 - val_loss: 0.0532 - val_acc: 0.9830
Epoch 9/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.0680 - acc: 0.9783 - val_loss: 0.0501 - val_acc: 0.9841
Epoch 10/10
60000/60000 [==============================] - 4s 69us/step - loss: 0.0622 - acc: 0.9796 - val_loss: 0.0496 - val_acc: 0.9837

Visualizziamo il grafico della procedura di apprendimento della nostra Convolutional Neural Network che ha raggiunto come promesso una precisione del 98.37%

plt.plot(history.history[‘acc’])
plt.plot(history.history[‘val_acc’])
plt.title(‘Model accuracy’)
plt.ylabel(‘Accuracy’)
plt.xlabel(‘Epoch’)
plt.legend([‘Train’, ‘Test’], loc=‘upper left’)
plt.show()


Lascia un commento

Il tuo indirizzo email non sarà pubblicato.