Il tuo primo modello Keras, con Transfer Learning

1. Panoramica

In questo lab imparerai a creare un classificatore Keras. Anziché cercare di trovare la combinazione perfetta di livelli di rete neurale per riconoscere i fiori, useremo prima una tecnica chiamata transfer learning per adattare un potente modello preaddestrato al nostro set di dati.

Questo lab include le spiegazioni teoriche necessarie sulle reti neurali ed è un buon punto di partenza per gli sviluppatori che vogliono imparare a utilizzare il deep learning.

Questo lab è la Parte 2 della serie "Keras on TPU". Puoi eseguirli nel seguente ordine o indipendentemente.

ca8cc21f6838eccc.png

Obiettivi didattici

  • Per creare il proprio classificatore di immagini Keras con uno strato softmax e la perdita di entropia incrociata
  • Per imbrogliare 🏏, usare il transfer learning invece di creare modelli personalizzati.

Feedback

Se noti qualcosa che non va in questo lab del codice, faccelo sapere. I feedback possono essere inviati tramite i problemi di GitHub [link al feedback].

2. Guida rapida di Google Colaboratory

Questo lab utilizza Google Collaboratory e non richiede alcuna configurazione da parte tua. Colaboratory è una piattaforma di notebook online per scopi didattici. Offre formazione gratuita su CPU, GPU e TPU.

688858c21e3beff2.png

Puoi aprire questo blocco note di esempio ed eseguire un paio di celle per acquisire familiarità con Colaboratory.

c3df49e90e5a654f.png Welcome to Colab.ipynb

Seleziona un backend TPU

8832c6208c99687d.png

Nel menu di Colab, seleziona Runtime > Cambia tipo di runtime e poi TPU. In questo codelab utilizzerai una potente TPU (Tensor Processing Unit) supportata per l'addestramento con accelerazione hardware. La connessione al runtime avverrà automaticamente alla prima esecuzione oppure puoi utilizzare il pulsante "Connetti" nell'angolo in alto a destra.

Esecuzione di blocchi note

76d05caa8b4db6da.png

Esegui le celle una alla volta facendo clic su una cella e utilizzando Maiusc-Invio. Puoi anche eseguire l'intero blocco note con Runtime > Esegui tutto

Sommario

429f106990037ec4.png

Tutti i blocchi note hanno un sommario. Puoi aprirlo utilizzando la freccia nera a sinistra.

Celle nascoste

edc3dba45d26f12a.png

Alcune celle mostreranno solo il titolo. Si tratta di una funzionalità del blocco note specifica per Colab. Puoi fare doppio clic sopra per vedere il codice al loro interno, ma di solito non è molto interessante. In genere supportano o le funzioni di visualizzazione. Devi comunque eseguire queste celle per definire le funzioni all'interno.

Autenticazione

cdd4b41413100543.png

Colab può accedere ai tuoi bucket Google Cloud Storage privati, a condizione che tu esegua l'autenticazione con un account autorizzato. Lo snippet di codice riportato sopra attiverà un processo di autenticazione.

3. [INFO] Classificatore di rete neurale 101

In breve

Se conosci già tutti i termini in grassetto nel paragrafo successivo, puoi passare all'esercizio successivo. Se hai appena iniziato il deep learning, ti diamo il benvenuto e continua a leggere.

Per i modelli creati come sequenza di strati, Keras offre l'API Sequential. Ad esempio, un classificatore di immagini che utilizza tre strati densi può essere scritto in Keras come:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

Rete neurale densa

Questa è la rete neurale più semplice per classificare le immagini. È costituito da "neuroni" disposti in strati. Il primo livello elabora i dati di input e invia le relative uscite ad altri livelli. È chiamato "denso" perché ogni neurone è collegato a tutti i neuroni dello strato precedente.

c21bae6dade487bc.png

Puoi inserire un'immagine in una rete di questo tipo, suddividendo i valori RGB di tutti i suoi pixel in un vettore lungo e utilizzandolo come input. Non è la tecnica migliore per il riconoscimento delle immagini, ma la miglioreremo in futuro.

