Esplorare l’estrazione delle funzionalità con le CNN |  di Rodrigo Silva |  Novembre 2023

 | Intelligenza-Artificiale

Le reti neurali convoluzionali sono gli elementi costitutivi odierni per le attività di classificazione delle immagini utilizzando l’apprendimento automatico. Tuttavia, un altro compito molto utile che svolgono prima della classificazione è quello di estrarre le caratteristiche rilevanti da un’immagine. L’estrazione delle caratteristiche è il modo in cui le CNN riconoscono i modelli chiave di un’immagine per classificarla. Questo articolo mostrerà un esempio di come eseguire estrazioni di funzionalità utilizzando TensorFlow e l’API funzionale Keras. Ma prima, per formalizzare questi concetti della CNN, dobbiamo parlare prima dello spazio dei pixel.

Spazio pixel

Lo spazio dei pixel è esattamente ciò che suggerisce il nome: è lo spazio in cui l’immagine viene convertita in una matrice di valori, dove ogni valore corrisponde a un singolo pixel. Pertanto, l’immagine originale che vediamo, quando viene immessa nella CNN, viene convertita in una matrice di numeri. Nelle immagini in scala di grigio, questi numeri in genere vanno da 0 (nero) a 255 (bianco) e i valori intermedi sono sfumature di grigio. In questo articolo tutte le immagini sono state normalizzate, cioè ogni pixel è stato diviso per 255 quindi il suo valore si trova nell’intervallo (0, 1).

CNN e spazio pixel

Ciò che una CNN fa con l’immagine nella rappresentazione in pixel è applicare filtri ed elaborarla al fine di estrarre i pixel rilevanti per prendere la “decisione” finale, ovvero inserire quell’immagine in una classe. Ad esempio, nell’immagine in cima alla pagina, la CNN ha prestato molta attenzione alla bocca, alla lingua, agli occhi del leone (e ai forti contorni in generale), e queste caratteristiche vengono ulteriormente estratte man mano che entriamo più in profondità nella rete neurale. . Basti quindi dire che quanto più una CNN è specializzata in termini di classificazione, tanto più professionale è nel riconoscere le caratteristiche chiave di un’immagine.

L’obiettivo

Detto questo, l’obiettivo è semplice: vedere il livello di specializzazione di una CNN quando si tratta di estrazione di funzionalità.

Il metodo

Per fare questo ho addestrato due CNN con la stessa architettura, ma con dimensioni di training diverse: una con immagini da 50K (questa è la segno di riferimentoquello intelligente) e l’altro con immagini da 10K (questo è il manichino uno). Successivamente, ho suddiviso gli strati della CNN per verificare cosa vede l’algoritmo e il senso che dà all’immagine immessa.

Set di dati

Il set di dati utilizzato per questo progetto è stato ampiamente utilizzato cifar10 set di dati di immagini (1), un set di dati di dominio pubblico, ovvero una base di immagini di 60.000 immagini suddivise in 10 classi, di cui 10.000 immagini vengono utilizzate come set di convalida di controllo. Le immagini hanno una dimensione di 32×32 pixel e sono di colore RGB, ovvero 3 canali di colore.

Per evitare fughe di dati, ho conservato un’immagine da utilizzare come immagine di prova nel riconoscimento delle caratteristiche, quindi questa immagine non è stata utilizzata in nessuno dei corsi di formazione. Vi presento la nostra cavia: la rana.

La rana.

L’implementazione è mostrata nello snippet di codice seguente. Per suddividere correttamente i layer della CNN è necessario utilizzare l’API funzionale Keras in TensorFlow anziché l’API Sequential. Funziona come una cascata, dove il livello successivo viene richiamato sull’ultimo.

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, MaxPool2D, Dense, Dropout, Flatten
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

def get_new_model(input_shape):
'''
This function returns a compiled CNN with specifications given above.
'''

#Defining the architecture of the CNN
input_layer = Input(shape=input_shape, name='input')
h = Conv2D(filters=16, kernel_size=(3,3),
activation='relu', padding='same', name='conv2d_1')(input_layer)
h = Conv2D(filters=16, kernel_size=(3,3),
activation='relu', padding='same', name='conv2d_2')(h)

h = MaxPool2D(pool_size=(2,2), name='pool_1')(h)

h = Conv2D(filters=16, kernel_size=(3,3),
activation='relu', padding='same', name='conv2d_3')(h)
h = Conv2D(filters=16, kernel_size=(3,3),
activation='relu', padding='same', name='conv2d_4')(h)

h = MaxPool2D(pool_size=(2,2), name='pool_2')(h)

h = Conv2D(filters=16, kernel_size=(3,3),
activation='relu', padding='same', name='conv2d_5')(h)
h = Conv2D(filters=16, kernel_size=(3,3),
activation='relu', padding='same', name='conv2d_6')(h)

h = Dense(64, activation='relu', name='dense_1')(h)
h = Dropout(0.5, name='dropout_1')(h)
h = Flatten(name='flatten_1')(h)
output_layer = Dense(10, activation='softmax', name='dense_2')(h)

#To generate the model, we pass the input layer and the output layer
model = Model(inputs=input_layer, outputs=output_layer, name='model_CNN')

#Next we apply the compile method
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=('accuracy'))

return model

Le specifiche dell’architettura sono mostrate di seguito in Fig. 1.

Fig. 1: Riepilogo delle CNN utilizzate. Immagine dell’autore.

