Gesichtserkennung mit Eigengesichtern

Gesichtserkennung ist in der Science-Fiction allgegenwärtig: Der Protagonist schaut in eine Kamera, und die Kamera scannt sein oder ihr Gesicht, um die Person zu erkennen. Formal gesehen kann man die Gesichtserkennung als eine Klassifizierungsaufgabe formulieren, bei der die Eingaben Bilder und die Ausgaben die Namen von Personen sind. Wir werden nun eine beliebte Technik zur Gesichtserkennung besprechen, die Eigenfaces genannt wird. Das Herzstück von Eigenfaces ist eine nicht überwachte Dimensionalitätsreduktionstechnik, die Hauptkomponentenanalyse (PCA), und wir werden sehen, wie wir diese allgemeine Technik auf unsere spezielle Aufgabe der Gesichtserkennung anwenden können. Laden Sie den vollständigen Code hier herunter.

Lassen Sie sich das Angebot nicht entgehen! Das Angebot endet in
  • Zugang zu allen über 200 Kursen
  • Neue Kurse werden monatlich hinzugefügt
  • Jederzeit kündbar
  • Abschlusszertifikate

Gesichtserkennung

Bevor wir die Hauptkomponentenanalyse diskutieren, sollten wir zunächst unser Problem definieren. Bei der Gesichtserkennung geht es darum, zu klassifizieren, wessen Gesicht sich in einem Eingabebild befindet. Dies unterscheidet sich von der Gesichtserkennung, bei der die Herausforderung darin besteht, festzustellen, ob ein Gesicht auf dem Eingabebild vorhanden ist. Bei der Gesichtserkennung benötigen wir eine bestehende Datenbank mit Gesichtern. Bei einem neuen Bild eines Gesichts müssen wir den Namen der Person angeben.

Eine naive Methode, dies zu erreichen, besteht darin, das neue Bild zu nehmen, es in einen Vektor zu zerlegen und den euklidischen Abstand zwischen ihm und allen anderen zerlegten Bildern in unserer Datenbank zu berechnen.

Dieser Ansatz hat mehrere Nachteile. Erstens, wenn wir eine große Datenbank mit Gesichtern haben, dauert es eine Weile, diesen Vergleich für jedes einzelne Gesicht durchzuführen! Stellen Sie sich vor, wir bauen ein Gesichtserkennungssystem für den Einsatz in Echtzeit! Je größer unser Datensatz ist, desto langsamer ist unser Algorithmus. Aber mehr Gesichter führen auch zu besseren Ergebnissen! Wir wollen ein System, das sowohl schnell als auch genau ist. Dafür werden wir ein neuronales Netz verwenden! Wir können unser Netzwerk auf unserem Datensatz trainieren und es für unsere Gesichtserkennungsaufgabe verwenden.

Es gibt ein Problem bei der direkten Verwendung eines neuronalen Netzwerks: Bilder können groß sein! Wenn wir ein einzelnes m\mal n

Bild hätten, müssten wir es in einen einzelnenm\dot n\mal 1Vektor umwandeln, um es in unser neuronales Netz als Eingabe zu geben. Bei großen Bildern kann dies die Geschwindigkeit beeinträchtigen! Dies hängt mit dem zweiten Problem bei der Verwendung von Bildern in unserem naiven Ansatz zusammen: Sie sind hochdimensional! (Ein

m\times nBild ist in Wirklichkeit einm\dot n\times 1Vektor) Eine neue Eingabe könnte eine Menge Rauschen enthalten und der Vergleich jedes einzelnen Pixels mit Hilfe von Matrixsubtraktion und euklidischem Abstand könnte uns einen hohen Fehler und Fehlklassifikationen bescheren!

Diese Probleme sind der Grund, warum wir die naive Methode nicht verwenden. Stattdessen möchten wir unsere hochdimensionalen Bilder auf eine geringere Dimensionalität reduzieren und dabei das Wesentliche oder wichtige Teile des Bildes beibehalten.

Dimensionalitätsreduktion

Der vorherige Abschnitt motiviert uns, eine Technik zur Dimensionalitätsreduktion einzusetzen. Die Dimensionalitätsreduktion ist eine Art des unüberwachten Lernens, bei dem wir höherdimensionale Daten, wie z.B. Bilder, in einem niedrigerdimensionalen Raum darstellen wollen. Nehmen wir das folgende Bild als Beispiel.

Diese Diagramme zeigen dieselben Daten, außer dass das untere Diagramm sie in die Nulllinie bringt. Beachten Sie, dass unseren Daten keine Labels zugeordnet sind, da es sich um unüberwachtes Lernen handelt! In unserem einfachen Fall wird die Dimensionalitätsreduktion diese Daten von einer 2D-Ebene auf eine 1D-Linie reduzieren. Hätten wir 3D-Daten, könnten wir sie auf eine 2D-Ebene oder sogar eine 1D-Linie reduzieren.

Alle Verfahren zur Dimensionalitätsreduktion zielen darauf ab, eine Hyperebene, eine höherdimensionale Linie, zu finden, auf die die Punkte projiziert werden. Wir können uns eine Projektion so vorstellen, dass wir eine Taschenlampe senkrecht zu der Hyperebene nehmen, auf die wir projizieren wollen, und aufzeichnen, wo die Schatten auf diese Hyperebene fallen. Wenn wir z. B. unsere Punkte auf die x-Achse projizieren wollen, stellen wir uns vor, dass jeder Punkt ein Ball ist, und unsere Taschenlampe würde direkt nach unten oder oben zeigen (senkrecht zur x-Achse), und die Schatten der Punkte würden auf die x-Achse fallen. Dies ist eine Projektion. Wir werden uns nicht um die genaue Mathematik dahinter kümmern, da scikit-learn diese Projektion für uns anwenden kann.

In unserem einfachen 2D-Fall wollen wir eine Linie finden, auf die wir unsere Punkte projizieren. Nachdem wir die Punkte projiziert haben, haben wir Daten in 1D statt in 2D! Wenn wir 3D-Daten hätten, würden wir eine Ebene suchen, auf die wir die Punkte projizieren, um die Dimensionalität unserer Daten von 3D auf 2D zu reduzieren. Bei den verschiedenen Arten der Dimensionalitätsreduzierung geht es darum, herauszufinden, welche dieser Hyperebenen ausgewählt werden soll: es gibt unendlich viele davon!

Hauptkomponentenanalyse

Eine Technik der Dimensionalitätsreduzierung ist die Hauptkomponentenanalyse (PCA). Die Idee hinter der PCA ist, die Hyperebene so zu wählen, dass alle Punkte, wenn sie auf sie projiziert werden, maximal verteilt sind. Mit anderen Worten, wir wollen die Achse mit der maximalen Varianz! Betrachten wir unser obiges Beispielplot. Eine mögliche Achse ist die x-Achse oder die y-Achse, aber in beiden Fällen ist das nicht die beste Achse. Wenn wir jedoch eine Linie wählen, die unsere Daten diagonal durchschneidet, ist dies die Achse, auf der die Daten am stärksten gestreut sind!

Die längere blaue Achse ist die richtige Achse! Wenn wir unsere Punkte auf diese Achse projizieren würden, wären sie maximal gestreut! Aber wie finden wir diese Achse heraus? Wir können uns einen Begriff aus der linearen Algebra ausleihen, der Eigenvektoren heißt! Daher kommt auch der Name Eigenflächen! Im Wesentlichen berechnen wir die Kovarianzmatrix unserer Daten und betrachten die größten Eigenvektoren dieser Kovarianzmatrix. Dies sind unsere Hauptachsen und die Achsen, auf die wir unsere Daten projizieren, um die Dimensionen zu reduzieren. Mit diesem Ansatz können wir hochdimensionale Daten auf eine niedrigere Dimension reduzieren, indem wir die größten Eigenvektoren der Kovarianzmatrix auswählen und auf diese Eigenvektoren projizieren.

