Face Recognition with Eigenfaces

Kasvojentunnistus on kaikkialla läsnä tieteiskirjallisuudessa: päähenkilö katsoo kameraan, ja kamera skannaa hänen kasvonsa henkilön tunnistamiseksi. Muodollisemmin voimme muotoilla kasvojentunnistuksen luokittelutehtäväksi, jossa syötteet ovat kuvia ja tuotokset ihmisten nimiä. Keskustelemme nyt kasvontunnistuksessa käytettävästä suositusta tekniikasta nimeltä eigenfaces. Ominaisten kasvojen ytimessä on valvomaton dimensioiden pienentämistekniikka, jota kutsutaan pääkomponenttianalyysiksi (PCA), ja näemme, miten voimme soveltaa tätä yleistä tekniikkaa kasvontunnistustehtävään. Lataa koko koodi täältä.

Älä jää paitsi! Tarjous päättyy
  • Pääset kaikille yli 200 kurssille
  • Uusia kursseja lisätään kuukausittain
  • Peruuta milloin tahansa
  • Päättötodistukset

Kasvojen tunnistaminen

Ennen kuin keskustelemme pääkomponenttianalyysistä, meidän on ensin määriteltävä ongelma. Kasvontunnistus on haaste luokitella, kenen kasvot ovat syötetyssä kuvassa. Tämä on eri asia kuin kasvojen tunnistaminen, jossa haasteena on määrittää, onko tulokuvassa kasvoja. Kasvontunnistuksessa tarvitsemme olemassa olevan kasvotietokannan. Kun meille annetaan uusi kuva kasvoista, meidän on ilmoitettava henkilön nimi.

Naiivi tapa toteuttaa tämä on ottaa uusi kuva, litistää se vektoriksi ja laskea sen ja kaikkien muiden tietokannassamme olevien litistettyjen kuvien välinen euklidinen etäisyys.

Tässä lähestymistavassa on useita haittoja. Ensinnäkin, jos meillä on suuri tietokanta kasvoja, tämän vertailun tekeminen jokaiselle kasvolle vie aikaa! Kuvittele, että olemme rakentamassa kasvontunnistusjärjestelmää reaaliaikaiseen käyttöön! Mitä suurempi tietokantamme on, sitä hitaampi algoritmimme on. Mutta useammat kasvot tuottavat myös parempia tuloksia! Haluamme järjestelmän, joka on sekä nopea että tarkka. Tähän käytämme neuroverkkoa! Voimme kouluttaa verkkoamme aineistollamme ja käyttää sitä kasvojentunnistustehtävään.

Neuraaliverkon suorassa käytössä on yksi ongelma: kuvat voivat olla suuria! Jos meillä olisi yksi m\times n

kuva, meidän täytyisi litistää se yhdeksim\dot n\times 1vektoriksi syötettäväksi neuroverkkoomme syötteenä. Suurten kuvakokojen kohdalla tämä saattaa haitata nopeutta! Tämä liittyy toiseen ongelmaan, joka liittyy kuvien käyttämiseen sellaisenaan naiivissa lähestymistavassa: ne ovat korkea-ulotteisia! (Kuvam\times non todellisuudessam\dot n\times 1-vektori.) Uudessa syötteessä saattaa olla paljon kohinaa, ja jokaisen pikselin vertaaminen matriisisubtraktion ja euklidisen etäisyyden avulla saattaa johtaa suureen virheeseen ja virheellisiin luokituksiin!

Näiden ongelmien vuoksi emme käytä naiivia menetelmää. Sen sijaan haluaisimme ottaa korkea-ulotteiset kuvamme ja kiehauttaa ne pienempään ulottuvuuteen säilyttäen samalla kuvan olemuksen tai tärkeät osat.

Dimensioiden pienentäminen

Edellisessä kappaleessa perusteltiin syymme käyttää dimensioiden pienentämistekniikkaa. Dimensioiden pienentäminen on eräänlaista valvomatonta oppimista, jossa haluamme ottaa korkeampiulotteista dataa, kuten kuvia, ja esittää ne alempiulotteisessa avaruudessa. Käytetään esimerkkinä seuraavaa kuvaa.

Nämä kuvaajat esittävät samaa dataa, paitsi että alin kuvaaja nollakeskittää sen. Huomaa, että dataan ei liity mitään merkintöjä, koska kyseessä on valvomaton oppiminen! Yksinkertaisessa tapauksessamme dimensioiden vähentäminen vähentää nämä tiedot 2D-tasosta 1D-viivaksi. Jos meillä olisi 3D-dataa, voisimme pelkistää sen 2D-tasoksi tai jopa 1D-viivaksi.