L’ottimizzatore utilizzato è Adam, la funzione di perdita era l’entropia incrociata categorica e la metrica utilizzata per la valutazione era semplicemente l’accuratezza, poiché il set di dati è perfettamente bilanciato.

Ora possiamo affettare alcuni strati strategici delle due CNN per verificare il livello di elaborazione delle immagini. L’implementazione del codice è mostrata di seguito:

benchmark_layers = model_benchmark.layers
benchmark_input = model_benchmark.input

layer_outputs_benchmark = (layer.output for layer in benchmark_layers)
features_benchmark = Model(inputs=benchmark_input, outputs=layer_outputs_benchmark)

Ciò che accade qui è il seguente: la prima riga accede a ciascun livello del modello e la seconda riga restituisce il livello di input dell’intera CNN. Quindi nella terza riga creiamo un elenco che mostra gli output di ciascun livello e, infine, creiamo un nuovo modello, i cui output sono gli output dei livelli. In questo modo possiamo dare un’occhiata a cosa sta succedendo tra gli strati.

Un codice molto simile è stato scritto per accedere ai livelli del nostro modello fittizio, quindi verrà omesso qui. Procediamo ora a guardare le immagini della nostra rana, elaborate all’interno di diversi strati delle nostre CNN.

Primo strato convoluzionale

Manichino

La Fig. 2 mostra le immagini dei 16 filtri dello strato convoluzionale (conv2d_1). Possiamo vedere che le immagini non sono super elaborate e c’è molta ridondanza. Si potrebbe sostenere che questo è solo il primo strato convoluzionale, il che spiega il fatto che l’elaborazione non è così pesante, e questa è un’osservazione giusta. Per affrontare questo problema, esamineremo il primo livello del benchmark.

Fig. 2: Primo strato convoluzionale del classificatore fittizio. Immagine dell’autore.

Segno di riferimento

Il classificatore benchmark mostra un’immagine molto più elaborata, al punto che la maggior parte di queste immagini non sono più riconoscibili. Ricorda: questo è solo il primo strato convoluzionale.

Fig. 3: Primo strato convoluzionale del classificatore benchmark. Immagine dell’autore.

Ultimo strato convoluzionale

Manichino

Come previsto, l’immagine non è più riconoscibile, poiché a questo punto abbiamo attraversato 6 livelli convoluzionali e 2 livelli di pooling, il che spiega le dimensioni inferiori delle immagini. Vediamo come appare l’ultimo livello del benchmark.

Fig. 4: Ultimo strato convoluzionale del classificatore fittizio. Immagine dell’autore.

Segno di riferimento

Questo è ancora più elaborato, al punto che la maggior parte dei pixel sono neri, il che dimostra che le caratteristiche importanti sono state selezionate e il resto dell’immagine viene praticamente buttato via.

Fig. 5: Ultimo strato convoluzionale del classificatore di benchmark. Immagine dell’autore.

Possiamo vedere che i gradi di elaborazione sono molto diversi per la stessa porzione di rete. L’analisi qualitativa indica che il modello benchmark è più aggressivo quando si tratta di estrarre informazioni utili dall’input. Ciò è particolarmente evidente dal confronto del primo livello convoluzionale: l’output dell’immagine della rana è molto meno distorto e molto più riconoscibile sul manichino rispetto al modello benchmark.

Ciò suggerisce che il benchmark è più efficiente nel scartare elementi dell’immagine che non sono utili per prevedere la classe, mentre il classificatore fittizio, incerto su come procedere, considera più funzionalità. Possiamo vedere nella Fig. 6 che il benchmark (in blu) scarta più pixel colorati rispetto al modello fittizio (in rosso), che mostra una coda più lunga nella distribuzione dei colori.

Fig. 6: Distribuzione di probabilità per i pixel nell’ultimo strato. Possiamo vedere che i pixel del benchmark (in blu) sono più schiacciati verso lo zero, mentre i pixel sl della modalità fittizia (in rosso) mostrano una coda più lunga.

Se diamo un’occhiata alla distribuzione dei pixel della nostra immagine originale della rana, abbiamo la Fig. 7, che mostra una distribuzione molto più simmetrica, centrata più o meno intorno a 0,4.

Fig. 7: Distribuzione dei colori della nostra immagine originale della rana. Immagine dell’autore.

Dal punto di vista della teoria dell’informazione, le differenze nelle distribuzioni di probabilità tra l’immagine originale e le immagini risultanti dopo gli strati convoluzionali rappresentano un enorme guadagno di informazioni.

Osservando la Fig. 6 e confrontandola con la Fig. 7, siamo molto più certi di quali pixel troveremo nella prima che nella seconda. Quindi c’è un guadagno di informazioni. Questa è un’esplorazione molto breve e qualitativa della Teoria dell’Informazione e apre la porta ad una vasta area. Per ulteriori informazioni sulle Informazioni (gioco di parole), vedere questo inviare.

Infine, un modo per esaminare l’incertezza nella risposta dei classificatori è osservare la distribuzione di probabilità sulle classi. Questo è l’output della funzione sofmax, alla fine della nostra CNN. La Fig. 8 (a sinistra) mostra che il benchmark è molto più certo della classe, con una distribuzione che raggiunge il picco nella classe della rana; mentre la Fig. 8 (a destra) mostra un classificatore fittizio confuso, con la più alta probabilità nella classe sbagliata.

Fonte: towardsdatascience.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *