Come funzionano gli algoritmi? Come possono individuare oggetti o persone in una immagine? Vediamo come ciò può avvenire.
Neuroni e perceptroni nelle reti neurali
La struttura di base per arrivare all’individuazione del gatto sono le reti neurali. Le reti neurali tentano di replicare la struttura cerebrale mediante i neuroni, che possono avere più input e un output.
Ogni neurone è una piccola funzione che prende gli input, li moltiplica ognuno per un “peso” corrispondente, e genera un output (vedi figura). L’input può essere una costante o una variabile, e sicuramente sono più interessanti le variabili.
Ad esempio, se un neurone ha 3 input dati dai numeri 1,2,3 e tre pesi associati 11,12,13, l’output potrebbe essere: 1*1+2*12+3*13=1+24+39=64.
In questo caso il neurone usa una funzione di identità per passare da input e output, ovvero fa semplicemente l’operazione algebrica.
Ci sono neuroni che utilizzano una step function (danno ON se il valore è sopra zero, OFF se sotto zero): quindi nel caso precedente avremmo avuto ON. Nel caso si usi una step function il neurone viene detto perceptrone, considerato per la sua semplicità un po’ la madre di tutte le reti neurali.
Ci sono, per completezza, anche neuroni che utilizzano una sigmoid function, che somiglia alla step function ma invece di ON/OFF (1/0) dà dei valori più distribuiti.
Ovviamente un neurone da solo non può fare molto. Ecco allora che i neuroni vengono uniti in una rete, detta rete neurale. La rete neurale di solito si divide in 3 livelli (layer): layer di input, layer di output e layer nascosto (hidden) ovvero che non comunica con l’ambiente esterno.
Come si può vedere ogni neurone è collegato a uno o più neuroni del livello successivo in modo da permettere a ogni neurone del livello successivo di avere un certo numero di input.
Abbiamo quindi visto cosa è una rete neurale (vedi disegno sopra), come calcola il suo output mediante i pesi dato l’input (step function nel caso del perceptrone) e abbiamo capito che ci sono degli output che derivano da questi calcoli.
Ma cosa è un input? Nel campo della image detection un input può essere semplicemente una matrice di pixel. L’esempio più semplice di una matrice di pixel sono dei digit (0-9) in bianco e nero. Lo scopo della rete neurale è capire se, per un dato un digit scritto a mano, questo è un 1,2,3,4,5,6,7,8,9 o 0.
Nel caso dell’esempio sotto un digit è una matrice 28×28 di pixel in RGB (rosso verde e blu). Rosso verde e blu sono rappresentati da un numero che spazia da 0 a 256. Ognuno di questi pixel viene trasformato in un valore e quindi abbiamo 784 input della rete neurale. Tali input vengono processati dai diversi “hidden layer” della rete neurale per poi generare un risultato che dovrebbe essere ON per l’output corrispondente a 3 e OFF per gli altri.
Come le reti neurali imparano le istruzioni
Ma come fa la rete neurale a imparare? Per imparare ha bisogno di due meccanismi.
Il primo è un dataset di training, ovvero un insieme di immagini da cui imparare. Come un bambino, se non ha mai visto un 3, non può riconoscerlo. Quindi gli vengono mostrati dei set di training (gruppi di digit di ogni tipo 0-9) e la rete neurale prova a classificare. L’output viene confrontato con il risultato atteso (supervised learning) e si capisce se la rete sta imparando oppure no. Inizialmente la rete sbaglierà molto, non conoscendo il concetto di 3. Nel tempo imparerà (mano a mano che vede sempre più digit=3) a riconoscerli.
Ed eccoci arrivati al secondo elemento: come fa la rete a imparare se i pesi sono inizialmente pressoché casuali e se il flusso è da input layer a output layer senza retroazione sui pesi?
Si usa l’algoritmo di backpropagation, che permette mediante alcuni calcoli matematici basati sulla error function, sulla derivata e sul fatto che nel training set è indicato il digit con relativo valore atteso (supervised learning), di fare una sorta di “tuning” dei pesi mano a mano che la rete processa i dati del training set, permettendo alla rete neurale di migliorare la sua capacità di classificazione.
Questo permette di migliorare progressivamente la capacità di individuare un digit=3 su un’immagine RGB di 28×28.
Più il training set è numeroso, più la backpropagation migliora l’apprendimento della rete neurale, più la rete neurale diventa capace di classificare meglio il numero 3 (e così gli altri digit). A quel punto la rete neurale può essere utilizzata per classificare con un buon grado di approssimazione digit sconosciuti (non facenti parte del training set).
Tornando all’esempio del bambino, possiamo dire che dopo un buon numero di 3 visti, il bambino sarà in grado di distinguere molto bene un 3 da 1,2,4 …
Come può avvenire questo? Chiariamolo con un ulteriore esempio.
Ecco una matrice 5×5. L’obiettivo è individuare i sorrisi, rispetto alle facce tristi. Ogni pixel ha valore 0 se non colorato, 1 se colorato. La rete neurale potrebbe ad esempio imparare progressivamente che se i 3 pixel della riga più in basso al centro sono accesi, con buona probabilità la faccina rappresentata è un sorriso. Quindi potrebbe dare pesi più alti agli input di questi 3 pixel che ritiene più facilmente “discriminatori” per classificare una faccina triste da una felice. Questo è solo un esempio per capire il concetto.
Se abbiamo insegnato alla rete a individuare un digit (es. 3) o una faccina, l’abbiamo però fatto su una matrice molto ben definita, ovvero una 28×28 e una 5×5. Questo non ci dice niente se scaliamo la matrice passando da 28×28 a 1000×1000, oppure da 5×5 a 33×33.
Scalando in verità un trucco c’è: si potrebbe con qualche accorgimento matematico riportare il problema di 1000×1000 al problema di 28×28 accorpando a gruppi i pixel e facendo una riduzione. Questo funziona se l’unico oggetto nella matrice 1000×1000 è il digit, cosa tipicamente non possibile in una fotografia in cui (tornando al problema iniziale) vogliamo individuare un gatto.
Inoltre un gatto è abbastanza diverso da un digit, per la complessità dell’identificazione del suo concetto, molto più complesso anche di una faccina stilizzata.
Quindi abbiamo 3 problemi da risolvere con una rete neurale:
– come individuiamo un gatto? (indipendentemente dalla razza, colore …)
– come individuiamo un gatto su scale diverse (se in primo piano, in secondo piano?)
– come individuiamo un gatto in posizioni nell’immagine diverse e con posizioni del gatto diverse?
Entrano quindi in gioco le convolutional neural network, o reti neurali convolutive.
Il ruolo delle reti neurali convolutive (CNN)
Le convolutional neural network (CNN) sono parte del mondo del deep learning. Una rete neurale deep presenta numerosi hidden layer. Lo sviluppo delle deep neural network (DNN) è stato permesso soprattutto negli ultimi anni dalla diffusione delle GPU che permettendo calcolo parallelo, consentono di trasformare appunto da seriale a parallelo il calcolo delle reti neurali e quindi hanno aggiunto la possibilità di aumentare la profondità delle reti neurali (la profondità è data dal numero di hidden layers). Il calcolo parallelo permette di trasformare calcoli prima lunghissimi in calcoli molto veloci.
Tornando all’esempio della classificazione delle faccine felici o tristi su matrice 5×5, abbiamo di molto semplificato la classificazione, dicendo che poteva essere un’ipotesi probabile quella di considerare felice la faccina se erano accesi i 3 pixel dell’immagine sopra presentata.
È chiaro che non basta, per risolvere il problema la cosa migliore è aggiungere hidden layer e aumentare quindi la profondità della NN. Il fatto è che così facendo si aumenta il numero di neuroni e così il numero di collegamenti e pesi. Perché la rete quindi impari servono training set più ampi, cosi ampi da diventare “irrealistico” averli (si passa da qualche migliaio di esempi a diversi milioni o miliardi prima che i pesi siano “ottimizzati”).
Fortunatamente, una soluzione molto elegante che risolve il problema dei “troppi pesi” esiste e si chiama convolutional layer (CL).
Convolutional layer (CL), cosa sono e a cosa servono
Un CL è uno speciale tipo di layer che si può aggiungere a una rete neurale facendola diventare una CNN (convolutional neural network).
Quale è la sua caratteristica principale? Proprio quella che ci serve per individuare i gatti, ovvero può individuare una caratteristica specifica (nel nostro caso un gatto) perché è in grado di individuare caratteristiche specifiche dell’immagine come ad esempio:
- macchie di luce e buio
- macchie di un colore specifico
- bordi o contorni orientati in maniera diversa
- pattern
- altri oggetti simili
I CL permettono, grazie al loro inserimento, di individuare “concetti più complessi” di un digit o di una faccina, come ad esempio “le orecchie di un gatto” indipendentemente dalla scala o dall’orientamento. Possono essere usati anche per individuare “gli occhi di una persona”, “un segnale di stop” o “una figura ottagonale”.
Questo risponde a tutte e tre le domande sopra, ovvero: come individuo il concetto di “gatto”, come lo individuo se è scalato, come lo individuo in base alla posizione.
Il CL può essere immaginato come uno scanner che invece di prendere l’immagine in toto è in grado di farne una sorta di scansione e “capire” se nell’immagine ci sono le orecchie del gatto. Prima lo fa scansionando l’intera immagine, poi dividendola in 4 quadranti, poi in 8 e così via. Poi la gira di 90 gradi ad esempio e fa lo stesso e così via. Fino a essere in grado di individuare quello che ci serve ovunque sia.
Quindi, ad esempio, un gatto posto in un’immagine in alto a destra viene individuato non purché nel training set ci sia un’immagine con un gatto in alto a destra, bensì purché la rete neurale sia stata allenata (train) per imparare cosa è un gatto.
Questo è eccezionale se pensiamo a come le foto di un gatto possano variare per zoom, angolazione, esposizione, colore ecc.
Come funziona questo? Il “trucco” è molto intelligente e mira a ridurre al minimo il numero di training data (ovvero permettere come detto di individuare un gatto in alto a destra senza averne mai visto uno in altro a destra, ma solo avendo visto dei gatti, un po’ come facciamo noi esseri umani).
Il metodo porta a utilizzare gli stessi input per diversi neuroni, in modo che tali neuroni siano attivati dallo stesso pattern. Tali neuroni ricevono però in input diversi pixel del layer di input.
In tale modo, ovunque sia il gatto, questo verrà individuato, mediante quanto indicato sopra che si può semplificare in un effetto scanner, come spiegato precedentemente. Se c’è un gatto, lo vedrò mediante l’attivazione del CL layer.
Il CL tipicamente è posizionato nella parte bassa della rete neurale, ovvero molto vicino agli input in modo da ricevere i dati “grezzi” e non processati da altri neuroni. Questo permette spesso di usare unsupervised learning (non si conosce il risultato a priori nel training set) e di individuare semplicemente pattern ricorrenti nelle immagini, indipendentemente da quale sia il pattern. Per cui dando in pasto a questo livello (CL) tante foto di gatto, tipicamente la reti “basse” impareranno ad individuare musi e orecchie (essendo ricorrenti). Dando in pasto tante foto di edifici, le reti “basse” impareranno a individuare muri, piani e finestre, e così via.
In tale modo si possono pre-allenare CL per individuare specifici pattern generici e quindi usarle “agganciandole” ad altre neural network per riutilizzarle in differenti processi di image recognition.
I livello “superiori” della rete neurale, invece andranno comunque allenati mediante supervised learning e backpropagation.
È interessante quindi come i layer CL siano general purpose e in grado di individuare macro aspetti dell’immagine in maniera unsupervised. Sono anche riutilizzabili.
Il risultato, unendo layer CL e una neural network che impara mediante backpropagation e supervised learning, sono immagini come quella seguente, dove una rete neurale (o più reti neurali i cui risultati vengono sommati) sono in grado di individuare persone e oggetti, arrivando a definire l’oggetto (es. statua, lampione etc etc), solitamente con un grado di probabilità di efficacia associato (ovvero è una persona al 0.91 di probabilità su 1).
Ecco spiegato come una rete neurale grazie ai CL diventa una CNN e può classificare l’immagine di un gatto, di una persona o di un oggetto.
Che cosa sono le GAN
Cosa sono le GAN (Generative Adversarial Network) nell’ambito delle reti neurali?
Le reti “basse” in una rete neurale imparano i tratti ricorrenti, mentre le reti “alte” imparano concetti più complessi. I livelli alti, che sono stati allenati mediante supervised learning, sono utili per il task specifico. Quindi se una rete è stata allenata per individuare un segnale di stop, sarà in grado con i suoi livelli superiori di fare quello e sarà inutile per individuare, ad esempio, un gatto o un digit (0-9).
Un risultato invece curioso si ottiene prendendo i livelli “bassi” e analizzando cos’hanno imparato. Questo può essere ottenuto facendo generare ai livelli bassi immagini attivando un certo gruppo di neuroni nei livelli bassi. Ovvero portando la rete, invece che a classificare, a generare immagini. È come se si chiedesse a un bambino, una volta imparato a riconoscere un gatto, di disegnarlo. Solo che le reti neurali non sono bambini e sono in grado ri-disegnare fedelmente quanto hanno imparato.
Guardando le immagini generate, si vede come le reti neurali abbiano individuato con precisione delle caratteristiche, ma le rappresentino a modo loro, come se fossero “sogni” o “reti allucinate” come si può vedere nel DeepDream system di Google.
Nota: parlare di reti allucinate o sognanti, non vuol dire che siano in grado di sognare. Si parla solo dell’effetto delle immagini generate che è curioso al punto da portare a usare questi termini. Si intende solo che sono in grado di generare immagini simili ai dati di allenamento, una volta che li hanno processati.
Per generare gatti, facce umane o oggetti non esistenti ma che sembrino tali, Ian Goodfellow, che lavora al progetto Google Brain, ha proposto una combinazione interessante tra due reti neurali. L’idea di base è stata quella di far competere tra loro le due reti. Una rete si allena a generare immagini come quelle nel training data, l’altra rete analizza le immagini e il suo compito è separare le immagini generate dalla prima rete e quelle reali, prese dal training set. La prima rete è generativa, la seconda è detta avversaria. L’intero sistema è detto “Generative Adversarial Network”, ovvero GAN.
Come agisce un sistema GAN
Il sistema quindi allena due modelli, che si allenano insieme. All’inizio dell’allenamento, è facile individuare le immagini reali da quelle generate dalla rete generativa (visto che sono piuttosto diverse). Poi, ripetendosi a “velocità computer” i cicli di creazione immagine e verifica, diventa sempre più difficile distinguere le immagini reali da quelle generate, ovvero la rete neurale generativa impara a generare immagini che sembrano reali.
Questo è permesso dal fatto che mentre migliora la rete generativa, migliora anche la rete avversaria, in un percorso verso l’ottimizzazione di entrambe.
Il risultato si può vedere nelle immagini pubblicate sotto:
Le immagini sopra sono generate da una GAN sviluppata da Nvidia in un progetto del professor Jaakko Lehtinen (articolo di dettaglio). È difficile capire quelle generate da una GAN rispetto a quelle reali!