Neuroni, attivazioni, RELU

Un "neurone" calcola una somma ponderata di tutti i suoi input, aggiunge un valore chiamato "bias" e alimenta il risultato attraverso una cosiddetta "funzione di attivazione". Inizialmente, le ponderazioni e il bias sono sconosciuti. Verranno inizializzate in modo casuale e "apprese" addestrando la rete neurale con molti dati noti.

644f4213a4ee70e5.png

La funzione di attivazione più utilizzata è chiamata RELU per Rectified Linear Unit. Si tratta di una funzione molto semplice, come puoi vedere nel grafico in alto.

Attivazione di softmax

La rete precedente termina con uno strato a 5 neuroni perché classifichiamo i fiori in 5 categorie (rosa, tulipano, dente di leone, margherita, girasole). I neuroni negli strati intermedi vengono attivati utilizzando la funzione di attivazione RELU classica. Nell'ultimo livello, però, vogliamo calcolare numeri compresi tra 0 e 1 che rappresentano la probabilità che questo fiore sia una rosa, un tulipano e così via. A questo scopo, utilizzeremo una funzione di attivazione chiamata "softmax".

L'applicazione di softmax a un vettore viene eseguita prendendo l'esponenziale di ogni elemento e poi normalizzando il vettore, in genere utilizzando la norma L1 (somma dei valori assoluti) in modo che i valori sommati diano 1 e possano essere interpretati come probabilità.

ef0d98c0952c262d.png d51252f75894479e.gif

Perdita con entropia incrociata

Ora che la nostra rete neurale produce previsioni dalle immagini di input, dobbiamo misurarne la qualità, ovvero la distanza tra ciò che ci dice la rete e le risposte corrette, spesso chiamate "etichette". Ricorda che abbiamo etichette corrette per tutte le immagini del set di dati.

Qualsiasi distanza andrebbe bene, ma per i problemi di classificazione la cosiddetta "distanza di entropia incrociata" è la più efficace. La chiameremo funzione di errore o "perdita":

7bdf8753d20617fb.png

Discesa del gradiente

"Addestrare" la rete neurale significa in realtà utilizzare immagini ed etichette di addestramento per regolare ponderazioni e bias in modo da minimizzare la funzione di perdita di entropia incrociata. Ecco come funziona.

L'entropia incrociata è una funzione delle ponderazioni, dei bias, dei pixel dell'immagine di addestramento e della sua classe nota.

Se calcoliamo le derivate parziali dell'entropia incrociata relativamente a tutte le ponderazioni e a tutti i bias, otteniamo un "gradiente", calcolato per una determinata immagine, etichetta e valore attuale di ponderazioni e bias. Ricorda che possiamo avere milioni di ponderazioni e bias, quindi il calcolo del gradiente richiede molto lavoro. Fortunatamente, TensorFlow lo fa per noi. La proprietà matematica di un gradiente è che punta "verso l'alto". Poiché vogliamo andare dove l'entropia incrociata è bassa, andiamo nella direzione opposta. Aggiorniamo i pesi e i bias in base a una frazione del gradiente. Poi ripetiamo la stessa cosa più volte utilizzando i batch successivi di immagini e etichette di addestramento, in un ciclo di addestramento. Si spera che questo converge in un punto in cui l'entropia incrociata è minima, anche se nulla garantisce che questo minimo sia unico.

discesa del gradiente2.png

Mini-batching e momentum

Puoi calcolare il gradiente su una sola immagine di esempio e aggiornare immediatamente i pesi e i bias, ma farlo su un batch di, ad esempio, 128 immagini fornisce un gradiente che rappresenta meglio i vincoli imposti da diverse immagini di esempio ed è quindi probabile che converga verso la soluzione più velocemente. La dimensione del mini-batch è un parametro regolabile.

Questa tecnica, a volte chiamata "discesa del gradiente stocastico", ha un altro vantaggio più pragmatico: lavorare con i batch significa anche lavorare con matrici più grandi, che in genere sono più facili da ottimizzare su GPU e TPU.

