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 tf
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.applications.inception_v3 import decode_predictions
from tensorflow.keras.applications.inception_v3 import preprocess_input
from tensorflow.keras.preprocessing.image import load_img
import matplotlib.pyplot as plt
import numpy as np
import 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 imagenet
model = 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 InceptionV3
image = 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 sbagliate
image = 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 classi
decode_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.