Da wir die Achsen der maximalen Streuung berechnen, behalten wir die wichtigsten Aspekte unserer Daten bei. Für unseren Klassifikator ist es einfacher, Gesichter zu unterscheiden, wenn die Daten verteilt sind, als wenn sie gebündelt sind.

(Es gibt andere Dimensionalitätstechniken, wie z.B. die lineare Diskriminanzanalyse, die überwachtes Lernen verwenden und auch in der Gesichtserkennung eingesetzt werden, aber die PCA funktioniert wirklich gut!)

Was bedeutet das für unsere Herausforderung der Gesichtserkennung? Wir können uns unsere m\mal n

Bilder als Punkte in einemm\dot n-dimensionalen Raum vorstellen. Dann können wir PCA verwenden, um unseren Raum vonm\dot nauf etwas viel Kleineres zu reduzieren. Dies wird dazu beitragen, unsere Berechnungen zu beschleunigen und robust gegenüber Rauschen und Variationen zu sein.

Nebenbemerkung zur Gesichtserkennung

Bis jetzt haben wir angenommen, dass das Eingabebild nur das eines Gesichts ist, aber in der Praxis sollten wir nicht verlangen, dass die Kamerabilder ein perfekt zentriertes Gesicht haben. Aus diesem Grund führen wir einen sofort einsetzbaren Algorithmus zur Gesichtserkennung aus, z. B. einen auf Gesichter trainierten Kaskadenklassifikator, um herauszufinden, welcher Teil des Eingabebildes ein Gesicht enthält. Wenn wir diese Bounding Box haben, können wir diesen Teil des Eingabebildes einfach ausschneiden und Eigengesichter auf diesem Ausschnitt verwenden. (Normalerweise glätten wir diesen Ausschnitt und führen eine affine Transformation durch, um das Gesicht zu entzerren, wenn es in einem Winkel erscheint.) Für unsere Zwecke gehen wir davon aus, dass wir bereits Bilder von Gesichtern haben.

Eigenfaces Code

Nachdem wir nun PCA und Eigenfaces besprochen haben, wollen wir einen Algorithmus zur Gesichtserkennung mit scikit-learn programmieren! Zuerst brauchen wir einen Datensatz. Für unsere Zwecke werden wir einen fertigen Datensatz der University of Massachusetts namens Labeled Faces in the Wild (LFW) verwenden.

Fühlen Sie sich frei, Ihren eigenen Datensatz zu ersetzen! Wenn Sie Ihren eigenen Gesichtsdatensatz erstellen möchten, benötigen Sie mehrere Bilder von jedem Gesicht (in verschiedenen Winkeln und bei unterschiedlichen Lichtverhältnissen), zusammen mit den „ground-truth“-Beschriftungen. Je mehr verschiedene Gesichter Sie verwenden, desto besser wird der Erkenner abschneiden. Der einfachste Weg, einen Datensatz für die Gesichtserkennung zu erstellen, besteht darin, für jede Person einen Ordner zu erstellen und die Gesichtsbilder darin abzulegen. Vergewissern Sie sich, dass alle Bilder die gleiche Größe haben, und passen Sie die Größe an, damit sie nicht zu groß sind! Denken Sie daran, dass die PCA die Dimensionalität des Bildes bei der Projektion auf diesen Raum ohnehin reduziert, so dass die Verwendung großer, hochauflösender Bilder nicht hilfreich ist und unseren Algorithmus verlangsamt. Eine gute Größe ist ~512×512 für jedes Bild. Die Bilder sollten alle die gleiche Größe haben, damit man sie in einem Numpy-Array mit den Dimensionen (num_examples, height, width) speichern kann. (Wir gehen von Graustufenbildern aus). Verwenden Sie dann die Ordnernamen, um die Klassen zu disambiguieren. Mit diesem Ansatz können Sie Ihre eigenen Bilder verwenden.

