Il riconoscimento facciale è uno dei campi che impiega l’apprendimento automatico ed è ampiamente utilizzato in molti settori, dall’etichettatura delle foto sui social media e l’abbinamento di persone con le stesse caratteristiche facciali sui siti di incontri, per rintracciare i criminali e proteggere i confini, per tenere a bada i grandi giocatori nei casinò.

Trovo affascinante che possiamo simulare il processo di riconoscimento facciale con un significativo grado di precisione, mentre allo stesso tempo ci sono persone che soffrono di prosopagnosia, o “cecità facciale”, che non sono così fortunate. Un autore di un articolo di Cracked in cui mi sono imbattuto un po’ di tempo fa descrive questa esperienza come vedere una pila di LEGO in cui, non appena si distoglie lo sguardo, non si riesce più a descrivere in alcun dettaglio sostanziale il colore e la forma di ogni pezzo o come erano posizionati. Mi sono chiesto se questo disturbo cognitivo abbia qualcosa a che fare con l’allocazione della memoria. Fortunatamente, la memoria è qualcosa che i computer hanno in abbondanza e non abbiamo nemmeno iniziato a scalfire la superficie dell’intera serie di capacità che l’informatica quantistica presenterà.

Ma torniamo alle facce proprie.

I dati visivi in un’immagine possono essere mappati in un vettore dove ogni voce rappresenta la luminosità del pixel corrispondente. Prendendo un insieme di immagini, una matrice può essere costruita con ogni riga corrispondente a un vettore specifico dell’immagine. Idealmente, le immagini sono prima normalizzate in modo da allineare le caratteristiche di base come occhi, naso e bocca per aumentare la precisione e ridurre il rumore. Gli autovettori sono quindi gli autovettori che derivano dalla matrice di covarianza di questa matrice di dati facciali analizzati.

Il set di dati dei volti che abbiamo usato è stato gentilmente fornito dai laboratori AT&T di Cambridge e consisteva di 40 volti individuali, 10 immagini di ciascuno con diverse espressioni facciali e posizioni della testa.

Le seguenti librerie e moduli Python sono stati utilizzati in questo esercizio:

from sklearn.preprocessing import normalize
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from scipy.misc import imread
from itertools import chain
import numpy as np
import scipy as sp
import glob
  • normalize funzione scala ogni singolo vettore campione per avere norma unitaria.
  • PCA o Principle Component Analysis, è un processo di riduzione della dimensionalità lineare utilizzando la Singular Value Decomposition dei dati per proiettarli in uno spazio dimensionale inferiore. In altre parole, è il processo di trovare la struttura sottostante dei dati o le direzioni in cui c’è la maggior varianza.
  • matplotlib.pyplot è la familiare funzione di plottaggio.
  • imread è usata per leggere un’immagine da un file come un array.
  • chain è un iteratore che passa attraverso la lista restituendo singoli elementi da ogni iterabile.
  • numpy è il pacchetto Python fondamentale per il calcolo scientifico.
  • scipy è un altro pacchetto per il calcolo scientifico e tecnico, simile a numpy ma che contiene versioni più complete dei moduli di algebra lineare, così come molti altri algoritmi numerici.
  • glob modulo trova tutti i nomi dei percorsi che corrispondono a un modello specificato.

Il primo passo è estrarre tutti i nomi dei file dall’archivio zippato. Poi viene creata una matrice dipanando le matrici delle immagini in vettori usando il comando chain e impilandole. Questo crea una matrice 400×10304 con ogni riga contenente tutte le informazioni su una specifica immagine 112×92.

filenames = m = for i in range(400)]for i in range(400):
m = list(chain.from_iterable(imread(filenames)))
m = np.matrix(m)

Poi, la matrice viene normalizzata e viene applicata la PCA. Qui abbiamo ridotto il nostro spazio vettoriale a sole 40 dimensioni su 10304:

model = PCA(n_components=40)
pts = normalize(m)
model.fit(pts)
pts2 = model.transform(pts)

Infine, gli autovettori, contenuti in model.components_, possono essere visualizzati:

fig, ax = plt.subplots(1,40)for i in range(40):
ord = model.components_
img = ord.reshape(112,92)
ax.imshow(img,cmap='gray')

Ed ecco fatto. Un mucchio di facce raccapriccianti.

Quello che abbiamo essenzialmente fatto è creare un insieme di basi ortogonali in cui ogni autofaccia evidenzia un certo tipo di caratteristica, e da cui le facce che abbiamo usato possono essere ricostruite attraverso diverse combinazioni e proporzioni di autovettori.

faces_pca = PCA(n_components=40)
faces_pca.fit(m)
components = faces_pca.transform(m)
projected = faces_pca.inverse_transform(components)fig, axes = plt.subplots(40,10,figsize=(20,80))
for i, ax in enumerate(axes.flat):
ax.imshow(projected.reshape(112,92),cmap="gray")

Perché abbiamo compresso così tanto il nostro spazio vettoriale (e non abbiamo allineato i volti per cominciare), molti dettagli sono andati persi, ma i volti sono rimasti in qualche modo riconoscibili.

E così, l’obiettivo per il problema della computer vision del riconoscimento dei volti umani è quello di creare il numero minimo di facce autoctone che possano rappresentare adeguatamente l’intero set di allenamento. Se l’insieme di addestramento è sufficientemente vario, l’insieme di autofatti risultante dovrebbe essere in grado di rappresentare tutti i volti. E, sebbene negli ultimi anni siano stati fatti progressi significativi negli algoritmi di riconoscimento facciale, c’è ancora molta strada da fare e molti miglioramenti da apportare.

D’altra parte, e come sempre, ci sono alcuni pericoli associati alle capacità in continua espansione di un software che è in grado di riconoscere, simulare, e quindi potenzialmente ingannare e manipolare un individuo ignaro, e dobbiamo prendere le precauzioni adeguate per assicurarci che sia usato in modo appropriato.

E lascerò questo qui come un caso esemplare e per il vostro intrattenimento.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.