Tuttavia, la convergenza può essere ancora un po' caotica e può persino interrompersi se il vettore del gradiente è composto interamente da zeri. Vuoi dire che abbiamo trovato un minimo? Non sempre. Un componente di gradiente può essere pari a zero per un valore minimo o massimo. Con un vettore gradiente con milioni di elementi, se sono tutti zeri, la probabilità che ogni zero corrisponda a un minimo e nessuno di questi a un punto massimo è piuttosto piccola. In uno spazio di molte dimensioni, i punti di sella sono piuttosto comuni e non vogliamo fermarci lì.

52e824fe4716c4a0.png

Illustrazione: un punto di attacco. La pendenza è 0, ma non è un minimo in tutte le direzioni. (Attribuzione immagine Wikimedia: di Nicoguaro - Opera propria, CC BY 3.0)

La soluzione consiste nell'aggiungere un po' di slancio all'algoritmo di ottimizzazione in modo che possa superare i punti di sella senza fermarsi.

Glossario

batch o mini-batch: l'addestramento viene sempre eseguito su batch di dati ed etichette di addestramento. In questo modo l'algoritmo converge. La dimensione "batch" è in genere la prima dimensione dei tensori di dati. Ad esempio, un tensore di forma [100, 192, 192, 3] contiene 100 immagini di 192 x 192 pixel con tre valori per pixel (RGB).

perdita con entropia incrociata: una funzione di perdita speciale spesso usata nei classificatori.

strato denso: uno strato di neuroni in cui ogni neurone è collegato a tutti i neuroni dello strato precedente.

features: gli input di una rete neurale sono a volte chiamati "caratteristiche". L'arte di capire quali parti di un set di dati (o combinazioni di parti) alimentare in una rete neurale per ottenere buone previsioni è chiamata "feature engineering".

labels: un altro nome per "classi" o risposte corrette in un problema di classificazione supervisionata

tasso di apprendimento: frazione del gradiente con cui i pesi e i bias vengono aggiornati a ogni iterazione del ciclo di addestramento.

Logit: gli output di uno strato di neuroni prima dell'applicazione della funzione di attivazione sono chiamati "logit". Il termine deriva dalla "funzione logistica", nota anche come "funzione sigmoide", che era la funzione di attivazione più utilizzata. "Output dei neuroni prima della funzione logistica" è stato abbreviato in "logit".

loss: la funzione di errore che confronta gli output della rete neurale con le risposte corrette

neurone: calcola la somma ponderata dei suoi input, aggiunge un bias e alimenta il risultato tramite una funzione di attivazione.

Codifica one-hot: la classe 3 su 5 viene codificata come un vettore di 5 elementi, tutti pari a zero tranne il terzo, che è 1.

relu: unità lineare rettificata. Una funzione di attivazione molto diffusa per i neuroni.

sigmoid: un'altra funzione di attivazione molto diffusa che è ancora utile in casi speciali.

softmax: una funzione di attivazione speciale che agisce su un vettore, aumenta la differenza tra il componente più grande e tutti gli altri e normalizza il vettore in modo che abbia una somma pari a 1 in modo che possa essere interpretato come un vettore di probabilità. Utilizzato come ultimo passaggio nelle categorie di classificazione.

tensore: un "tensore" è simile a una matrice, ma con un numero arbitrario di dimensioni. Un tensore 1D è un vettore. Un tensore di 2 dimensioni è una matrice. Poi si possono avere tensori con 3, 4, 5 o più dimensioni.

4. Transfer Learning

Per un problema di classificazione delle immagini, i livelli densi probabilmente non saranno sufficienti. Dobbiamo conoscere gli strati convoluzionali e i molti modi in cui è possibile organizzarli.

