sabato 11 dicembre 2021

Le reti neurali convoluzionali.

Le reti neuronali convoluzionali (CNN) sono un particolare tipo di reti neurali artificali (ANN) utilizzate per lo piu’ per la classificazione delle immagini. Le CNNs si ispirano al principio biologico della riproduzione di una struttura capace di identificare dei patterns in diversi luoghi descritta nell’articolo dei premi Nobel Hubel e Wiesel pubblicato nel 1962 e dal titolo: “Receptive fields, binocular interaction and functional architecture in the cat’s visual cortex”. Queste reti oltre alla classificazione delle immagini hanno mostrato buoni risultati anche con le analisi delle serie temporali e il riconoscimento vocale. Esse sono diventate molto popolari dopo che nel 2012 hanno vinto la competizione  Imagenet Large Scale Visual Recognition Challenge (ILSVRC)  con un margine addirittura del 10%.  Alex Krizhevsky e Ilya Sutskever, sotto la guida di Geoffrey Hinton, proposero l’architettura CNN che presto divento’ famosa con il nome di “AlexNet”. A quel tempo, Geoffrey Hinton era gia’ conosciuto per i suoi contributi scientifici nel campo delle reti neurali artificiali. Egli era stato uno dei contributori dell’algoritmo di Backpropagation nel 1986, e delle macchine di Boltzmann nel 1983. Queste sono alcune delle ragioni per cui Geoffrey Hinton e’ stato riconosciuto come uno dei padri del Deep Learning. Una CNN tipica e’ composta da una serie di strati convoluzionali, che agiscono come estrattori di features, seguiti da un classificatore, in genere un Multilayer Perceptron (MLP), anche conosciuto come una rete a strati completamente connessi (FC) come mostrato in figura 1.

image_thumb1

Figura 1. Gli strati di una CNN

 

Il primo strato riceve in input un’immagine rappresentata nei 3 canali colore RGB. Questo significa avere un array con una certo numero di pixels come per esempio 100x100 ripetuto 3 volte, uno per ogni canale colore. Si tratta quindi di un oggetto con dimensione 100x100x3 che prende il nome di tensore. Infatti l’immagine 100x100 e’ una matrice bidimensionale mentre l’aggiunta dei 3 canali rende questo oggetto non piu’ bidimensionale ma tridimensionale come si puo’ vedere nella prima parte della figura 1. Il primo strato esegue le convoluzione dell’immagine in ingresso con diversi kernel, generando una serie di feature maps del primo strato. Ogni feature map determina l’intensita’ e la localizzazione di una specifica feature. La feature map estratta dallo strato convoluzionale puo’ essere sottomessa ad un’operazione di downsampling conosciuta come Pooling. Questa operazione e’ opzionale cosi e’ possible che essa non segua tutti gli strati convoluzionali. Il risultato di uno strato di Pooling e’ un altro insieme di feature maps ma con ridotta risoluzione. Il successivo strato convoluzionale usa la feature map dello strato precedente per eseguire piu’ convoluzioni e generare nuove feature maps. Le feature maps dell’ultimo strato diventano l’input del classificatore e cioe’ degli strati FC full connected. L’operazione di convoluzione che viene indicata con un asterisco ∗, puo’ essere descritta con la seguente formula:

image7_thumb

essendo x un tipo di input, t un tempo e k il kernel applicato. Il kernel in pratica e’ una matrice di pesi ed esso viene applicato ad una sotto matrice dell’immagine conosciuta come receptive field in biologia (una regione sensoriale che stimola un neurone). La moltiplicazione tra il receptive field e il kernel consiste nella moltiplicazione di ogni pixel e i rispettivi elementi del kernel. Dopo le moltiplicazioni, i risultati vengono aggiunti a formare un elemento della feature map definita dall’equazione con 3 canali RGB:

image14_thumb

 

Le seguenti immagini mostrano l’operazione di convoluzione per un’immagine in grigio 5x5 e un kernel 3x3. Il receptive field e’ stato evidenziato in rosso. L’output della convoluzione e’ una feature map 3x3. Occhio. Le 2 matrici kernel e Recept non vengono moltiplicate con la regola delle matrici ma semplicemente moltiplicando un elemento alla volta. Ogni cella della feature map viene costruita facendo la somma di tutti gli elementi della matrice ottenuta con la moltiplicazione e indicata con sum nella figura.