Kaikki dimensioiden pelkistämistekniikat pyrkivät löytämään jonkin hypertason, korkeampiulotteisemman viivan, johon pisteet voidaan projisoida. Voimme kuvitella projisoinnin niin, että otamme taskulampun kohtisuoraan siihen hypertasoon, johon projisoimme, ja piirrämme, mihin varjot osuvat tällä hypertasolla. Jos esimerkiksi haluaisimme projisoida pisteet x-akselille, kuvittelemme, että jokainen piste on pallo ja taskulamppu osoittaa suoraan alas tai ylös (kohtisuoraan x-akselia vastaan), jolloin pisteiden varjot osuisivat x-akselille. Tämä on projektio. Emme huolehdi tämän takana olevasta tarkasta matematiikasta, koska scikit-learn voi soveltaa tätä projektiota puolestamme.

Yksinkertaisessa 2D-tapauksessamme haluamme löytää viivan, johon projisoimme pisteemme. Kun projisoimme pisteet, meillä on dataa 1D:ssä 2D:n sijaan! Vastaavasti, jos meillä olisi 3D-dataa, haluaisimme löytää tason, johon voimme projisoida pisteet alaspäin, jotta voimme vähentää datamme ulottuvuutta 3D:stä 2D:ksi. Erilaisissa dimensioiden pienentämistavoissa on kyse sen selvittämisestä, mikä näistä hypertasoista valitaan: niitä on ääretön määrä!

Pääkomponenttianalyysi

Eräs dimensioiden pienentämistekniikka on nimeltään pääkomponenttianalyysi (principal component analysis, PCA). PCA:n ideana on, että halutaan valita sellainen hypertaso, että kun kaikki pisteet projisoidaan siihen, ne jakautuvat maksimaalisesti. Toisin sanoen haluamme akselin, jolla on suurin varianssi! Tarkastellaan edellä esitettyä esimerkkikaaviota. Mahdollinen akseli on x-akseli tai y-akseli, mutta kummassakaan tapauksessa se ei ole paras akseli. Jos kuitenkin valitsemme viivan, joka leikkaa datamme diagonaalisesti, se on akseli, jolla datan hajonta olisi suurin!

Pidempi sininen akseli on oikea akseli! Jos projisoisimme pisteemme tälle akselille, ne olisivat maksimaalisesti hajallaan! Mutta miten saamme selville tämän akselin? Voimme lainata lineaarialgebrasta termiä nimeltä omavektorit! Tästä ominaisvektorit saavat nimensä! Pohjimmiltaan laskemme tietojemme kovarianssimatriisin ja tarkastelemme kyseisen kovarianssimatriisin suurimpia ominaisvektoreita. Ne ovat pääakseleita ja akseleita, joihin projisoimme tietomme ulottuvuuksien vähentämiseksi. Tämän lähestymistavan avulla voimme ottaa korkea-ulotteisen datan ja pienentää sen pienempään ulottuvuuteen valitsemalla kovarianssimatriisin suurimmat ominaissuuntaiset vektorit ja projisoimalla ne näihin ominaissuuntaisiin vektoreihin.

Koska laskemme maksimihajonnan akselit, säilytämme datamme tärkeimmät näkökohdat. Luokittelijamme on helpompi erottaa kasvot toisistaan, kun datamme on hajautettu eikä niputettu yhteen.

(On olemassa muitakin ulottuvuustekniikoita, kuten lineaarinen diskriminaatioanalyysi, jotka käyttävät valvottua oppimista ja joita käytetään myös kasvojentunnistuksessa, mutta PCA toimii todella hyvin!)

Miten tämä liittyy haasteeseemme kasvojentunnistuksessa? Voimme käsitteellistää m\times n

kuvamme pisteinäm\dot n-ulotteisessa avaruudessa. Sitten voimme käyttää PCA:ta pienentääksemme avaruudenm\dot njoksikin paljon pienemmäksi. Tämä auttaa nopeuttamaan laskutoimituksiamme ja on kestävää kohinaa ja vaihtelua vastaan.

Lisätietoa kasvojen havaitsemisesta

Tähän asti olemme olettaneet, että syötekuvana on vain kasvojen kuva, mutta käytännössä meidän ei pitäisi vaatia, että kameran kuvissa on täydellisesti keskitetyt kasvot. Tämän vuoksi suoritamme valmiiksi kasvontunnistusalgoritmin, kuten kasvojen perusteella koulutetun kaskadiluokittimen, selvittääksemme, missä osassa tulokuvasta on kasvot. Kun meillä on tämä rajaava laatikko, voimme helposti leikata kyseisen osan tulokuvasta ja käyttää ominaistunnisteita kyseiseen osaan. (Yleensä leikkaus tasoitetaan ja tehdään affiinimuunnos kasvojen vääristymisen poistamiseksi, jos kasvot näkyvät vinossa). Meidän tarkoituksiamme varten oletamme, että meillä on jo kuvia kasvoista.

Eigenfaces Koodi

