
Das siamesische neuronale Netzwerk ist einer der einfachsten und beliebtesten Algorithmen für das einzelne Lernen. Methoden, bei denen für jede Klasse nur eine Fallstudie durchgeführt wird. Daher wird das siamesische Netzwerk normalerweise in Anwendungen verwendet, in denen nicht viele Dateneinheiten in jeder Klasse vorhanden sind.
Angenommen, wir müssen ein Gesichtserkennungsmodell für eine Organisation erstellen, die etwa 500 Mitarbeiter beschäftigt. Wenn Sie ein solches Modell basierend auf dem Convolutional Neural Network (CNN) von Grund auf neu erstellen, benötigen wir viele Bilder von jeder dieser 500 Personen, um das Modell zu trainieren und eine gute Erkennungsgenauigkeit zu erzielen. Es ist jedoch offensichtlich, dass wir einen solchen Datensatz nicht erfassen können. Sie sollten daher kein Modell erstellen, das auf CNN oder einem anderen
Deep-Learning- Algorithmus basiert, wenn wir nicht über genügend Daten verfügen. In solchen Fällen können Sie den komplexen einmaligen Lernalgorithmus wie das siamesische Netzwerk verwenden, der mit weniger Daten trainiert werden kann.
Tatsächlich bestehen siamesische Netze aus zwei symmetrischen neuronalen Netzen mit den gleichen Gewichten und der gleichen Architektur, die am Ende die Energiefunktion kombinieren und nutzen - E.
Schauen wir uns das siamesische Netzwerk an und erstellen ein darauf basierendes Gesichtserkennungsmodell. Wir werden sie lehren zu bestimmen, wann zwei Gesichter gleich sind und wann nicht. Für den Anfang verwenden wir den Datensatz AT & T Database of Faces, der von der
Computerlabor- Website der
Universität Cambridge heruntergeladen werden kann.
Laden Sie Ordner von s1 bis s40 herunter, entpacken Sie sie und sehen Sie sie sich an:

Jeder Ordner enthält 10 verschiedene Fotos einer einzelnen Person aus verschiedenen Blickwinkeln. Hier ist der Inhalt des s1-Ordners:

Und hier ist, was sich im s13-Ordner befindet:

Siamesische Netzwerke müssen gepaarte Werte mit Markierungen eingeben, also erstellen wir solche Mengen. Nehmen Sie zwei zufällige Fotos aus demselben Ordner auf und markieren Sie sie als „echtes“ Paar. Dann machen wir zwei Fotos aus verschiedenen Ordnern und markieren sie als "falsches" Paar (imposit):

Nachdem wir alle Fotos in markierten Paaren verteilt haben, werden wir das Netzwerk untersuchen. Von jedem Paar übertragen wir ein Foto an Netzwerk A und das zweite an Netzwerk B. Beide Netzwerke extrahieren nur Eigenschaftsvektoren. Dazu verwenden wir zwei Faltungsschichten mit Aktivierung der gleichgerichteten Lineareinheit (ReLU). Nachdem wir die Eigenschaften untersucht haben, übertragen wir die von beiden Netzwerken erzeugten Vektoren in eine Energiefunktion, die die Ähnlichkeit abschätzt. Wir verwenden den euklidischen Abstand als Funktion.
Betrachten Sie nun alle diese Schritte genauer.
Importieren Sie zunächst die erforderlichen Bibliotheken:
import re import numpy as np from PIL import Image from sklearn.model_selection import train_test_split from keras import backend as K from keras.layers import Activation from keras.layers import Input, Lambda, Dense, Dropout, Convolution2D, MaxPooling2D, Flatten from keras.models import Sequential, Model from keras.optimizers import RMSprop
Nun definieren wir eine Funktion zum Lesen von Eingabebildern. Die Funktion
read_image
macht ein Bild und gibt ein NumPy-Array zurück:
def read_image(filename, byteorder='>'):
Öffnen Sie zum Beispiel dieses Foto:
Image.open("data/orl_faces/s1/1.pgm")