image18_thumb

image21_thumb

image24_thumb

Figure 2 — Alcuni steps della convoluzione di un’immagine 5x5 con un kernel 3x3.

Le immagini utilizzate in figura 2 possono essere viste nella figura 3. I valori del kernel e della feature map sono stati riscalati tra 0 e 255 per essere rappresentati in una scala di grigi. I pixels bianchi corrispondono a valori prossimi a 255 mentre quelli neri a valori prossimi allo 0.

clip_image014_thumb1

Figure 3 — Convoluzione di una matrice 5x5 con un kernel 3x3

 

Poiche’ la convoluzione della figura 2 usa un kernel 3x3 ci sono 9 possibili receptive fields in input ognuno con una dimensione 3x3. Notare che quando la Receptive field contiene tutti pixels chiari la somma delle celle della matrice ottenuta agendo con il kernel e’ scura e viceversa. Nella figura 2 infatti quando la receptive field ha tutti valori maggiori di 200 la cella corrispondente nella feature map ha come valore 44. Questo e’ dovuto al fatto che il kernel utilizzato evidenzia i contorni passando da un colore brillante sulla sinistra ad un colore scuro sulla destra della matrice. Vediamo adesso cosa accade se applichiamo lo stesso kernel ad un immagine che ha una transizione da una regione scura a sinistra ad una chiara sulla destra. In Figura 4, il receptive field esibisce la transizione dai pixel scuri a quelli chiari e da quelli chiari a quelli scuri. Notare come il kernel identifica gli estremi della stripe segnalandoli con una fascia chiara a sinistra e una scura a destra.

clip_image016_thumb

Figure 4 — Convoluzione di un immagine 17x17 con un kernel per evidenziare gli estremi

 

Passiamo adesso ad un esempio pratico. Qui di seguito la foto a colori di un aereo su cui viene applicato un kernel 3x3 estratto da una piccola regione dell’immagine stessa.

              image_thumb11image_thumb12 

image_thumb13  Figure 5 — Esempi di convoluzione .

 

Nel primo esempio, il kernel comprende la regione della foto con il numero 6 in bianco. L’immagine in grigio sulla destra e’ il risultato della convoluzione tra il kernel e l’immagine stessa. I pixels piu’ scuri rappresentano I valori piu’ bassi ottenuti dall’operazione del kernel sulla receprive field mentre quelli piu’ chiari rappresentano I valori piu’ alti. Nel secondo esempio il kernel e’ costituito da una ruota dell’aereo mentre nel terzo viene riportato il colore giallo dell’aereo. Notare che I pixels piu’ brillanti sono quelli che corrispondono alla parte dell’immagine contenuta nel kernel: numero 6 nel primo caso, la ruota nel secondo e le pareti di colore giallo dell’aereo nel terzo. Osserviamo anche che se la seconda ruota non e’ contenuta nel kernel anch’essa risulta brillante essendo molto simile alla prima ruota. Altra caratteristica importante di una CNN e’ il passo (stride) tra ogni receptive field. Tutti gli esempi mostrati fino ad adesso avevano passo 1. L’adozione di un passo cosi piccolo risulta in una sovrapposizione abbastanza spinta tra i receptive field. Il risultato e’ che molta informazione viene ripetuta tra i receptive field adiacenti come mostrato in figura 6.

 

image36_thumb1

Figure 6 – Receptive field con passo (stride) 1.

In caso di  kernel con dimensioni 3x3, l’utilizzo di un passo (stride) 2 risulta in una colonna o riga di sovrapposizione con il receptive field adiacente. Aumentando lo stride si riduce il costo computazionale del PC. Passando da uno stride di 1 a 2 abbiamo una riduzione del costo di un fattore 4. Questo accade in quanto lo stride 2 impatta la distanza tra i receptive field in entrambe le dimensioni. Allo stesso modo se triplichiamo il passo il costo computazionale si ridurra’ di un fattore 9. Il costo di computazione si riduce in quanto aumentando il passo si riduce il numero di receptive field estratti dall’input e di conseguenza si riduce la dimensione dell’output. La figura 7 mostra 4 esempi di convoluzione con passi (strides) di 2, 4, 8, e 16. La dimensione del kernel e’ di 70x70. Notare che aumentando il passo di un fattore 2 il tempo di esecuzione si riduce di circa un fattore 4.