Nyt kun olemme keskustelleet PCA:sta ja eigenfacesista, koodataanpa kasvontunnistusalgoritmi scikit-learnin avulla! Ensin tarvitsemme datasetin. Käytämme tarkoituksiamme varten Massachusettsin yliopiston valmiiksi asennettua tietokokonaisuutta nimeltä Labeled Faces in the Wild (LFW).

Vaihda vapaasti oma tietokokonaisuutesi tilalle! Jos haluat luoda oman kasvotietoaineistosi, tarvitset useita kuvia kunkin henkilön kasvoista (eri kulmista ja eri valaistuksessa) sekä ground-truth-merkinnät. Mitä enemmän erilaisia kasvoja käytät, sitä paremmin tunnistin toimii. Helpoin tapa luoda tietokanta kasvontunnistusta varten on luoda jokaiselle henkilölle oma kansio ja laittaa kasvokuvat sinne. Varmista, että jokainen on samankokoinen, ja muuta niiden kokoa, jotta ne eivät ole suuria kuvia! Muista, että PCA pienentää kuvan dimensiota, kun projisoimme siihen avaruuteen joka tapauksessa, joten suurten, teräväpiirtoisten kuvien käyttäminen ei auta ja hidastaa algoritmiamme. Hyvä koko on ~512×512 kuhunkin kuvaan. Kaikkien kuvien tulisi olla samankokoisia, joten voit tallentaa ne yhteen numpy-määritykseen, jonka mitat ovat (num_examples, height, width) . (Oletamme, että kuvat ovat harmaasävykuvia). Käytä sitten kansioiden nimiä luokkien erottamiseen. Tätä lähestymistapaa käyttäen voit käyttää omia kuvia.

Käytämme kuitenkin LFW-tietokantaa. Onneksi scikit-learn osaa ladata tietokokonaisuutemme automaattisesti puolestamme oikeassa muodossa. Voimme kutsua funktiota lataamaan datamme. Jos dataa ei ole saatavilla levyllä, scikit-learn lataa sen automaattisesti puolestamme Massachusettsin yliopiston verkkosivuilta. pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_lfw_people
from sklearn.metrics import classification_report
from sklearn.decomposition import PCA
from sklearn.neural_network import MLPClassifier
# Lataa data
lfw_dataset = fetch_lfw_people(min_faces_per_person=100)
_, h, w = lfw_dataset.images.shape
X = lfw_dataset.data
y = lfw_dataset.target
target_names = lfw_dataset.target_names
# jaetaan harjoittelu- ja testausjoukkoon
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

Funktiomme argumentti vain karsii kaikki ihmiset, joilla ei ole vähintään 100 kasvoa, jolloin luokkien määrä vähenee. Sitten voimme poimia aineistomme ja muut aputiedot. Lopuksi jaamme tietokokonaisuutemme harjoittelu- ja testausjoukkoihin.

Nyt voimme yksinkertaisesti käyttää scikit-learnin PCA-luokkaa suorittamaan dimensionaalisuuden vähentämisen puolestamme! Meidän on valittava komponenttien määrä, eli ulostulon ulottuvuus (projisoitavien ominaisvektoreiden määrä), johon haluamme pienentää, ja voit vapaasti säätää tätä parametria yrittäessäsi saada parhaan tuloksen! Käytämme 100 komponenttia. Lisäksi valkaisemme datamme, mikä on helppo tehdä yksinkertaisella boolean-lipukkeella! (Valkaisu vain tekee tuloksena olevasta datastamme yksikkövarianssin, jonka on osoitettu tuottavan parempia tuloksia)

1
2
3
4
5
6
7

# Laske PCA
n_komponentit = 100
pca = PCA(n_komponentit=n_komponentit, whiten=True).fit(X_train)
# apply PCA transformation
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)

Voidaan soveltaa transformaatiota, jolla saamme kuvamme pienennettyä 100-ulotteiseen avaruuteen. Huomaa, että emme suorita PCA:ta koko aineistolle, vaan ainoastaan harjoitusaineistolle. Näin voimme paremmin yleistää näkymättömään dataan.

Nyt kun meillä on vähennetty ulottuvuusvektori, voimme kouluttaa neuroverkkomme!

1
2
3

# treenaa neuroverkkoa
print(”Luokittelijan sovittaminen harjoittelukokonaisuuteen”)
clf = MLPC-luokittelija(hidden_layer_sizes=(1024,), batch_size=256, verbose=True, early_stopping=True).fit(X_train_pca, y_train)

Voidaksemme nähdä, miten verkkomme harjoittelee, voimme asettaa verbose-lipun. Lisäksi käytämme varhaista pysäytystä.

