Reti pre-trained.
Uno dei più grandi vantaggi dell'approccio corrente al Deep Learned è la possibilità di avere accesso a reti pre-addestrate. In questo modo si evita di dover spendere tante ore, se non giornate, nell'addestramento della rete, ed è possibile utilizzare direttamente l'architettura della stessa ed i pesi (weights) ottenuti dall'adddestramento, scaricandoli da Internet. E' uno dei vantaggi offerti dall'approccio "Open Source" adottato il larga misura.
In questa breve nota riporto il codice Python, con commenti, per utilizzare una delle reti che hanno vinto la competizione ILSVRC: Inception (V3).
Il codice.
Ecco il codice da eseguire in un Jupyter Notebook. Il codice è basato ed è stato testato su Tensorflow 2.1
import tensorflow as tffrom tensorflow.keras.applications.inception_v3 import InceptionV3from tensorflow.keras.applications.inception_v3 import decode_predictionsfrom tensorflow.keras.applications.inception_v3 import preprocess_inputfrom tensorflow.keras.preprocessing.image import load_imgimport matplotlib.pyplot as pltimport numpy as npimport cv2
Nelle due righe seguenti è riportato il codice che costruisce il modello basato su InceptionV3 e carica, da Internet, i pesi della rete, addestrata e pronta per effettuare la classificazione.
# prebuild model with pre-trained weights on imagenetmodel = InceptionV3(weights='imagenet', include_top=True)
model.compile(optimizer='sgd', loss='categorical_crossentropy')
A questo punto ossiamo testare la NN con un'immagine. L'immagine deve essere preprocessata per trasformarla nel formato atteso da InceptionV3, che attende immagini con shape (299,299,3).
RADIX = '/home/opc/images/'
# change image file name here !!!IMAGE_NAME = 'cat-standing.jpg'IMAGE_PATH = RADIX + IMAGE_NAME
# il caricamento è fatto con un'utility fornita da Keras, ma avremmo potuto utilizzare OpenCV (cv2).
image = load_img(IMAGE_PATH, target_size=(299, 299))
# preparo l'immagine per InceptionV3image = np.array(image)
# dobbiamo fornire a predict un tensore (1, 299, 299, 3)image = np.expand_dims(image, axis=0)
# per InceptionV3 è fondamentale questo step di preelaborazione !!!# altrimenti le predizioni sono sbagliateimage = preprocess_input(image)
image.shape
A questo punto possiamo chiedere la previsione:
# predict
out = model.predict(image)index = np.argmax(out)# print(index)
# vediamo le probabilità per le varie classidecode_predictions(out)
Se vogliamo visualizzare la distribuzione di probabilità per tutte le 1000 classi
# grafica le probabilità per tutte le mille classi (per capire quanto netta è la scelta)plt.plot(out.ravel())plt.show()
Le prestazioni.
Ovviamente, a molti può interessare la domanda: quali sono le prestazioni (accuratezza) offerte da InceptionV3?
Un confronto tra le varie architettuure di CNN si può trovare, ad esempio, in https://arxiv.org/pdf/1810.00736.pdf
Il grafico che riporto è tratto da esso.
Nel grafico si vede che InceptionV3 ha un'accuratezza migliore di VGG16 e VGG19 ed è più efficiente dal punto di vista computazionale.