image_thumb15image_thumb16image_thumb17

Figura 7 — Esempi di stride 2, 4, 8, e 16. La dimensione del kernel e’ di 70x70.

Grafico del tempo di elaborazione verso lo stride

Osserviamo come aumentando il passo riduciamo il tempo di calcolo e il numero di pixels dell’immagine nonostante sia ancora possibile individuare i valori piu’ alti della convoluzione grazie ai pixel piu’ brillanti in alcune zone dell’aereo. Adesso andiamo a vedere come lavora un singolo strato convolutivo e cosa succede quando ne mettiamo insieme un certo numero. La figura 8 mostra cosa succede all’interno dello strato convoluzionale che consiste di 3 stadi: convoluzione, attivazione non lineare, e pooling. L’operazione di convoluzione l’abbiamo discussa nella prima parte. Adesso vediamo le altre 2 operazioni.

 

clip_image032_thumb1

Figura 8 — I 3 stadi di uno strato convolutivo.

 

L’attivazione non lineare e’ conosciuta anche come lo stadio del rivelatore. Qui il risultato della convoluzione e il bias vengono sottomessi ad una funzione di attivazione non lineare come la funzione ReLU. Quest’ ultima non cambia la dimensione della feature map ma modula solo i valori contenuti in essa. Ma che cosa e’ un’attivazione non lineare? Prima di tutto ricordiamo che la non linearita’ in una rete neurale ANN la rende migliore in termini di approssimazione  di funzioni. Una delle funzioni di attivazione non lineare piu’ utilizzata e’ la funzione ReLU, che sta per Rectified Linear Unit. Questa funzione e’ data da:

image48_thumb 

Questa funzione quando applicata con un bias, da’ origine a grafici com quelli illustrati in Figura 9.

 

image51_thumb  Figura 9 — Grafico della funzione ReLU.

 

La figura 10 mostra come la ReLU modula il risultato della convoluzione. L’immagine e il kernel sono gli stessi della figura 2 dove la convolution output e’ quella che prima abbiamo chiamata la feature map.

clip_image038_thumb

Figura 10 — La funzione ReLU applicata all’aoutput della convoluzione.

 

L’immagine equivalente in scala di grigio prima e dopo l’applicazione della funzione ReLU e’ riportata in Figura 11. Notare come alcuni dei valori intermedi sono stati anneriti facendo risaltare ancora di piu’ i 3 pixels con valore diverso da zero.

image_thumb22  Figura 11 — Rappresentazione visuale della funzione ReLU applicata all’output della convoluzione.

 

Nella figura 12, si puo’ vedere come lavora il bias nella funzione ReLU. Il bias si comporta come una soglia che determina cosa mostrare e cosa no.

clip_image042_thumbclip_image044_thumb

Figura 12 — Diversi valori di bias applicati allo stesso risultato della convoluzione dell’immagine contenente le ruote dell’aereo.

