Rozpoznávání obličejů je jedním z oborů, které využívají strojové učení a jsou široce využívány v mnoha oblastech od označování fotografií na sociálních sítích a porovnávání lidí se stejnými rysy obličeje na seznamkách, přes vyhledávání zločinců a ochranu hranic až po hlídání hráčů v kasinech.

Považuji za fascinující, že dokážeme simulovat proces rozpoznávání obličejů se značnou mírou přesnosti, a zároveň existují lidé, kteří trpí prosopagnosií neboli „obličejovou slepotou“ a kteří takové štěstí nemají. Autor článku na serveru Cracked, na který jsem před časem narazil, popisuje tuto zkušenost jako pohled na hromadu stavebnic LEGO, u nichž, jakmile odvrátíte zrak, už nedokážete do podstatných detailů popsat, jakou barvu a tvar měly jednotlivé dílky a jak byly rozmístěny. Napadlo mě, jestli tato kognitivní porucha nesouvisí s alokací paměti. Naštěstí je paměť něco, čeho mají počítače dostatek, a to jsme ještě ani nezačali škrábat povrch celého souboru schopností, které nám kvantová výpočetní technika nabídne.

Ale zpět k vlastním obrazům.

Vizuální data v obraze lze mapovat do vektoru, kde každá položka představuje jas příslušného pixelu. Vezmeme-li sadu obrázků, lze pak sestrojit matici, jejíž každý řádek odpovídá určitému obrazovému vektoru. V ideálním případě se snímky nejprve normalizují tak, aby se vyrovnaly základní rysy, jako jsou oči, nos a ústa, a tím se zvýšila přesnost a snížil šum. Vlastní tváře jsou pak vlastní vektory, které jsou odvozeny z kovarianční matice této matice analyzovaných dat tváří.

Soubor dat tváří, který jsme použili, byl laskavě poskytnut laboratořemi AT&T v Cambridge a skládal se ze 40 jednotlivých tváří, z nichž každá měla 10 snímků s různým výrazem tváře a polohou hlavy.

V tomto cvičení byly použity následující knihovny a moduly Pythonu:

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 funkce škáluje každý jednotlivý vektor vzorku tak, aby měl jednotkovou normu.
  • PCA neboli analýza hlavních komponent je proces lineární redukce dimenzionality pomocí rozkladu singulární hodnoty dat, který je promítá do prostoru s nižší dimenzí. Jinými slovy je to proces hledání základní struktury dat nebo směrů, ve kterých je největší rozptyl.
  • matplotlib.pyplot je známá funkce vykreslování.
  • imread slouží k načtení obrázku ze souboru jako pole.
  • chain je iterátor, který prochází seznamem a vrací jednotlivé prvky z každé iterovatelné položky.
  • numpy je základní balík jazyka Python pro vědecké výpočty.
  • scipy je další balík pro vědecké a technické výpočty, podobný balíku numpy, který však obsahuje plnohodnotnější verze modulů lineární algebry a mnoho dalších numerických algoritmů.
  • glob Modul najde všechny názvy cest odpovídající zadanému vzoru.

Prvním krokem je extrakce všech názvů souborů ze zazipovaného archivu. Poté se vytvoří matice rozbalením matic obrázků na vektory pomocí příkazu chain a jejich poskládáním. Tím se vytvoří matice 400×10304, přičemž každý řádek obsahuje všechny informace o konkrétním obrázku 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)

Následuje normalizace matice a aplikace PCA. Zde jsme zredukovali náš vektorový prostor na pouhých 40 z 10304 rozměrů:

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

Nakonec lze zobrazit vlastní plochy, obsažené v model.components_:

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

A je to. Hromada strašidelných tváří.

V podstatě jsme vytvořili ortogonální základní množinu, kde každá vlastní plocha zvýrazňuje určitý typ rysu a z níž lze pomocí různých kombinací a poměrů vlastních vektorů rekonstruovat námi použité tváře.

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")

Protože jsme náš vektorový prostor natolik zkomprimovali (a obličeje jsme na začátku nesrovnali), ztratilo se mnoho detailů, ale obličeje přesto zůstaly do určité míry rozpoznatelné.

A tak je cílem problému počítačového vidění rozpoznávání lidských tváří vytvořit minimální počet vlastních tváří, které mohou adekvátně reprezentovat celou trénovací množinu. Pokud je trénovací množina dostatečně různorodá, měla by výsledná množina vlastních obličejů být schopna reprezentovat všechny obličeje. A přestože bylo v posledních letech dosaženo významného pokroku v oblasti algoritmů pro rozpoznávání obličejů, je před námi ještě dlouhá cesta a spousta vylepšení.

Na druhou stranu, a jako vždy, existují určitá nebezpečí spojená se stále se rozšiřujícími možnostmi softwaru, který je schopen rozpoznat, simulovat, a tím potenciálně oklamat a manipulovat nic netušícího jedince, a musíme přijmout odpovídající opatření, abychom se ujistili, že je používán vhodným způsobem.

A toto zde nechám jen jako příklad a pro pobavení.

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.