Ansiktsigenkänning är ett av de områden där maskininlärning används och används i stor utsträckning på många områden, från att tagga foton på sociala medier och matcha personer med samma ansiktsdrag på dejtingsajter till att spåra upp brottslingar, säkra gränser och hålla storspelare i schack på kasinon.

Jag tycker att det är fascinerande att vi kan simulera processen för ansiktsigenkänning med en betydande grad av precision, samtidigt som det finns människor som lider av prosopagnosia, eller ”ansiktsblindhet”, som inte har samma tur. En författare till en Cracked-artikel som jag snubblade över för ett tag sedan beskriver denna upplevelse som att se en hög med LEGO-klossar där man så fort man tittar bort inte längre kan beskriva i någon väsentlig detalj vilken färg och form varje bit hade eller hur de var placerade. Jag har undrat om denna kognitiva störning har något att göra med minnesallokering. Lyckligtvis är minne något som datorer har gott om och vi har inte ens börjat skrapa på ytan av alla de möjligheter som kvantdatorer kommer att erbjuda.

Men tillbaka till egenytorna.

Den visuella datan i en bild kan avbildas till en vektor där varje post representerar ljusstyrkan hos motsvarande pixel. Genom att ta en uppsättning bilder kan man sedan konstruera en matris där varje rad motsvarar en specifik bildvektor. I idealfallet normaliseras bilderna först på ett sätt som anpassar grundläggande egenskaper som ögon, näsa och mun för att öka noggrannheten och minska bruset. Egna ansikten är sedan de egenvektorer som härleds från kovariansmatrisen för denna matris av analyserade ansiktsdata.

Den datamängd av ansikten som vi använde tillhandahölls vänligen av AT&T Laboratories i Cambridge och bestod av 40 individuella ansikten, 10 bilder av var och en med varierande ansiktsuttryck och huvudpositioner.

Följande Pythonbibliotek och -moduler användes i den här övningen:

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 funktionen skalar varje enskild provvektor så att den har enhetsnorm.
  • PCA eller Principle Component Analysis, är en process för linjär dimensionsminskning med hjälp av Singular Value Decomposition av data för att projicera dem till ett lägre dimensionellt utrymme. Med andra ord är det en process för att hitta den underliggande strukturen i data eller de riktningar där variansen är störst.
  • matplotlib.pyplot är den välkända plottningsfunktionen.
  • imread används för att läsa in en bild från en fil som en array.
  • chain är en iterator som går igenom listan och returnerar enskilda element från varje iterabel.
  • numpy är det grundläggande Python-paketet för vetenskapliga beräkningar.
  • scipy är ett annat paket för vetenskaplig och teknisk beräkning, som liknar numpy men som innehåller mer fullfjädrade versioner av modulerna för linjär algebra samt många andra numeriska algoritmer.
  • glob modulen hittar alla sökvägsnamn som matchar ett specificerat mönster.

Det första steget är att extrahera alla filnamn från det komprimerade arkivet. Därefter skapas en matris genom att avveckla bildmatriser till vektorer med hjälp av kommandot chain och stapla dem. Detta skapar en 400×10304-matris där varje rad innehåller all information om en specifik 112×92-bild.

filenames = m = for i in range(400)]for i in range(400):
m = list(chain.from_iterable(imread(filenames)))
m = np.matrix(m)

Nästan normaliseras matrisen och PCA tillämpas. Här har vi reducerat vårt vektorutrymme till endast 40 av 10304 dimensioner:

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

Slutligt kan egenytorna, som finns i model.components_, visas:

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

Och där har vi det. Ett gäng läskiga ansikten.

Vad vi i huvudsak har gjort är att skapa en ortogonal basuppsättning där varje egenyta framhäver en viss typ av egenskap, och från vilken de ansikten vi använde kan rekonstrueras genom olika kombinationer och proportioner av egenvektorer.

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

Eftersom vi komprimerade vårt vektorutrymme så mycket (och inte riktade in ansiktena till att börja med) förlorades en hel del av detaljerna, men ansiktena förblev ändå någorlunda igenkännbara.

Och sålunda är målet för datorseendeproblemet med igenkänning av mänskliga ansikten att skapa det minsta antalet egna ansikten som på ett adekvat sätt kan representera hela träningsmängden. Om träningsuppsättningen är tillräckligt varierad bör den resulterande uppsättningen av egna ansikten kunna representera alla ansikten. Även om betydande framsteg har gjorts under de senaste åren när det gäller algoritmer för ansiktsigenkänning finns det fortfarande en lång väg att gå och många förbättringar att göra.

Å andra sidan, och som alltid, finns det vissa faror förknippade med den ständigt växande kapaciteten hos programvara som kan känna igen, simulera och därmed potentiellt lura och manipulera en intet ont anande individ, och vi måste vidta tillräckliga försiktighetsåtgärder för att se till att den används på ett lämpligt sätt.

Och jag tänker bara lämna detta här som ett exempel och för din underhållning.

Lämna ett svar

Din e-postadress kommer inte publiceras.