Il comportamento a soglia della figura 12 rassomiglia ai neuroni biologici, che non si attivano quado ricevono uno stimolo al di sotto di una certa soglia. Se lo stimolo supera la soglia, il neurone si accende e la frequenza di accensione cresce con l’aumento dello stimolo. In Figura 12, quando il bias e’ 500, esso contribuisce all’attivita’ dei neuroni artificiali. Ma se definiamo il bias a -1000, allora il neurone artificiale si accende solo son stimoli piu’ forti. Per concludere la funzione ReLU lavora come un neurone del nostro cervello. Questo spiega perche’ questa fase e’ chiamata la fase di rivelazione. La funzione ReLU e’ quella che rivela la presenza di una feature estratta dal kernel. Di conseguenza c’e’ un singolo bias per ogni kernel, perche’ ogni feature richiede una differente soglia di attivazione. Alla fine, arriva l’operazione di pooling. Si tratta di un’operazione di sottocampionamento eseguita su ogni feature map. Essa estrae i receptive fields dalla feature map e li rimpiazza con un singolo valore. Questo valore puo’ essere ottenuto attraverso diversi criteri di aggregazione, come il valore massimo, media o media pesata in base alla distanza dal centro del receptive field. Oltre ai criteri di aggregazione ci sono altri 2 ipeparametri nell’operazione di pooling: la dimensione del receptive field e il passo. In modo simile allo stride, l’operazione di pooling genera meno dati di quelli processati dalla convoluzione. Una differenza e’ che invece di saltare dei dati, l’operazione di pooling cerca di riassumere il receptive field in un singolo valore. Un’altra differenza e’ che il passo viene applicato prima della convoluzione, mentre il pooling viene applicato sui risultati della convoluzione, riducendo il volume dei dati al prossimo strato. Inoltre il receptive field dell’operazione di pooling e’ bidimensionale in quanto esso viene applicato ad ogni feature della mappa individualmente mentre il receptive field della convoluzione e’ tri-dimensionale. Un effetto desiderato collaterale del pooling e’ che aumenta l’invarianza delle transazioni degli inputs. Questo effetto a’ amplificato dal numero di strati convoluzionali seguiti dagli strati di pooling. La figura 13 mostra la propagazione dei valori attraverso due strati di pooling con size 3x3 e stride di 2. Per ogni regione di attivazione colorata in blu l’input feature map influenza la regione colorata in blu in uscita dal pooling 1. Allo stesso modo , le attivazioni nella regione coperta di blu in uscita del pooling 1 influenzano la regione ricoperta di blu in uscita del pooling 2. La stessa relazione e’ valida tra le regioni di colore verde.

image59_thumb1

Figura 13–Propagazione di valori attraverso gli strati di pooling con dimensione 3x3 e stride 2. In questo esempio, gli strati convoluzionali sono stati omessi per chiarezza.

 

Considerando che il pooling in Figure 13 e’ il max pooling, indipendentemente da dove capita il valore piu’ alto nella feature map blu in input, esso verra’ propagato nella matrice blu in uscita. Questa e’ la ragione per cui gli strati di pooling amplificano l’invarianza traslazionale (piccole variazioni in ingresso non cambiano i valori in uscita). La figura 14 mostra l’effetto delle diverse combinazioni di strides nella convoluzione, bias nella funzione ReLU,  dimensione del pooling e i passi (strides) di pooling. Sulla sinistra ci sono 3 esempi di strides: 2, 9, e 16. Per ogni opzione di stride ci sono 3 esempi di bias: 500, -250, e -1000. Per ogni bias, ci sono 3 esempi di dimensione del pooling e stride: 3x3 e 2, 5x5 e 3, 7x7 e stride of 4.

clip_image048_thumb

Figura 14– effetti di diversi iperparametri nella convoluzione, ReLU e max pooling.

L’ effetto dello stride nella convoluzione e dello stride nel max-pooling e’ cumulativo. Quando usiamo un passo di 2 sia nella convoluzione che nel max pooling, il risultato finale e’ una riduzione di quasi 4 volte la larghezza e l’altezza della feature map. Il valore 16 come passo nella convoluzione e di 4 nel max pooling sono abbastanza inusuali. In questo caso sono stati intenzionalmente esagerati per illustrare l’impatto che hanno sul risultato finale dello strato di convoluzione. Gli elementi costitutivi di una rete AlexNet vengono rappresentati in figura 14. Le piramidi riportate con linee spezzate rappresentano l’esecuzione delle convoluzioni usando un receptive field dagli inputs o la feature map dagli strati precedenti. Le grosse scatole rappresentano le feature maps mentre le scatole piccole all’interno delle feature maps sono i receptive fields. Questo tipo di CNN riescono a classificare oggetti in 1000 diverse classi.

clip_image050_thumb

Figura 15 — Architettura di AlexNet CNN.

