Il tuo primo modello Keras, con Transfer Learning

1. Panoramica

In questo lab imparerai a creare un classificatore Keras. Invece di cercare la combinazione perfetta di livelli della rete neurale per riconoscere i fiori, utilizzeremo 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 il deep learning.

Questo lab è la seconda parte della serie "Keras on TPU". Puoi eseguirle nel seguente ordine o in modo indipendente.

ca8cc21f6838eccc.png

Obiettivi didattici

  • Per creare il tuo classificatore di immagini Keras con uno strato softmax e una perdita di cross-entropia
  • Per barare 😈, utilizzando il transfer learning anziché creare modelli personalizzati.

Feedback

Se noti qualcosa di strano in questo codelab, comunicacelo. Il feedback può essere fornito 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 addestramento senza costi per CPU, GPU e TPU.

688858c21e3beff2.png

Puoi aprire questo notebook di esempio ed eseguire alcune 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 del notebook

76d05caa8b4db6da.png

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

Sommario

429f106990037ec4.png

Tutti i notebook hanno un indice. Puoi aprirlo utilizzando la freccia nera a sinistra.

Celle nascoste

edc3dba45d26f12a.png

Alcune celle mostreranno solo il titolo. Questa è una funzionalità specifica dei notebook di Colab. Puoi fare doppio clic per visualizzare il codice all'interno, ma di solito non è molto interessante. In genere, funzioni di supporto o visualizzazione. Devi comunque eseguire queste celle per definire le funzioni al loro interno.

Autenticazione

cdd4b41413100543.png

Colab può accedere ai tuoi bucket Google Cloud Storage privati se esegui l'autenticazione con un account autorizzato. Lo snippet di codice riportato sopra attiverà una procedura 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 a utilizzare il deep learning, benvenuto e continua a leggere.

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

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

Si tratta della rete neurale più semplice per classificare le immagini. È composto da "neuroni" disposti in strati. Il primo livello elabora i dati di input e invia gli output ad altri livelli. Viene 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 appiattendo i valori RGB di tutti i suoi pixel in un lungo vettore 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 inserisce il risultato in una cosiddetta "funzione di attivazione". All'inizio, i pesi e il bias sono sconosciuti. Verranno inizializzati in modo casuale e "appresi" addestrando la rete neurale su molti dati noti.

644f4213a4ee70e5.png

La funzione di attivazione più popolare è chiamata ReLU, acronimo di Rectified Linear Unit. È una funzione molto semplice, come puoi vedere nel grafico sopra.

Attivazione Softmax

La rete precedente termina con un livello di 5 neuroni perché stiamo classificando i fiori in 5 categorie (rosa, tulipano, tarassaco, margherita, girasole). I neuroni negli strati intermedi vengono attivati utilizzando la classica funzione di attivazione ReLU. Nell'ultimo livello, invece, vogliamo calcolare numeri compresi tra 0 e 1 che rappresentano la probabilità che questo fiore sia una rosa, un tulipano e così via. Per questo, 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 di entropia incrociata

Ora che la nostra rete neurale produce previsioni dalle immagini di input, dobbiamo misurare la loro qualità, ovvero la distanza tra ciò che ci dice la rete e le risposte corrette, spesso chiamate "etichette". Ricorda che abbiamo le 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 utilizzare immagini e etichette di addestramento per regolare pesi e bias in modo da ridurre al minimo la funzione di perdita di entropia incrociata. Ecco come funziona.

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

Se calcoliamo le derivate parziali dell'entropia incrociata rispetto a tutti i pesi e a tutti i bias, otteniamo un "gradiente", calcolato per una determinata immagine, etichetta e valore attuale di pesi e bias. Ricorda che possiamo avere milioni di pesi e bias, quindi il calcolo del gradiente sembra un'attività molto impegnativa. 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 pesi e bias di una frazione del gradiente. Quindi, ripetiamo la stessa operazione più e più volte utilizzando i batch successivi di immagini e etichette di addestramento, in un ciclo di addestramento. Si spera che converga in un punto in cui l'entropia incrociata sia minima, anche se nulla garantisce che questo minimo sia univoco.

gradient descent2.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 e quindi è più probabile che converga più rapidamente verso la soluzione. 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 e queste sono generalmente più facili da ottimizzare su GPU e TPU.

La convergenza può comunque essere un po' caotica e può persino interrompersi se il vettore gradiente è tutto zero. Significa che abbiamo trovato un minimo? Non sempre. Un componente gradiente può essere zero su un minimo o un massimo. Con un vettore gradiente con milioni di elementi, se sono tutti zero, la probabilità che ogni zero corrisponda a un minimo e nessuno a un punto massimo è piuttosto bassa. In uno spazio con molte dimensioni, i punti di sella sono piuttosto comuni e non vogliamo fermarci.

52e824fe4716c4a0.png

