Creare reti neurali convoluzionali (CNN) per migliorare la visione artificiale

1. Prima di iniziare

In questo codelab, imparerai a utilizzare le CNN per migliorare i modelli di classificazione delle immagini.

Prerequisiti

Questo codelab si basa sul lavoro completato in due istanze precedenti, Build a computer vision model, in cui introduciamo parte del codice che utilizzerai qui e il codelab Build convolution and execute pooling, dove introduciamo convoluzioni e pooling.

Cosa imparerai a fare:

  • Come migliorare la visione e la precisione del computer con le convoluzioni

Cosa imparerai a realizzare

  • Livelli per ottimizzare la rete neurale

Che cosa ti serve

Puoi trovare il codice per il resto del codelab in esecuzione in Colab.

Dovrai anche installare TensorFlow e le librerie installate nel codelab precedente.

2. Migliora l'accuratezza della visione artificiale con le conversioni

Ora sai come eseguire il riconoscimento delle immagini di moda utilizzando una rete neurale profonda (DNN) che contiene tre livelli: il livello di input (nella forma dei dati di input), il livello di output (nella forma dell'output desiderato) e un livello nascosto. Hai testato diversi parametri che influenzano la precisione finale, ad esempio dimensioni diverse di livelli nascosti e numero di periodi di addestramento.

Per praticità, ecco di nuovo l'intero codice. Eseguila e prendi nota dell'accuratezza del test che viene stampata alla fine.

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images/255.0
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))

La tua accuratezza è probabilmente pari all'89% circa per l'addestramento e all'87% per la convalida. Puoi migliorarlo ulteriormente utilizzando le contorzioni, che restringono i contenuti dell'immagine per concentrarti su dettagli specifici e distinti.

Se hai mai eseguito l'elaborazione delle immagini utilizzando un filtro, le convoluzioni ti sembreranno molto familiari.

In breve, prendiamo un array (di solito 3 x 3 o 5 x 5) e lo trasmetti sull'immagine. Modificando i pixel sottostanti in base alla formula all'interno di quella matrice, puoi eseguire operazioni come il rilevamento dei bordi. Ad esempio, in genere viene definito un 3x3 per il rilevamento dei bordi in cui la cella centrale è 8 e tutti i suoi vicini sono -1. In questo caso, per ogni pixel, moltiplica il valore per 8, quindi sottrai il valore di ogni vicino. Ripeti l'operazione per ogni pixel per ottenere una nuova immagine con i bordi ottimizzati.

È perfetto per la visione artificiale, perché il miglioramento delle funzionalità come i bordi consente al computer di distinguere un elemento dall'altro. Meglio ancora, la quantità di informazioni necessaria è molto inferiore, perché ti eserciterai solo sulle funzionalità evidenziate.

È questo il concetto delle reti neurali convoluzionali. Aggiungi qualche livello per fare la convoluzione prima di avere i livelli ad alta densità, in modo che le informazioni sui livelli più densi diventino più mirati ed eventualmente più accurate.

3. Prova il codice

Esegui questo codice. È la stessa rete neurale della precedente, ma questa volta con livelli convoluzionali aggiunti per primi. Ci vorrà più tempo, ma valuta l'impatto sull'accuratezza:

import tensorflow as tf
print(tf.__version__)
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images / 255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(2, 2),
  tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=5)
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_accuracy*100))

Probabilmente è cresciuto fino a circa il 93% nei dati di addestramento e il 91% nei dati di convalida.

Ora prova a eseguire questa funzionalità per più periodi, ad esempio 20, ed esplora i risultati. Sebbene i risultati dell'addestramento possano sembrare davvero buoni, i risultati di convalida potrebbero effettivamente diminuire a causa di un fenomeno chiamato overfitting.

L'overfiting si verifica quando la rete apprende troppo bene i dati del set di addestramento, pertanto è specializzata nel riconoscimento solo di tali dati e, di conseguenza, meno efficace nel vedere altri dati in situazioni più generiche. Ad esempio, se ti sei allenato solo con i tacchi, la rete potrebbe essere molto efficace per identificare i tacchi, ma le scarpe da ginnastica potrebbero confonderli.

Guarda di nuovo il codice e vedi come sono state costruite le convoluzioni.

4. Raccogli i dati

Il primo passaggio consiste nel raccogliere i dati.

Noterai un cambiamento qui e i dati di addestramento da modificare. Questo perché la prima convoluzione prevede un singolo tensore contenente tutto, quindi invece di 60.000 elementi 28x28x1 in un elenco, hai un unico elenco 4D di 60.000 x 28 x 28x1 e lo stesso per le immagini di test. Se non esegui questa operazione, verrà visualizzato un errore durante l'addestramento perché le convoluzioni non riconoscono la forma.

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images = training_images/255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images = test_images/255.0

5. Definisci il modello

Definisci quindi il tuo modello. Invece del livello di input in alto, aggiungerai un livello convoluzionale. I parametri sono i seguenti:

  • Il numero di convoluzioni che vuoi generare. Un valore come 32 è un buon punto di partenza.
  • Le dimensioni della matrice convoluzionale, in questo caso una griglia 3x3.
  • La funzione di attivazione da utilizzare, in questo caso relu.
  • Nel primo livello, la forma dei dati di input.

