Kasvojentunnistus on yksi koneoppimista hyödyntävistä aloista, ja sitä käytetään laajalti monilla aloilla aina valokuvien merkitsemisestä sosiaalisessa mediassa ja samoja kasvonpiirteitä omaavien ihmisten yhteensovittamisesta deittisivustoilla, rikollisten jäljittämisestä ja rajojen turvaamisesta suurten rullien pelaajien pitämiseen loitolla kasinoilla.
Minusta on kiehtovaa, että voimme simuloida kasvojentunnistusprosessia huomattavan tarkasti, kun taas samaan aikaan on ihmisiä, jotka kärsivät prosopagnosiasta eli ”kasvosokeudesta” ja jotka eivät ole yhtä onnekkaita. Erään Cracked-artikkelin kirjoittaja, johon törmäsin jokin aika sitten, kuvailee tätä kokemusta kuin näkisi kasan LEGO-palikoita, joiden kohdalla ei enää pysty kuvaamaan yksityiskohtaisesti, minkä värisiä ja muotoisia kukin pala on tai miten ne on sijoitettu. Olen miettinyt, liittyykö tämä kognitiivinen häiriö jotenkin muistin jakamiseen. Onneksi tietokoneilla on runsaasti muistia, emmekä ole vielä edes raapaisseet pintaa kaikista kvanttilaskennan tarjoamista mahdollisuuksista.
Mutta takaisin omiin näkymiin.
Kuvan visuaalista dataa voidaan kuvata vektoriksi, jossa jokainen merkintä edustaa vastaavan pikselin kirkkautta. Kun otetaan joukko kuvia, voidaan muodostaa matriisi, jonka jokainen rivi vastaa tiettyä kuvavektoria. Ihannetapauksessa kuvat normalisoidaan ensin siten, että peruspiirteet, kuten silmät, nenä ja suu, kohdistetaan toisiinsa tarkkuuden lisäämiseksi ja kohinan vähentämiseksi. Omat kasvot ovat sitten omavektoreita, jotka johdetaan tämän analysoidun kasvodatan matriisin kovarianssimatriisista.
Käyttämämme kasvotietokanta saatiin ystävällisesti AT&T Laboratoriesilta Cambridgesta, ja se koostui 40 yksittäisestä kasvosta, joista jokaisesta oli 10 kuvaa, joissa oli vaihtelevia ilmeitä ja pään asentoja.
Harjoituksessa käytettiin seuraavia Python-kirjastoja ja -moduuleja:
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
-funktio skaalaa jokaisen yksittäisen otosvektorin niin, että sillä on yksikkönormi. -
PCA
eli periaatekomponenttianalyysi on lineaarinen dimensioiden pienentämisprosessi, jossa käytetään datan singulaariarvojen hajotusta sen projisoimiseksi alempiulotteiseen avaruuteen. Toisin sanoen se on prosessi, jossa etsitään datan perimmäinen rakenne tai suunnat, joissa on eniten varianssia. -
matplotlib.pyplot
on tuttu piirtofunktio. -
imread
käytetään kuvan lukemiseen tiedostosta matriisina. -
chain
on iteraattori, joka käy listan läpi palauttaen yksittäisiä elementtejä jokaisesta iteraattorista. -
numpy
on perustavanlaatuinen Python-paketti tieteelliseen laskentaan. -
scipy
on toinen tieteelliseen ja tekniseen laskentaan tarkoitettu paketti, joka on samankaltainen kuinnumpy
, mutta joka sisältää monipuolisemmat versiot lineaarialgebran moduuleista sekä monia muita numeerisia algoritmeja. -
glob
moduuli etsii kaikki polkujen nimet, jotka sopivat määritettyyn kuvioon.
Ensimmäisenä vaiheena poimitaan pakatusta arkistosta kaikki tiedostojen nimet. Sitten luodaan matriisi purkamalla kuvamatriisit vektoreiksi chain
-komennolla ja pinoamalla ne. Näin luodaan 400×10304-matriisi, jonka jokainen rivi sisältää kaikki tiedot tietystä 112×92-kokoisesta kuvasta.
filenames = m = for i in range(400)]for i in range(400):
m = list(chain.from_iterable(imread(filenames)))
m = np.matrix(m)
Seuraavaksi matriisi normalisoidaan ja sovelletaan PCA:ta. Tässä olemme pienentäneet vektoriavaruutemme vain 40:een ulottuvuuteen 10304:stä:
model = PCA(n_components=40)
pts = normalize(m)
model.fit(pts)
pts2 = model.transform(pts)
Viimeiseksi voidaan näyttää model.components_
:n sisältämät ominaissivut:
fig, ax = plt.subplots(1,40)for i in range(40):
ord = model.components_
img = ord.reshape(112,92)
ax.imshow(img,cmap='gray')