Az arcfelismerés az egyik olyan terület, amely a gépi tanulást alkalmazza, és széles körben használják számos területen, kezdve a közösségi médiában található fényképek megjelölésétől és az azonos arcvonásokkal rendelkező emberek párosításától a társkereső oldalakon, a bűnözők felkutatásán és a határok biztosításán át a nagymenők sakkban tartásáig a kaszinókban.
Lenyűgözőnek találom, hogy jelentős pontossággal tudjuk szimulálni az arcfelismerés folyamatát, ugyanakkor vannak olyan emberek, akik prosopagnosiában, azaz “arcvakságban” szenvednek, akiknek nincs ilyen szerencséjük. Egy Cracked-cikk szerzője, amibe nemrég belebotlottam, úgy írja le ezt az élményt, mintha egy halom LEGO-t látnánk, ahol amint félrenézünk, már nem tudjuk érdemben leírni, hogy az egyes darabok milyen színűek és formájúak, vagy hogyan helyezkednek el. Elgondolkodtam azon, hogy ennek a kognitív zavarnak van-e valami köze a memóriaelosztáshoz. Szerencsére a memória olyasmi, amiből a számítógépeknek rengeteg van, és még csak a felszínét sem kezdtük el kapargatni annak a teljes képességkészletnek, amit a kvantumszámítógépek nyújtani fognak.
De vissza a sajátfelületekhez.
A kép vizuális adatai leképezhetők egy vektorra, ahol minden egyes bejegyzés a megfelelő pixel fényerejét jelöli. Ha egy képhalmazt veszünk, akkor egy mátrixot építhetünk, amelynek minden sora egy adott képvektornak felel meg. Ideális esetben a képeket először normalizáljuk oly módon, hogy a pontosság növelése és a zaj csökkentése érdekében az alapvető jellemzők, például a szemek, az orr és a száj összehangolására kerüljön sor. A saját arcok ezután a sajátvektorok, amelyeket ennek a mátrixnak a kovariancia-mátrixából származtatnak az elemzett arcadatokból.
Az általunk használt arcok adathalmazát a cambridge-i AT&T Laboratories bocsátotta rendelkezésünkre, és 40 egyedi arcból állt, mindegyikből 10 képből, változó arckifejezéssel és fejpozícióval.
A feladat során a következő Python könyvtárakat és modulokat használtuk:
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
függvény minden egyes mintavektort egységnyi normára méretez. -
PCA
vagy Principle Component Analysis, a lineáris dimenziócsökkentés folyamata, amely az adatok szinguláris érték dekompozícióját használja, hogy egy alacsonyabb dimenziós térbe vetítse azokat. Más szóval az adatok mögöttes struktúrájának, illetve azon irányok megtalálása, amelyekben a legnagyobb a szórás. -
matplotlib.pyplot
az ismert ábrázoló függvény. -
imread
arra szolgál, hogy egy képet egy fájlból tömbként beolvassunk. -
chain
egy iterátor, amely végigmegy a listán, visszaadva az egyes iterálandó elemek egyes elemeit. -
numpy
a tudományos számítások alapvető Python-csomagja. -
scipy
egy másik csomag a tudományos és műszaki számításokhoz, hasonló anumpy
-hoz, de tartalmazza a lineáris algebra modulok teljesebb képességű változatait, valamint számos más numerikus algoritmust. -
glob
A modul megtalálja az összes olyan elérési útvonalnevet, amely megfelel egy megadott mintának.
Az első lépés az összes fájlnevet kivenni a zipelt archívumból. Ezután a chain
parancs segítségével a képmátrixok vektorokká bontásával és egymásra helyezésével létrejön egy mátrix. Ez egy 400×10304-es mátrixot hoz létre, amelynek minden sora egy adott 112×92-es kép összes információját tartalmazza.
filenames = m = for i in range(400)]for i in range(400):
m = list(chain.from_iterable(imread(filenames)))
m = np.matrix(m)
A következő lépés a mátrix normalizálása és a PCA alkalmazása. Itt a vektortérünket az 10304 dimenzióból mindössze 40-re csökkentettük:
model = PCA(n_components=40)
pts = normalize(m)
model.fit(pts)
pts2 = model.transform(pts)
Végül megjeleníthetjük a model.components_
-ben szereplő sajátfelületeket:
fig, ax = plt.subplots(1,40)for i in range(40):
ord = model.components_
img = ord.reshape(112,92)
ax.imshow(img,cmap='gray')
És kész is vagyunk. Egy rakás hátborzongató arc.
Azt tettük lényegében, hogy létrehoztunk egy ortogonális alaphalmazt, ahol minden egyes sajátarc kiemel egy bizonyos típusú tulajdonságot, és amelyből az általunk használt arcok a sajátvektorok különböző kombinációi és arányai révén rekonstruálhatók.
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")
Mivel a vektortérünket annyira összenyomtuk (és eleve nem igazítottuk az arcokat), sok részlet elveszett, de az arcok így is valamelyest felismerhetők maradtak.
Az emberi arcfelismerés számítógépes látásproblémájának célja tehát az, hogy olyan minimális számú sajátarcot hozzunk létre, amely képes megfelelően reprezentálni a teljes gyakorlóhalmazt. Ha a gyakorlóhalmaz kellően változatos, akkor az így kapott sajátarcok halmazának képesnek kell lennie az összes arc reprezentálására. És bár az elmúlt években jelentős előrelépés történt az arcfelismerő algoritmusok terén, még mindig hosszú út áll előttünk, és rengeteg fejlesztésre van szükség.
Másrészt, mint mindig, az egyre bővülő képességekkel rendelkező szoftverek, amelyek képesek felismerni, szimulálni, és ezáltal potenciálisan megtéveszteni és manipulálni egy gyanútlan személyt, bizonyos veszélyeket rejtenek magukban, és megfelelő óvintézkedéseket kell tennünk annak biztosítására, hogy megfelelően használjuk őket.
És ezt most csak példának okáért és az Ön szórakoztatására hagyom itt.