Gezichtsherkenning is een van de gebieden waarop machinaal leren wordt toegepast en wordt op vele gebieden toegepast, van het taggen van foto’s op sociale media en het matchen van mensen met dezelfde gelaatstrekken op datingsites, tot het opsporen van criminelen en het beveiligen van grenzen, tot het op afstand houden van high rollers in casino’s.

Ik vind het fascinerend dat we het proces van gezichtsherkenning met een aanzienlijke mate van precisie kunnen simuleren, terwijl er tegelijkertijd mensen zijn die lijden aan prosopagnosie, of “gezichtsblindheid”, die niet zo gelukkig zijn. Een auteur van een Cracked artikel waar ik een tijdje geleden op stuitte beschrijft deze ervaring als het zien van een stapel LEGO’s waarbij je, zodra je wegkijkt, niet langer in detail kunt beschrijven welke kleur en vorm elk stukje had of hoe ze waren gepositioneerd. Ik heb me afgevraagd of deze cognitieve stoornis iets te maken heeft met geheugentoewijzing. Gelukkig hebben computers geheugen in overvloed, en we zijn nog niet eens begonnen aan het oppervlak van alle mogelijkheden die quantumcomputing zal bieden.

Maar terug naar eigenfaces.

De visuele gegevens in een afbeelding kunnen in kaart worden gebracht in een vector waarbij elk gegeven de helderheid van de corresponderende pixel weergeeft. Door een reeks beelden te nemen, kan dan een matrix worden geconstrueerd met elke rij die met een specifieke beeldvector overeenkomt. Idealiter worden de beelden eerst genormaliseerd om basiskenmerken zoals ogen, neus en mond op één lijn te brengen om de nauwkeurigheid te verhogen en ruis te verminderen. Eigenfaces zijn dan de eigenvectoren die worden afgeleid uit de covariantiematrix van deze matrix van geparseerde gezichtsgegevens.

De dataset van gezichten die we gebruikten werd vriendelijk ter beschikking gesteld door AT&T Laboratories in Cambridge en bestond uit 40 individuele gezichten, 10 beelden van elk met variërende gezichtsuitdrukkingen en hoofdposities.

De volgende Python-bibliotheken en -modules werden in deze oefening gebruikt:

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 functie schaalt elke individuele steekproefvector om eenheidsnorm te hebben.
  • PCA of Principle Component Analysis, is een proces van lineaire dimensionaliteitsvermindering met behulp van Singular Value Decomposition van de gegevens om ze te projecteren naar een lagere dimensionale ruimte. Met andere woorden, het is het proces van het vinden van de onderliggende structuur van de gegevens of de richtingen waarin de meeste variantie is.
  • matplotlib.pyplot is de bekende plotfunctie.
  • imread wordt gebruikt om een afbeelding uit een bestand in te lezen als een matrix.
  • chain is een iterator die door de lijst gaat en individuele elementen van elke iterable teruggeeft.
  • numpy is het fundamentele Python pakket voor wetenschappelijke berekeningen.
  • scipy is een ander pakket voor wetenschappelijke en technische berekeningen, vergelijkbaar met numpy maar dat meer volledig uitgeruste versies van de lineaire algebra modules bevat, evenals vele andere numerieke algoritmen.
  • glob module vindt alle padnamen die overeenkomen met een opgegeven patroon.

De eerste stap is om alle bestandsnamen uit het gezipte archief te halen. Dan wordt een matrix gemaakt door beeldmatrices met het chain-commando in vectoren te ontrafelen en ze te stapelen. Hierdoor ontstaat een 400×10304 matrix met elke rij alle informatie over een specifieke 112×92 afbeelding.

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

Volgende wordt de matrix genormaliseerd en de PCA wordt toegepast. Hier hebben we onze vectorruimte teruggebracht tot slechts 40 van de 10304 dimensies:

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

Tot slot kunnen de eigenfaces, die in model.components_ staan, worden weergegeven:

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

En daar hebben we het. Een stel griezelige gezichten.

Wat we in wezen hebben gedaan, is een orthogonale basisverzameling maken waarbij elk eigenvlak een bepaald type kenmerk benadrukt, en waaruit de gezichten die we hebben gebruikt kunnen worden gereconstrueerd door middel van verschillende combinaties en verhoudingen van eigenvectoren.

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

Omdat we onze vectorruimte zo sterk hebben gecomprimeerd (en de gezichten om te beginnen niet hebben uitgelijnd), zijn veel details verloren gegaan, maar de gezichten zijn toch nog enigszins herkenbaar gebleven.

En dus is het doel van het computervisieprobleem van menselijke gezichtsherkenning het creëren van het minimum aantal eigenfaces dat de gehele trainingsverzameling adequaat kan representeren. Als de trainingsverzameling voldoende divers is, moet de resulterende verzameling eigenfaces in staat zijn alle gezichten te representeren. En hoewel er de laatste jaren aanzienlijke vooruitgang is geboekt met gezichtsherkenningsalgoritmen, is er nog een lange weg te gaan en zijn er nog veel verbeteringen mogelijk.

Aan de andere kant zijn er, zoals altijd, gevaren verbonden aan de steeds toenemende mogelijkheden van software die in staat is een nietsvermoedend individu te herkennen, te simuleren en dus mogelijk te misleiden en te manipuleren, en we moeten de nodige voorzorgsmaatregelen nemen om ervoor te zorgen dat deze op de juiste wijze wordt gebruikt.

En ik laat dit hier even voor wat het is en voor uw vermaak.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.