Wir übergeben es an die Funktion
read_image
und erhalten ein NumPy-Array:
img = read_image('data/orl_faces/s1/1.pgm') img.shape (112, 92)
Jetzt definieren wir die Funktion
get_data
, die die Daten generiert. Ich möchte Sie daran erinnern, dass siamesische Netzwerke Datenpaare (echt und imposant) mit binärer Markierung einreichen müssen.
Lesen Sie zuerst die Bilder (
img1
,
img2
) aus einem Verzeichnis, speichern Sie sie im Array
x_genuine_pair,
setzen Sie
y_genuine
auf
1
. Dann lesen wir die Bilder (
img1
,
img2
) aus verschiedenen Verzeichnissen, speichern sie im
x_imposite,
Paar und setzen
y_imposite
auf
0
.
x_genuine_pair
x_imposite
x_genuine_pair
und
x_imposite
in
X
und
y_genuine
und
y_imposite
in
Y
:
size = 2 total_sample_size = 10000 def get_data(size, total_sample_size):
Jetzt werden wir die Daten generieren und ihre Größe überprüfen. Wir haben 20.000 Fotos, von denen 10.000 echte und 10.000 falsche Paare gesammelt wurden:
X, Y = get_data(size, total_sample_size) X.shape (20000, 2, 1, 56, 46) Y.shape (20000, 1)
Wir werden die gesamte Reihe von Informationen teilen: 75% der Paare werden zum Training gehen und 25% - zum Testen:
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=.25)
Erstellen Sie jetzt ein siamesisches Netzwerk. Zuerst definieren wir das Kernnetzwerk - es wird ein neuronales Faltungsnetzwerk sein, um Eigenschaften zu extrahieren. Erstellen Sie zwei Faltungsebenen mit ReLU-Aktivierungen und eine Ebene mit maximalem Pooling nach einer flachen Ebene:
def build_base_network(input_shape): seq = Sequential() nb_filter = [6, 12] kernel_size = 3
Dann werden wir ein Paar von Bildern des Kernnetzwerks übertragen, die Vektordarstellungen, dh Eigenschaftsvektoren, zurückgeben:
input_dim = x_train.shape[2:] img_a = Input(shape=input_dim) img_b = Input(shape=input_dim) base_network = build_base_network(input_dim) feat_vecs_a = base_network(img_a) feat_vecs_b = base_network(img_b)
feat_vecs_a
und
feat_vecs_b
sind Eigenschaftsvektoren eines Bildpaares. Lassen Sie uns ihre Energiefunktionen übergeben, um den Abstand zwischen ihnen zu berechnen. Und als Funktion der Energie verwenden wir die euklidische Distanz:
def euclidean_distance(vects): x, y = vects return K.sqrt(K.sum(K.square(x - y), axis=1, keepdims=True)) def eucl_dist_output_shape(shapes): shape1, shape2 = shapes return (shape1[0], 1) distance = Lambda(euclidean_distance, output_shape=eucl_dist_output_shape)([feat_vecs_a, feat_vecs_b])
Wir setzen die Anzahl der Epochen auf 13, wenden die RMS-Eigenschaft zur Optimierung an und deklarieren das Modell:
epochs = 13 rms = RMSprop() model = Model(input=[input_a, input_b], output=distance)
Nun definieren wir die Verlustfunktion
contrastive_loss
und kompilieren das Modell:
def contrastive_loss(y_true, y_pred): margin = 1 return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0))) model.compile(loss=contrastive_loss, optimizer=rms)
Lassen Sie uns das Modell studieren:
img_1 = x_train[:, 0] img_2 = x_train[:, 1] model.fit([img_1, img_2], y_train, validation_split=.25, batch_size=128, verbose=2, nb_epoch=epochs)
Sie sehen, wie die Verluste im Laufe der Zeit abnehmen:
Train on 11250 samples, validate on 3750 samples Epoch 1/13 - 60s - loss: 0.2179 - val_loss: 0.2156 Epoch 2/13 - 53s - loss: 0.1520 - val_loss: 0.2102 Epoch 3/13 - 53s - loss: 0.1190 - val_loss: 0.1545 Epoch 4/13 - 55s - loss: 0.0959 - val_loss: 0.1705 Epoch 5/13 - 52s - loss: 0.0801 - val_loss: 0.1181 Epoch 6/13 - 52s - loss: 0.0684 - val_loss: 0.0821 Epoch 7/13 - 52s - loss: 0.0591 - val_loss: 0.0762 Epoch 8/13 - 52s - loss: 0.0526 - val_loss: 0.0655 Epoch 9/13 - 52s - loss: 0.0475 - val_loss: 0.0662 Epoch 10/13 - 52s - loss: 0.0444 - val_loss: 0.0469 Epoch 11/13 - 52s - loss: 0.0408 - val_loss: 0.0478 Epoch 12/13 - 52s - loss: 0.0381 - val_loss: 0.0498 Epoch 13/13 - 54s - loss: 0.0356 - val_loss: 0.0363
Und jetzt testen wir das Modell anhand von Testdaten:
pred = model.predict([x_test[:, 0], x_test[:, 1]])
Definieren Sie eine Funktion zur Berechnung der Genauigkeit:
def compute_accuracy(predictions, labels): return labels[predictions.ravel()
Wir berechnen die Genauigkeit:
compute_accuracy(pred, y_test) 0.9779092702169625
Schlussfolgerungen
In diesem Handbuch haben wir gelernt, wie Gesichtserkennungsmodelle basierend auf siamesischen Netzwerken erstellt werden. Die Architektur solcher Netze besteht aus zwei identischen neuronalen Netzen mit gleichem Gewicht und gleicher Struktur, und die Ergebnisse ihrer Arbeit werden auf eine Energiefunktion übertragen - dies bestimmt die Identität der Eingabedaten. Weitere Informationen zum Meta-Lernen mit
Python finden Sie unter
Praktisches Meta-Lernen mit Python.Mein Kommentar
Für die Arbeit mit Bildern sind derzeit Kenntnisse über siamesische Netzwerke erforderlich. Es gibt viele Ansätze, um Netzwerke in kleinen Stichproben, neue Datengenerierung und Erweiterungsmethoden zu trainieren. Diese Methode ermöglicht es relativ "billig", gute Ergebnisse zu erzielen. Hier ist ein klassischeres Beispiel für das siamesische Netzwerk in "Hallo Welt" für neuronale Netze - Datensatz MNIST
keras.io/examples/mnist_siamese