Wir werden jedoch den LFW-Datensatz verwenden. Glücklicherweise kann scikit-learn unseren Datensatz automatisch im richtigen Format laden. Wir können eine Funktion aufrufen, um unsere Daten zu laden. Wenn die Daten nicht auf der Festplatte verfügbar sind, lädt scikit-learn sie automatisch von der Website der University of Massachusetts herunter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_lfw_people
from sklearn.metrics import classification_report
from sklearn.decomposition import PCA
from sklearn.neural_network import MLPClassifier
# Daten laden
lfw_dataset = fetch_lfw_people(min_faces_per_person=100)
_, h, w = lfw_dataset.images.shape
X = lfw_dataset.data
y = lfw_dataset.target
target_names = lfw_dataset.target_names
# split into a training and testing set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

Das Argument für unsere Funktion entfernt einfach alle Personen, die nicht mindestens 100 Gesichter haben, und reduziert so die Anzahl der Klassen. Dann können wir unseren Datensatz und andere Hilfsinformationen extrahieren. Zum Schluss teilen wir unseren Datensatz in einen Trainings- und einen Testdatensatz auf.

Jetzt können wir einfach die PCA-Klasse von Scikit-Learn verwenden, um die Dimensionalitätsreduktion für uns durchzuführen! Wir müssen die Anzahl der Komponenten, d.h. die Ausgangsdimensionalität (die Anzahl der Eigenvektoren, auf die projiziert werden soll), auf die wir reduzieren wollen, auswählen und können diesen Parameter nach Belieben verändern, um das beste Ergebnis zu erzielen! Wir werden 100 Komponenten verwenden. Außerdem werden wir unsere Daten aufhellen, was mit einem einfachen booleschen Flag leicht möglich ist! (Durch das Aufhellen erhalten unsere Daten lediglich eine Einheitsvarianz, was erwiesenermaßen zu besseren Ergebnissen führt)

1
2
3
4
5
6
7

# Berechne eine PCA
n_components = 100
pca = PCA(n_components=n_components, whiten=True).fit(X_train)
# PCA-Transformation anwenden
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)

Wir können die Transformation anwenden, um unsere Bilder auf einen 100-dimensionalen Raum zu reduzieren. Beachten Sie, dass wir die PCA nicht auf den gesamten Datensatz anwenden, sondern nur auf die Trainingsdaten. So können wir besser auf ungesehene Daten verallgemeinern.

Nun, da wir einen Vektor mit reduzierter Dimensionalität haben, können wir unser neuronales Netz trainieren!

1
2
3

# trainiere ein neuronales Netzwerk
print(„Fitting the classifier to the training set“)
clf = MLPClassifier(hidden_layer_sizes=(1024,), batch_size=256, verbose=True, early_stopping=True).fit(X_train_pca, y_train)

Um zu sehen, wie unser Netzwerk trainiert, können wir das verbose Flag setzen. Außerdem verwenden wir das frühe Anhalten.

Lassen Sie uns kurz auf das frühe Anhalten eingehen. Im Wesentlichen überwacht unser Optimierer die durchschnittliche Genauigkeit für den Validierungssatz für jede Epoche. Wenn er feststellt, dass sich die Validierungsgenauigkeit für eine bestimmte Anzahl von Epochen nicht signifikant erhöht hat, wird das Training abgebrochen. Dies ist eine Regularisierungstechnik, die verhindert, dass sich unser Modell übermäßig anpasst!

Betrachten Sie das obige Diagramm. Wir bemerken eine Überanpassung, wenn die Genauigkeit unseres Validierungssatzes zu sinken beginnt. An diesem Punkt stoppen wir sofort das Training, um eine Überanpassung zu verhindern.

Schließlich können wir eine Vorhersage treffen und eine Funktion verwenden, um einen vollständigen Qualitätsbericht für jede Klasse auszudrucken.

1
2

y_pred = clf.predict(X_test_pca)
print(classification_report(y_test, y_pred, target_names=target_names))

Hier ist ein Beispiel für einen Klassifizierungsbericht.