Illustrazione: un punto di sella. Il gradiente è 0, ma non è un minimo in tutte le direzioni. (Attribuzione immagine Wikimedia: di Nicoguaro - Own work, 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 di addestramento ed etichette. In questo modo, l'algoritmo può convergere. 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 di entropia incrociata: una funzione di perdita speciale spesso utilizzata nei classificatori.

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

Caratteristiche: gli input di una rete neurale a volte vengono chiamati "caratteristiche". L'arte di capire quali parti di un set di dati (o combinazioni di parti) inserire in una rete neurale per ottenere buone previsioni è chiamata "ingegneria delle funzionalità".

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

Tasso di apprendimento: frazione del gradiente in base alla quale vengono aggiornati pesi e bias a ogni iterazione del ciclo di addestramento.

Logit: gli output di un livello di neuroni prima dell'applicazione della funzione di attivazione sono chiamati "logit". Il termine deriva dalla "funzione logistica", nota anche come "funzione sigmoide", che in passato era la funzione di attivazione più popolare. "Neuron outputs before logistic function" è stato abbreviato in "logits".

Perdita: 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 trasmette 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 è pari a 1.

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

sigmoid: un'altra funzione di attivazione che era molto popolare e 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 la somma sia pari a 1, in modo che possa essere interpretato come un vettore di probabilità. Utilizzato come ultimo passaggio nei classificatori.

Tensore: un "tensore" è come una matrice, ma con un numero arbitrario di dimensioni. Un tensore unidimensionale è un vettore. Un tensore bidimensionale è una matrice. Poi puoi 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 imparare a conoscere i livelli convoluzionali e i molti modi in cui è possibile disporli.

Ma possiamo anche prendere una scorciatoia. Sono disponibili per il download reti neurali convoluzionali completamente addestrate. È possibile eliminare l'ultimo livello, l'intestazione di classificazione softmax, e sostituirlo con il proprio. Tutti i pesi e i bias addestrati rimangono invariati, viene riaddestrato solo il livello softmax che aggiungi. Questa tecnica è chiamata transfer learning e, cosa sorprendente, funziona purché il set di dati su cui è pre-addestrata la rete neurale sia "abbastanza vicino" al tuo.

Pratico

Apri il seguente notebook, esegui le celle (Maiusc+Invio) e segui le istruzioni ovunque vedi l'etichetta "LAVORO RICHIESTO".

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

Ulteriori informazioni

Con il transfer learning, puoi usufruire sia di architetture avanzate di reti neurali convoluzionali sviluppate dai migliori ricercatori sia del pre-training su un enorme set di dati di immagini. Nel nostro caso, eseguiremo il transfer learning da una rete addestrata su ImageNet, un database di immagini contenente molte piante e scene all'aperto, che è abbastanza simile ai fiori.

b8fc1efd2001f072.png

Illustrazione: utilizzo di una rete neurale convoluzionale complessa, già addestrata, come scatola nera, riaddestramento solo dell'intestazione di classificazione. Questo è il transfer learning. Vedremo più avanti come funzionano queste complesse disposizioni di livelli convoluzionali. Per ora, è un problema di qualcun altro.

Transfer learning in Keras

In Keras, puoi istanziare un modello preaddestrato dalla raccolta tf.keras.applications.*. MobileNet V2, ad esempio, è un'ottima architettura convoluzionale che mantiene dimensioni ragionevoli. Se selezioni include_top=False, ottieni il modello preaddestrato senza il livello 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')
])

Nota anche l'impostazione pretrained_model.trainable = False. Congela i pesi e i bias del modello preaddestrato in modo da addestrare solo lo strato softmax. In genere, ciò comporta un numero relativamente ridotto di pesi e può essere eseguito rapidamente e senza richiedere un set di dati molto grande. Tuttavia, se disponi di molti dati, il transfer learning può funzionare ancora meglio con pretrained_model.trainable = True. I pesi preaddestrati forniscono quindi valori iniziali eccellenti e possono comunque essere modificati dall'addestramento per adattarsi meglio al tuo problema.

Infine, nota il livello Flatten() inserito prima del livello softmax denso. I livelli densi funzionano su vettori di dati piatti, ma non sappiamo se è questo che restituisce il modello preaddestrato. Ecco perché dobbiamo appiattire la curva. Nel capitolo successivo, quando approfondiremo le architetture convoluzionali, spiegheremo il formato dei dati restituito dai layer convoluzionali.

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

Soluzione

Ecco il notebook della soluzione. Puoi utilizzarlo se non riesci a risolvere il problema.

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

Argomenti trattati

  • 🤔 Come scrivere un classificatore in Keras
  • 🤓 configurato con un ultimo livello softmax e una perdita di entropia incrociata
  • 😈 Transfer learning
  • 🤔 Addestramento del primo modello
  • 🧐 Monitorando la perdita e l'accuratezza durante l'addestramento

Ti invitiamo a esaminare questo elenco di controllo.

5. Complimenti!

Ora puoi creare un modello Keras. Continua con il lab successivo per scoprire come assemblare i livelli convoluzionali.

TPU in pratica

TPU e GPU sono disponibili su Cloud AI Platform:

Infine, ci piacerebbe ricevere un tuo feedback. Comunicaci se noti qualcosa di strano in questo lab o se ritieni che debba essere migliorato. Il feedback può essere fornito 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