Una peculiarita’ di questa architettura e’ che essa viene addestrata usando 2 GPU (Graphics processing units). Gli elementi al top della figura 15 sono stati allocati in una GPU, mentre gli elementi al bottom sono stati allocati in un’altra GPU. Questa rete CNN gia’ addestrata e’ possibile trovarla in qualche framework come PyTorch. In questi casi c’e’ bisogno di conoscere Python e buttare giu’ linee di codice prima di ottenere i risultati sperati. Un modo alternativo che non richiede nessuna linea di codice e’ quello di costruire una rete personalizzata CNN usando per esempio l’eccellente console per deep neural net messa a disposizione dalla Deep Cognition (o deep learning studio DLS). Si tratta di un sistema user-friendly con molte features, incluso la possibilita’ di disegnare la topologia della rete senza scrivere nessuna linea di codice interagendo con una semplice GUI. Come riportato dai creatori di questa piattaforma, Deep Cognition nasce con lo scopo di democratizzare l’intelligenza artificiale. La loro piattaforma e’ disponibile sia come soluzione Cloud che come Desktop solution nel qual caso il software girera’ sul personal PC . L’interfaccia permette un semplice drag & drop che aiuta a mettere insieme i diversi pezzi di una deep net. C’e’ anche la possibilita’ di utilizzare delle reti pre-trained come Inception, ResNet, MobileNet e cosi via per velocizzare la fase di apprendimento. Questo e’ possibile in quanto nei primi layers di una rete vengono catturate le feature piu’ importanti e molto generiche che possono essere utilizzate per esempio nella classificazione di qualsiasi immagine. La piattaforma salva velocemente qualsiasi modello dopo il training e l’aggiustamento degli iper-parametri (come per esempio learning rate, epochs, batch size etc) della rete.

clip_image052_thumb

 

Di seguito un esempio di utilizzo di una CNN per il riconoscimento delle 9 cifre scritte a mano (il famoso MNIST dataset – fig. 16). In questo caso ogni cifra e’ rappresentata da un’array 28x28 come mostrato nella figura 17 e valori da 0 a 255 (28X28X1).

 

clip_image054_thumb1

Fig 16. Alcune delle cifre del dataset MNIST

 

clip_image056_thumb

Figura 17. La rappresentazione matriciale dell’ 8

 

In figura 18 invece e’ riportata la divisione del database in training set (90%), validation set (5%) e test set (5%). Tutte le righe del database vengono presentate alla rete a batch (insieme di piu’ righe per abbattere il rumore)

clip_image058_thumb

Figura 18. Data pre-processing

Deep Learning Studio permette di disegnare una qualsiasi rete senza scrivere nessuna riga di codice ma semplicemente mettendo insieme i diversi moduli a disposizione, oppure provvedendo esso stesso a costruire l’architettura della rete in modo automatico senza alcun intervento da parte dell’analista grazie ad un’avanzata feature chiamata AutoML (figura 19), che crea per l’utente l’intera pipeline per andare dai dati grezzi fino alla predizione. In figura  20 la rete convoluzionale utilizzata per la classificazione del data set MNIST.

clip_image060_thumb

Figure 19. AutoML

 

clip_image062_thumb4

Figura 20. L’architettura della CNN

 

clip_image064_thumb

Figura 21. Iperparametri

 

Una volta stabiliti i valori degli iper-parametri (figura 21)  si passa alla fase di training della rete CNN. Dopo appena 6 epoche su 10 la rete ha raggiunto un’accuratezza del 89% per il training set e il 91% per il set di validation. Un risultato niente male (figura 22).

clip_image066_thumb1

Figura 22. Training della rete CNN con i risultati di accuracy e loss

 

Qui alcune cifre del test set riconosciute dalla rete con a fianco  la probabilita’ della predizione. Per il 4 nella prima riga, per esempio la rete e’ sicura all’82% che si tratti proprio di un quattro e cosi via per le altre cifre (figura 23).

clip_image068_thumb1

Figura 23. Predizione della rete per le cifre del test set

 

Questo sistema DLS e’ nato con la promessa di rendere facile l’intelligenza artificiale; non c’e’ bisogno di essere un esperto per realizzare modelli molto complessi anche se e’ opportuno avere almeno un’idea di quello che si sta facendo leggendo i documenti di help e i tutorial presenti sul sito della Deep cognition. Non resta che provare. Buon divertimento.

http://www.wikio.it