Ma possiamo anche usare una scorciatoia! Sono disponibili per il download reti neurali convoluzionali completamente addestrate. È possibile tagliare l'ultimo strato, la testa di classificazione softmax, e sostituirlo con uno proprio. Tutti i pesi e i bias addestrati rimangono invariati, devi solo addestrare nuovamente il livello softmax che aggiungi. Questa tecnica è chiamata Transfer Learning e, sorprendentemente, funziona purché il set di dati su cui la rete neurale è preaddestrata sia "abbastanza simile" al tuo.

Hands-on

Apri il blocco note seguente, esegui le celle (Maiusc-Invio) e segui le istruzioni ovunque vedi l'etichetta "LAVORO OBBLIGATORIO".

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

Ulteriori informazioni

Il transfer learning consente di sfruttare sia le architetture di reti neurali convoluzionali avanzate sviluppate da famosi ricercatori sia il preaddestramento su un enorme set di dati di immagini. Nel nostro caso, utilizzeremo il trasferimento dell'apprendimento da una rete addestrata su ImageNet, un database di immagini contenenti molte piante e scene all'aperto, che è abbastanza simile ai fiori.

b8fc1efd2001f072.png

Ilustrazione: utilizzo di una complessa rete neurale convoluzionale, già addestrata, come una scatola nera, per addestrare nuovamente solo la testa di classificazione. Questo è il trasferimento di apprendimento. Vedremo come funzionano queste complesse combinazioni di livelli con convoluzione più avanti. Per il momento, il problema è qualcun altro.

Transfer Learning in Keras

In Keras, puoi creare un'istanza di un modello preaddestrato dalla raccolta tf.keras.applications.*. MobileNet V2, ad esempio, è un'ottima architettura convoluzionale che garantisce dimensioni ragionevoli. Se selezioni include_top=False, ottieni il modello preaddestrato senza il suo strato softmax finale, in modo da poter aggiungere il tuo:

pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False

model = tf.keras.Sequential([
    pretrained_model,
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(5, activation='softmax')
])

Tieni presente anche l'impostazione pretrained_model.trainable = False. Blocca le ponderazioni e i bias del modello preaddestrato in modo da addestrare solo il livello softmax. Questo in genere prevede pesi relativamente pochi e può essere fatto rapidamente e senza richiedere un set di dati molto ampio. Tuttavia, se hai molti dati, l'apprendimento tramite trasferimento può funzionare ancora meglio con pretrained_model.trainable = True. I pesi preaddestrati forniscono quindi eccellenti valori iniziali e possono ancora essere regolati dall'addestramento per adattarsi meglio al tuo problema.

Infine, nota lo strato Flatten() inserito prima dello strato softmax denso. Gli strati densi funzionano su vettori piatti di dati, ma non sappiamo se questo è ciò che restituisce il modello preaddestrato. Ecco perché dobbiamo appiattire. Nel prossimo capitolo, quando esamineremo le architetture convoluzionali, spiegheremo il formato dei dati restituito dai livelli con convoluzione.

Con questo approccio dovresti ottenere un'accuratezza del 75%.

Soluzione

Ecco il blocco note della soluzione. Puoi utilizzarlo se non riesci a procedere.

c3df49e90e5a654f.png Keras Flowers transfer learning (solution).ipynb

Argomenti trattati

  • 🤔 Come scrivere un classificatore in Keras
  • 🤓 configurato con un ultimo strato softmax e perdita di entropia incrociata
  • 🔍 Transfer Learning
  • 🤔 Addestramento del primo modello
  • 🧐 A seguito della perdita e della precisione durante l'addestramento

Dedica qualche istante a leggere questo elenco di controllo.

5. Complimenti!

Ora puoi creare un modello Keras. Continua con il prossimo lab per imparare a combinare strati convoluzionali.

TPU nella pratica

Le TPU e le GPU sono disponibili sulla Cloud AI Platform:

Infine, ci piace ricevere feedback. Facci sapere se noti qualcosa di strano in questo lab o se ritieni che debba essere migliorato. I feedback possono essere inviati tramite i problemi di GitHub [link al feedback].

HR.png

Martin Görner ID small.jpg
L'autore: Martin Görner
Twitter: @martin_gorner

Tensorflow logo.jpg
www.tensorflow.org