245 lines
19 KiB
Markdown
245 lines
19 KiB
Markdown
![[Pasted image 20241030133828.png]]
|
||
|
||
Nel riconoscimento facciale 2D abbiamo principalmente due problematiche da
|
||
risolvere:
|
||
- **Costruzione di feature discriminative e rappresentative**
|
||
- difficile avere una separazione lineare tra classi
|
||
- in certi casi dobbiamo combinare classificatori lineari (AdaBoost) o usare classificatori non lineari (molto più complesso)
|
||
- **Costruzione di un classificatore che possa generalizzare anche su oggetti mai visti nel training**
|
||
|
||
**Le facce possono essere rappresentate nell'image space:**
|
||
In questo caso quindi ci troviamo a rappresentare le facce all'interno di immagini digitali, che vengono rappresentate da matrici a due dimensioni (w × h) oppure vettori unidimensionali (d = w × h). L’alta dimensionalità dei dati (es.: immagine 100 × 100 ha dimensione 10000) ci porta subito a un primo problema, ovvero il “Curse of dimensionality”: quando la dimensionalità aumenta, il volume dello spazio aumenta così velocemente che i dati diventano sparsi/radi, rendendo difficile la classificazione.
|
||
La sparsità dei dati, nel momento in cui vengono utilizzati strumenti statistici
|
||
come ad esempio i modelli di machine learning, diminuisce drasticamente la capacità predittiva di questi in quanto si hanno bisogno di tanti più esempi per generalizzarne le regole predittive.
|
||
> [!PDF|yellow] [[LEZIONE6_Face recognition2D.pdf#page=7&selection=6,0,6,17&color=yellow|LEZIONE6_Face recognition2D, p.7]]
|
||
> > Some consequences
|
||
>
|
||
> leggi le conseguenze
|
||
|
||
**Un'alternativa è rappresentare un'immagine nel feature space:**
|
||
- Gabor filters
|
||
- discrete cosine transform (DCT)
|
||
- local binary pattern (LBP) operator
|
||
- fractal encoding
|
||
|
||
#### PCA
|
||
possibile soluzione al curse of dimensionality: PCA.
|
||
p.s. per una descrizione molto migliore di PCA guardate gli appunti di FDS. Poi tornate qui per Eigenfaces ;>
|
||
|
||
Metodo statistico che consente di ridurre l'alta dimensionalità di uno spazio mappando i dati in un altro spazio con dimensionalità decisamente più piccola minimizzando la perdita di informazioni.
|
||
Vengono individuati dei nuovi assi, ortogonali tra loro, su cui proiettare i dati che però ne **massimizzano la varianza**. L'ortogonalità di questi ci permette di escludere componenti correlate tra loro che risultano quindi ridondanti.
|
||
Nello spazio delle immagini, i principali componenti sono ortogonali quando sono gli *autovettori della matrice di covarianza*.
|
||
|
||
L'obiettivo è di eliminare features con varianza molto bassa, che quindi sono comuni tra tutti i sample e poco utili a discriminare classi.
|
||
|
||
Calcoliamo l'optimal k
|
||
Dato un training set TS di m sample di n dimensioni, calcoliamo
|
||
- il vettore medio $\hat{x}$ del training set $$\hat{x}=\frac{1}{m}\sum_{i=1}^{m}x_{i}$$
|
||
- matrice di covarianza C $$C=\frac{1}{m}\sum_{i=1}^m(x_{i}-\hat{x})(x_{i}-\hat{x})^T$$
|
||
- la dimensione di C è (n x n)
|
||
- il nuovo spazio k-dimensionale è dato dalla matrice di proiezione dove le colonne sono i k autovettori di C, corrispondenti ai k autovalori di C. Plottando gli autovalori possiamo ottenere la varianza lungo gli autovettori.
|
||
|
||
> [!PDF|red] [[LEZIONE6_Face recognition2D.pdf#page=14&selection=0,0,2,10&color=red|LEZIONE6_Face recognition2D, p.14]]
|
||
> > PCA and Eigenfaces
|
||
>
|
||
> esempio
|
||
|
||
![[Pasted image 20241030142613.png]]
|
||
da questo otteniamo l'elemento medio:
|
||
![[Pasted image 20241030142635.png]]
|
||
|
||
problema: bisogna avere tutte le facce ben centrate!!
|
||
|
||
![[Pasted image 20241030142717.png]]
|
||
autovettori (completamente diverse da quelle di partenza se ci facciamo caso)
|
||
dobbiamo estrarre quelle
|
||
|
||
Proiezione: eseguita moltiplicando la matrice di proiezione trasposta $𝜑_{k}^T$ per il vettore originale.
|
||
![[Pasted image 20241030142934.png]]
|
||
![[Pasted image 20241030143149.png]]
|
||
|
||
##### Problemi di PCA
|
||
- mancanza di potere discriminativo
|
||
- la separazione degli autovettori dipende anche dalle differenze intra-classe
|
||
- ma il sistema è unsupervised learning
|
||
- in in presenza di variazioni PIE, il modello potrebbe usare quelle come componenti facciali e non essere quindi in grado di separare correttamente le classi
|
||
|
||
Possibile soluzione: Fisherfaces, un'applicazione di FLD (Fisher's linear discriminant), spesso menzionato nel contesto del Linear Discriminant Analysis (LDA).
|
||
|
||
### LDA
|
||
Alcuni dei problemi di PCA possono essere dati dal fatto che lavoriamo su dati in una maniera unsupervised (non supervisionata), ovvero senza tenere in considerazione le classi dei vari sample.
|
||
Una soluzione supervised è proposta da LDA, ovvero un metodo simile a PCA ma che minimizza la distanza intra-classe e cerca di massimizzare invece la distanza tra classi.
|
||
|
||
Nell'immagine sotto la riduzione è da 2 a 1 dimensioni. In alcuni casi tipo questo non basta ridurre da due a un asse, gli assi sono ruotati per massimizzare la separazione tra classi. L'importante è che le coordinate rimangano ortogonali tra loro
|
||
![[Pasted image 20241030144246.png]]
|
||
the best subspace is better cause we are able to separate class among the 1D axis. As we can see, in the worst one, we are definitely not able to.
|
||
|
||
##### Possibile approccio
|
||
- partiamo, come nel PCA, da un set di m sample di n dimensioni.
|
||
- a differenza del PCA, splittiamo il set in base ai label che rappresentano le classi $PTS=\{P_{1},P_{2},{_{3},\dots,P_{s}}\}$, dove $P_{i}$ è una classe di cardinalità $m_{i}$
|
||
- cerchiamo di ottenere uno scalare $y$ proiettando il sample $x$ su una linea, in modo che $y=w^Tx$
|
||
- chiaramente x è un punto nell'immagine 2D
|
||
- y è il punto proiettato invece nel nuovo spazio 1D
|
||
|
||
Consideriamo due classi $P_1$ e $P_{2}$, rispettivamente con $m_{1}$ e $m_{2}$ vettori ciascuna
|
||
- consideriamo i vettori medi di ogni classe nei due spazi: $$\mu_{i}=\frac{1}{m_{i}}\sum_{j=1}^{m_{i}}x_{j}$$
|
||
- nel nuovo spazio si avrà (la tilde indica che è nel nuovo spazio) $$\tilde{}\mu_{i}=\frac{1}{m_{i}}\sum_{j=1}^{m_{i}}y_{j}=\frac{1}{m_{i}}\sum_{j=1}^{m_{i}}w^Tx_{j}=w^T\mu_{i}$$
|
||
- possiamo scegliere la distanza dai vettori medi proiettati (quindi nel nuovo spazio) come una funzione che chiaramente vogliamo cercare di massimizzare $$J(w)=|\tilde{\mu_{1}}-\tilde{\mu_{2}}|=|w^T(\mu_{1}-\mu_{2})|$$
|
||
![[Pasted image 20241031085606.png]]
|
||
in questo caso però notiamo come in un asse abbiamo un'ottima separabilità tra classi, nell'altro abbiamo una distanza maggiore tra i due vettori medi.
|
||
E mo come cazzo famo? Proviamo a cercare un metodo migliore
|
||
|
||
##### Scattering matrices
|
||
Dobbiamo prendere in considerazione lo spread tra le classi.
|
||
Dobbiamo massimizzare il rapporto tra la varianza tra classi e la varianza della singola classe
|
||
- **varianza della singola classe**
|
||
- indica come i vettori sono distribuiti/dispersi rispetto al centro della stessa classe
|
||
- **varianza tra classi**
|
||
- indica come i centri sono distribuiti rispetto al centro di tutto (ok si potrebbe spiegare meglio ma so le 9:00
|
||
|
||
##### Approccio
|
||
- partiamo, come nel PCA, da un set di m sample di n dimensioni.
|
||
- a differenza del PCA, splittiamo il set in base ai label che rappresentano le classi $PTS=\{P_{1},P_{2},{_{3},\dots,P_{s}}\}$, dove $P_{i}$ è una classe di cardinalità $m_{i}$
|
||
- per ogni classe $P_{i}$ calcoliamo il vettore medio e la "media dei medi"$$\mu_{i}=\frac{1}{m_{i}}\sum_{j=1}^{m_{i}}x_{j}$$$$\mu_{TS}=\frac{1}{m}\sum_{i=1}^{S}m_{i}\mu_{i}$$
|
||
- calcoliamo la matrice di covarianza per la classe ${P_{i}}$ $$C_{i}=\frac{1}{m_{i}}\sum_{j=1}^{m_{i}}(x_{j}-\mu_{i})(x_{j}-\mu_{i})^T$$
|
||
- ora possiamo calcolare scatter matrix whithin-class (della stessa classe) $$S_{W}=\sum_{i=1}^Sm_{i}C_{i}$$
|
||
- scatter matrix tra classi $$S_{B}=\sum_{i=1}^Sm_{i}(\mu_{i}-\mu_{TS})(\mu_{i}-\mu_{TS})^T$$per due classi è anche definita come $$(\mu_{1}-\mu_{2})(\mu_{1}-\mu_{2})^T$$
|
||
- le stesse definizioni sono valide anche nel nuovo spazio con $\tilde{S_{W}}$ e $\tilde{S_{B}}$ con $y=w^Tx$ e la dispersione (scatter) della classe proiettata $P_{i}$ è definito come $$\tilde{s_{i}}^2=\sum_{y \in P_{i}}(y-\tilde{\mu_{i}})^2$$ la somma di tutti gli $\tilde{s_{i}}^2$ (di tutte le classi) è la within-class scatter (dispersione tra classi)
|
||
|
||
- adesso vogliamo massimizzare la differenza tra i vettori medi, normalizzati secondo una misura della dispersione della singola classe (within-class scatter)
|
||
- con due classi, è definita come la funzione lineare $w^Tx$ che massimizza la funzione $$J(w)=\frac{{|\tilde{\mu_{1}}-\tilde{\mu_{2}}|^2}}{\tilde{s_{1}}²+\tilde{s_{2}}^2}$$
|
||
- cerchiamo una proiezione dove sample della stessa classe sono proiettati molto vicini tra loro, ma con i valori medi delle classi il più possibile lontani tra loro![[Pasted image 20241031091853.png]]
|
||
|
||
e poi si calcolano autovettori e autovalori sulla matrice $(S_{W})^{-1}S_{B}$, e si prosegue come PCA.
|
||
|
||
### Feature spaces
|
||
- possiamo estrarre feature applicando filtri o trasformazioni alle immagini
|
||
- possiamo usare uno dei metodi appena descritti se le feature estratte hanno una dimensionalità alta
|
||
Quali sono le migliori feature da estrarre? Vediamo alcuni operatori
|
||
|
||
##### Bubbles
|
||
- un osservatore umano può subito ipotizzare il genere, l'identità, l'età e l'espressione guardando una faccia
|
||
- l'esperimento consiste nel mostrare l'immagine con sopra un pattern a bolle e vedere se l'osservatore umano e un sistema biometrico riescono a classificarlo bene![[Pasted image 20241031100207.png]]
|
||
- alla fine dell'esperimento riusciamo a capire quali sono gli elementi (le features quindi) della faccia che vengono prese in considerazione da un essere umano o che un sistema biometrico utilizza per classificare
|
||
|
||
#### Wavelet
|
||
provides a time-frequency representation of the signal. Fornisce tempo e frequenza contemporaneamente.
|
||
![[Pasted image 20241031102321.png]]
|
||
|
||
#### Gabor filters
|
||
È un filtro lineare utilizzato in applicazioni di edge detection, analisi di texture e estrazione di feature, e si pensa che sia simile al sistema percettivo visivo di noi umani. Un Gabor filter 2D non è altro che un kernel Gaussiano modulato da un’onda piana sinusoidale.
|
||
> [!PDF|yellow] [[LEZIONE6_Face recognition2D.pdf#page=43&selection=0,2,11,7&color=yellow|LEZIONE6_Face recognition2D, p.43]]
|
||
> > An example of filters: Gabor filters
|
||
>
|
||
> guarda dalle slide
|
||
|
||
![[Pasted image 20241031102640.png]]
|
||
|
||
Un feature vector viene ricavato eseguendo varie convoluzioni con un insieme Gabor filter (Gabor filter bank) con diversi orientamenti e scale (nell'immagine sull'asse x troviamo gli orientamenti e su y le scale)
|
||
|
||
Otteniamo quindi diversi filtri andando a cambiare i parametri:
|
||
- f: frequenza della sinusoide, controlla lo spessore delle strisce
|
||
- θ: orientamento, controlla la rotazione della striscia ed è espresso come un angolo
|
||
- $\sigma_{x}$ e $\sigma_{y}$: Varianza della gaussiana.
|
||
|
||
Questa procedura, su immagini molto grandi, porta ad un’alta dimensionalità ed è computazionalmente complessa; possibili soluzioni sono:
|
||
- Applicare il filtro su un subset di pixel, come ad esempio una griglia =⇒ dimensionalità ridotta, ma possibile perdita di informazioni salienti (dovuta a possibili rotazioni ad esempio)
|
||
Spiegato più semplicemente: faccio la convoluzione ma saltando un po' di pixel ogni volta (lo stride per chi conosce le CNN)
|
||
- Griglia fissa
|
||
- possiamo perdere punti importanti
|
||
- Griglia definita a mano in modo che i vertici sono vicini alle feature importanti, come gli occhi
|
||
|
||
- Applico il filtro su tutti i pixel, ma poi seleziono solo i punti con picchi di valori (con maggiore informazione) $\to$ problemi di allineamento.
|
||
|
||
#### EBGM Elastic Bunch Graph Matching
|
||
Questo metodo fa uso di grafi, nello specifico abbiamo per ogni soggetto una collezione di grafi (per questo il nome “bunch”), uno per ogni posa, dove:
|
||
- gli archi (edges) sono labellati (pesati) con la distanza tra i nodi
|
||
- i nodi contengono un insieme di risultati di diversi gabor filter (in genere 5 differenti frequenze e 8 diversi orientamenti), conservati in questa struttura chiamata “Jet”, e sono posizionati in punti importanti come ad esempio naso, occhi e bocca
|
||
|
||
In questo modo considerando la posizione dei nodi e le label degli archi, il grafo modella la geometria del volto.
|
||
|
||
Face Bunch Graph: può rappresentare volti
|
||
label dei nodi: insiemi di jet (detti bunches) dei volti campione usati per costruire il FBG
|
||
label degli archi: distanze come detto prima
|
||
|
||
un volto è rappresentato come una combinazione di jet. Per ogni bunch si sceglie il jet più appropriato, una faccia nuova viene quindi rappresentata con i jet delle facce nel campione che più gli assomigliano, prendendo ad es. bocca da faccia 1, naso da faccia 2...
|
||
|
||
(un FBG fatto con 6 volti campione e 9 punti cardine può rappresentare fino a 6⁹ volti diversi :o)
|
||
|
||
![[Pasted image 20241031104206.png]]
|
||
![[Pasted image 20241031104526.png]]
|
||
|
||
oggi non lo usa nessuno.
|
||
|
||
#### LBP Local Binary Pattern
|
||
Lavora sempre su un kernel, ma il kernel è "trasparente". Lavora pixel per pixel e ci aiuta ad estrarre informazioni riguardo le texture all'interno di un'immagine (utile anche per antispoofing). Nella sua prima versione va a considerare una griglia 3x3 dove a ognuno dei quali viene assegnato un valore binario: se il suo valore era maggiore del pixel centrale viene assegnato 1, altrimenti 0. Effettuando questa operazione con un ordine di processo dei vicini (parto dal vicino in alto a sinistra ad es.) si ottiene una stringa binaria, il cui valore convertito in decimale viene assegnato al pixel centrale. Sarà il valore del pixel nella nuova immagine.
|
||
È tipo una convoluzione ma molto più semplice.
|
||
|
||
![[Pasted image 20241106133301.png]]
|
||
|
||
Possiamo ottenere l'istogramma di questi valori e considerarlo come una feature.
|
||
Inoltre possiamo ottenere una misura di contrasto: (media valori dei pixel con valore maggiore del centrale) - (media valori dei pixel con valore minore del centrale)
|
||
|
||
![[Pasted image 20241106133935.png]]
|
||
Ottengo un'immagine LBP (grayscale) e un istogramma LBP.
|
||
L'immagine può banalmente poi essere usata come input di una deep network.
|
||
Si può estendere per RGB? Beh sì basta che ripeto il processo per ogni immagine e faccio la media dei 3 risultati, ma ci sono strategie migliori.
|
||
###### Versione migliorata
|
||
In questa versione scelgo io il numero di pixel vicini (P) e il loro raggio di distanza (R), il valore di un pixel $p_{c}$ si calcolerà quindi come:
|
||
$$LBP_{R,P}=\sum_{i=0}^{P-1}sign(p_{i}-p_{c})2^P$$
|
||
sign torna 1 se >= 0, altrimenti 0.
|
||
|
||
![[Pasted image 20241106134544.png]]
|
||
p.s. la rappresentazione come immagine LBP è possibile solo se P=8.
|
||
|
||
Un pattern viene detto **uniforme** se nella stringa binaria contiene al massimo due transizioni $0 \to 1$, $1 \to 0$. Questi rappresentano le informazioni essenziali e ci consentono di ridurre notevolmente il numero di punti da considerare riducendo la dimensionalità, dato che sono solo $P(P-1)+2$ su un totale di $P^2$ possibili pattern.
|
||
![[Pasted image 20241106135449.png]]
|
||
|
||
Da questo esempio si dovrebbe capire come le informazioni importanti alla fine siano tutte comprese nei pattern uniformi: ![[Pasted image 20241106135815.png]]
|
||
La seconda immagine contiene i pixel associati a pattern **uniformi**, la terza pixel associati a pattern **non uniformi**.
|
||
|
||
Come possiamo ottenere un vettore di features?
|
||
- l'immagine viene suddivisa in sotto-finestre, ottenendo una griglia $k \times k$
|
||
- per ogni sotto-finestra calcoliamo un istogramma (ad ogni bin corrisponde un pattern)
|
||
- il vettore finale viene costruito concatenando i $k^2$ istogrammi.
|
||
![[Pasted image 20241106140102.png]]
|
||
|
||
![[Pasted image 20241106140241.png]]
|
||
Le rotazioni modificano l'LBP.
|
||
|
||
### Classificazioni di sistemi di riconoscimento facciale
|
||
- **Metodi basati sull'apparenza della faccia (global/holistic appearance methods):** PCA, LDA, alcune reti neurali. Utilizzano l'immagine per intero invece di concentrarsi solo su alcune regioni, non perdendo informazioni da subito. Svantaggi: danno la stessa importanza ad ogni pixel, necessitano di alta correlazione tra training e test set, non performano bene su grandi variazioni PIE.
|
||
- **Metodi basati su feature locali:** EBGM, LBP. Sono robusti a varianze di posizione in quanto vengono prima individuati i punti da cui estrarre le feature, e inoltre sono computazionalmente veloci. Come principale svantaggio hanno la scelta a priori dei punti da cui estrarre le feature, se non sono molto discriminativi le performance saranno pessime.
|
||
- **Sistemi basati su grafi:** a ogni faccia è associato un grafo, dove ogni nodo corrisponde a punti discriminativi della faccia. Ottimi dal punto di vista di variazioni di posizione e illuminazione. Train e test molto lunghi.
|
||
- **Sistemi basati su immagini termografiche o a infrarossi:** ottimi per quanto riguarda variazioni di illuminazione, però richiedono attrezzatura adeguata e la temperatura misurata varia in base allo stato del soggetto. Molto sensibili ai movimenti.
|
||
- **Reti neurali:** mirano a simulare il modo in cui funzionano i neuroni del cervello. Ogni neurone è rappresentato da una funzione matematica, approccio ideale: usare un neurone per pixel ma richiede tantissimi neuroni. Quindi spesso si usa una rete per estrarre feature dall'immagine / comprimere l'immagine e poi una rete per la recognition effettiva. Sono molto robuste ma richiedono un training set molto grande. Altri possibili problemi: overfitting (the network has the same dimension of the input), overtraining (non generalizza più), diventano inefficienti all'aumentare del numero di soggetti nel database.
|
||
|
||
###### Overfitting
|
||
Quando la rete ha troppi parametri rispetto alla dimensione dell'input.
|
||
|
||
###### Overtraining
|
||
Il sistema perde la capacità di generalizzare.
|
||
|
||
### Approcci Deep Learning: DeepFace di Facebook
|
||
Include una fase di allineamento.
|
||
- l'obiettivo della fase di allineamento è generale una faccia frontale a partire dall'immagine che può contenere facce con posizioni o angoli differenti. Il metodo proposto si basa dei "fiducial point" (punti estratti dalla faccia) per estrarre la fraccia frontale
|
||
- generazione della faccia 2D, che non è altro che la faccia croppata dall'immagine di partenza
|
||
- applicazione dei 67 fiducial point sull'immagine. Generazione di un modello 3D
|
||
- frontalizzazione della faccia
|
||
|
||
![[Pasted image 20241106142503.png]]![[Pasted image 20241106142523.png]]![[Pasted image 20241106142539.png]]
|
||
|
||
Le facce "frontalizzate" saranno l'input della rete neurale:
|
||
![[Pasted image 20241106142610.png]]
|
||
|
||
### Approcci Deep Learning: FaceNet di Google
|
||
Raggiunse il miglior risultato sul dataset Labeled Faces in the Wild e Youtube Face Database.
|
||
Fa uso di deep architectures come **ZF-Net** e **Inception Network**. Usa poi un metodo chiamato **triplet loss** come funzione loss per il training.
|
||
|
||
![[Pasted image 20241106143837.png]]
|
||
- normalizzazione least squares: riscala i vettori in modo che la loro norma L2 sia 1 (ogni vettore è diviso per la norma L2)
|
||
- la norma L2 calcola la distanza delle coordinate del vettore dall'origine dello spazio vettoriale, anche detta norma euclidea.
|
||
|
||
##### Triplet loss
|
||
ha l'obiettivo di rendere piccola la distanza al quadrato (squared distance) tra gli embedding di due immagini corrispondenti alla stessa identità, indipendentemente dalla posa o altre condizioni, e di rendere grande la distanza tra immagini corrispondenti a identità diverse.
|
||
![[Pasted image 20241106144314.png]]
|