Seguirai la convoluzione con un livello di pool massimo, che è stato progettato per comprimere l'immagine mantenendo al contempo i contenuti delle funzionalità evidenziate dalla convoluzione. Specificando (2,2) per il pool massimo, l'effetto è ridurre la dimensione dell'immagine di un fattore 4. Crea un array di pixel 2 x 2 e sceglie il valore più grande, trasformando 4 pixel in 1. Ripeti il calcolo nell'immagine e, di conseguenza, dimezza il numero di pixel orizzontali.

Puoi chiamare model.summary() per controllare le dimensioni e la forma della rete. Tieni presente che, dopo ogni livello massimo di pool, le dimensioni dell'immagine vengono ridotte nel seguente modo:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 26, 26, 64)        640       
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 11, 11, 64)        36928     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 1600)              0         
_________________________________________________________________
dense_4 (Dense)              (None, 128)               204928    
_________________________________________________________________
dense_5 (Dense)              (None, 10)                1290      
=================================================================

Ecco il codice completo della CNN:

model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
#Add another convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
#Now flatten the output. After this you'll just have the same DNN structure as the non convolutional version
tf.keras.layers.Flatten(),
#The same 128 dense layers, and 10 output layers as in the pre-convolution example:
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])

6. Compilare e addestrare il modello

Compila il modello, chiama il metodo di adattamento per eseguire l'addestramento e valuta la perdita e la precisione del set di test.

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print ('Test loss: {}, Test accuracy: {}'.format(test_loss, test_acc*100))

7. Visualizza le convoluzioni e il pool

Questo codice mostra graficamente le convoluzioni. Il print (test_labels[:100]) mostra le prime 100 etichette nel set di test e puoi vedere che quelle all'indice 0, all'indice 23 e all'indice 28 sono tutte dello stesso valore (9). Sono tutte scarpe. Dai un'occhiata al risultato dell'esecuzione della convoluzione su ciascuno di essi e inizierai a notare le caratteristiche in comune tra le due. Ora, quando la DNN si sta addestrando su quei dati, lavora con molte meno informazioni e forse trova una corrispondenza tra le scarpe in base a quella convoluzione e alla combinazione di pool.

print(test_labels[:100])
[9 2 1 1 6 1 4 6 5 7 4 5 7 3 4 1 2 4 8 0 2 5 7 9 1 4 6 0 9 3 8 8 3 3 8 0 7
 5 7 9 6 1 3 7 6 7 2 1 2 2 4 4 5 8 2 2 8 4 8 0 7 7 8 5 1 1 2 3 9 8 7 0 2 6
 2 3 1 2 8 4 1 8 5 9 5 0 3 2 0 6 5 3 6 7 1 8 0 1 4 2]

Ora puoi selezionare alcune delle immagini corrispondenti per visualizzare queste etichette e visualizzare l'aspetto che avranno durante le convoluzioni. Quindi, nel codice seguente, FIRST_IMAGE, SECOND_IMAGE e THIRD_IMAGE sono tutti gli indici del valore 9, uno stivaletto.

import matplotlib.pyplot as plt
f, axarr = plt.subplots(3,4)
FIRST_IMAGE=0
SECOND_IMAGE=23
THIRD_IMAGE=28
CONVOLUTION_NUMBER = 6
from tensorflow.keras import models
layer_outputs = [layer.output for layer in model.layers]
activation_model = tf.keras.models.Model(inputs = model.input, outputs = layer_outputs)
for x in range(0,4):
  f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[0,x].grid(False)
  f2 = activation_model.predict(test_images[SECOND_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[1,x].imshow(f2[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[1,x].grid(False)
  f3 = activation_model.predict(test_images[THIRD_IMAGE].reshape(1, 28, 28, 1))[x]
  axarr[2,x].imshow(f3[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
  axarr[2,x].grid(False)

E dovresti vedere qualcosa di simile nell'immagine, in cui la versione si basa sull'essenza della suola e, di fatto, è una caratteristica comune in tutte le scarpe.

6c9109bcc640a1ec.png

8. Esercitazioni

Attività fisica 1

Prova a modificare le convoluzioni. Modifica il numero di convoluzioni da 32 a 16 o 64. Quale impatto ha sulla precisione e sul tempo di formazione?

Attività fisica 2

Rimuovi l'ultima convoluzione. Che impatto ha sul tempo di accuratezza o di formazione?

Attività fisica 3

Aggiungi altre convoluzioni. Che impatto ha questo cambiamento?

Attività fisica 4

Rimuovi tutte le convoluzioni tranne la prima. Che impatto ha questo cambiamento? Fai degli esperimenti.

9. Complimenti

Hai costruito la tua prima CNN! Per scoprire come migliorare ulteriormente i tuoi modelli di visione artificiale, consulta Utilizzare reti neurali convoluzionali (CNN) con immagini complesse.