Keskustellaan lyhyesti sivuhuomautuksena varhaista pysäytystä. Pohjimmiltaan optimointilaitteemme seuraa validointijoukon keskimääräistä tarkkuutta jokaisella epookilla. Jos se huomaa, että validointitarkkuutemme ei ole kasvanut merkittävästi tiettyyn määrään epookkeja, lopetamme harjoittelun. Tämä on regularisointitekniikka, joka estää mallimme ylisovittamisen!

Tarkastellaan yllä olevaa kaaviota. Huomaamme ylisovittamisen, kun validointijoukkomme tarkkuus alkaa laskea. Siinä vaiheessa lopetamme välittömästi harjoittelun, jotta estämme ylisovittamisen.

Viimeiseksi voimme tehdä ennusteen ja käyttää funktiota, jolla voimme tulostaa kokonaisen raportin kunkin luokan laadusta.

1
2

y_pred = clf.predict(X_testi_pca)
print(luokitus_raportti(y_testi, y_pred, tavoitenimet=kohdenimet))

Tässä on esimerkki luokitusraportista.

1
2
3
4
5
6
7
8
9

precision recall f1-pisteet tuki
Colin Powell 0.86 0,89 0,87 66
Donald Rumsfeld 0,85 0,61 0,71 38
George W. Bush 0,88 0,94 0,91 177
Gerhard Schröder 0,67 0,69 0.68 26
Tony Blair 0,86 0,71 0,78 35
avg / total 0,85 0,85 0,85 0,85 342

Huomaa, että tarkkuusmittaria ei ole. Tarkkuus ei ole kaikkein spesifisin metriikka aloittaa. Sen sijaan nähdään tarkkuus, recall, f1-score ja support. Tuki on yksinkertaisesti se, kuinka monta kertaa tämä perustotuusmerkki esiintyi testijoukossamme, esimerkiksi testijoukossamme oli itse asiassa 35 kuvaa Tony Blairista. F1-tulos lasketaan itse asiassa vain tarkkuus- ja recall-tuloksista. Precision ja recall ovat tarkempia mittareita kuin yksittäinen tarkkuuspistemäärä. Korkeampi arvo molemmille on parempi.

Koulutettuamme luokittelijamme voimme antaa sille muutaman kuvan luokiteltavaksi.

12
13
14
15
16
17
18
# Visualisointi
def plot_galleria(images, titles, h, w, rows=3, cols=4):
plt.figure()
for i in range(rows * cols):
plt.subplot(rows, cols, i + 1)
plt.imshow(images.reshape((h, w)), cmap=plt.cm.gray)
plt.title(titles)
plt.xticks(())
plt.yticks(())
def titles(y_pred, y_test, target_names):
for i in range(y_pred.shape):
pred_name = target_names].split(’ ’ ’)
true_name = target_names].split(’ ’)
yield ’predicted: {0}\ntrue: {1}’.format(pred_name, true_name)
prediction_titles = list(titles(y_pred, y_test, target_names))
plot_gallery(X_test, prediction_titles, h, w)

(plot_gallery- ja titles-funktiot muokattu scikit-learn-dokumentaatiosta)

Näemme verkostomme ennusteet ja pohjatodellisuusarvon kullekin kuvalle.

Toinen mielenkiintoinen asia visualisoitavaksi ovat itse eigenfacet. Muista, että PCA tuottaa omavektorit. Voimme muotoilla nuo omavektorit uudelleen kuviksi ja visualisoida ominaiskasvot.

Nämä edustavat aineistomme ”yleisiä” kasvoja. Intuitiivisesti nämä ovat vektoreita, jotka edustavat suuntia ”kasvoavaruudessa” ja joita neuroverkkomme käyttää apuna luokittelussa. Nyt kun olemme keskustelleet eigenfaces-lähestymistavasta, voit rakentaa sovelluksia, jotka käyttävät tätä kasvontunnistusalgoritmia!

Keskustelimme suositusta kasvontunnistuslähestymistavasta nimeltä eigenfaces. Eigenfacesin ydin on valvomaton dimensioiden pienentämisalgoritmi nimeltä pääkomponenttianalyysi (PCA), jota käytämme pienentämään kuvien dimensioita joksikin pienemmäksi. Nyt kun meillä on pienempi esitys kasvoistamme, käytämme luokittelijaa, joka ottaa pienemmän ulottuvuuden syötteen ja tuottaa luokkatunnisteen. Luokittelijana käytimme yksikerroksista neuroverkkoa.

Kasvojentunnistus on kiehtova esimerkki tietokonenäön ja koneoppimisen yhdistämisestä, ja monet tutkijat työskentelevät tämän haastavan ongelman parissa vielä tänäkin päivänä!

Tänä päivänä kasvontunnistukseen käytetään syviä konvolutiivisia neuroverkkoja, ja niillä on valtavat vaikutukset kehitysurien maailmaan. Kokeile sellaista tällä tietokokonaisuudella!

Vastaa

Sähköpostiosoitettasi ei julkaista.