1
2
3
4
5
6
7
8
9

Präzision Rückruf f1-score support
Colin Powell 0.86 0.89 0.87 66
Donald Rumsfeld 0.85 0.61 0.71 38
George W Bush 0.88 0.94 0.91 177
Gerhard Schroeder 0.67 0.69 0.68 26
Tony Blair 0.86 0.71 0.78 35
Durchschnitt/Gesamt 0.85 0.85 0.85 342

Bemerken Sie, dass es keinen Genauigkeitsmaßstab gibt. Genauigkeit ist nicht die spezifischste Art von Metrik für den Anfang. Stattdessen sehen wir Präzision, Recall, f1-Score und Support. Die Unterstützung ist einfach die Anzahl der Vorkommen dieser Grundwahrheitsbezeichnung in unserer Testmenge, z. B. gab es in unserer Testmenge tatsächlich 35 Bilder von Tony Blair. Der F1-Score wird eigentlich nur aus den Werten für Precision und Recall berechnet. Precision und Recall sind spezifischere Maßzahlen als ein einzelner Genauigkeitswert. Ein höherer Wert für beide ist besser.

Nachdem wir unseren Klassifikator trainiert haben, können wir ihm ein paar Bilder zum Klassifizieren geben.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Visualisierung
def plot_gallery(images, titles, h, w, rows=3, cols=4):
plt.figure()
for i in range(rows * cols):
plt.subplot(rows, cols, i + 1)
plt.imshow(images.reshape((h, w)), cmap=plt.cm.gray)
plt.title(titles)
plt.xticks(())
plt.yticks(())
def titles(y_pred, y_test, target_names):
for i in range(y_pred.shape):
pred_name = target_names].split(‚ ‚)
true_name = target_names].split(‚ ‚)
yield ‚predicted: {0}\true: {1}‘.format(pred_name, true_name)
prediction_titles = list(titles(y_pred, y_test, target_names))
plot_gallery(X_test, prediction_titles, h, w)

(plot_gallery und titles functions modified from the scikit-learn documentation)

Wir können die Vorhersagen unseres Netzwerks und den Ground-Truth-Wert für jedes Bild sehen.

Eine weitere interessante Sache, die man visualisieren kann, sind die Eigenflächen selbst. Denken Sie daran, dass die PCA Eigenvektoren erzeugt. Wir können diese Eigenvektoren in Bilder umformen und die Eigenflächen visualisieren.

Diese stellen die „generischen“ Flächen unseres Datensatzes dar. Intuitiv handelt es sich dabei um Vektoren, die Richtungen im „Gesichtsraum“ darstellen und die unser neuronales Netz zur Klassifizierung verwendet. Nachdem wir nun den Ansatz der Eigenfaces besprochen haben, können Sie Anwendungen erstellen, die diesen Algorithmus zur Gesichtserkennung verwenden!

Wir haben einen beliebten Ansatz zur Gesichtserkennung namens Eigenfaces besprochen. Der Kern von Eigenfaces ist ein unüberwachter Algorithmus zur Dimensionalitätsreduzierung, der Principal Components Analysis (PCA) genannt wird und den wir verwenden, um die Dimensionalität von Bildern auf eine kleinere Größe zu reduzieren. Jetzt, da wir eine kleinere Darstellung unserer Gesichter haben, wenden wir einen Klassifikator an, der die reduzierte Dimension als Input nimmt und eine Klassenbezeichnung erzeugt. Für unseren Klassifikator haben wir ein einschichtiges neuronales Netz verwendet.

Gesichtserkennung ist ein faszinierendes Beispiel für die Verschmelzung von Computer Vision und maschinellem Lernen, und viele Forscher arbeiten auch heute noch an diesem herausfordernden Problem!

Heutzutage werden tiefe faltige neuronale Netze für die Gesichtserkennung verwendet und haben enorme Auswirkungen auf die Entwicklung der Berufswelt. Probieren Sie es an diesem Datensatz aus!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.