Autoencoder in TensorFlow mit Beispiel

⚡ Intelligente Zusammenfassung

Autoencoder komprimieren eine Eingabe zu einer kleineren internen Repräsentation und rekonstruieren sie anschließend, indem sie die wichtigsten Merkmale ohne Labels lernen. Diese Anleitung stapelt vier Dense-Layer in TensorFlow und rekonstruiert CIFAR-10-Pferdebilder.

  • 🔘 Kodierer und Dekodierer: Zwei symmetrische Blöcke treffen in einer schmalen Codierungsschicht aufeinander, die das Netzwerk dazu zwingt, nur das wesentliche Signal beizubehalten.
  • ☑️ Vorbereitung des Datensatzes: Die CIFAR-10-Datensätze werden geladen, in Graustufen konvertiert, gestapelt und auf die 5,000 Pferdebilder reduziert.
  • Zuleitung: Ein Dataset-Schätzer mit from_tensor_slices, repeat und batch liefert Bilder über einen initialisierbaren Iterator.
  • 🧪 Netzwerkstruktur: Die Schichtbreiten betragen 1024, 300, 150, 300, 1024, mit ELU-Aktivierung, Xavier-Initialisierung und L2-Regularisierung.
  • Trainingsaufbau: Mittlerer quadratischer Fehler zwischen Ausgabe und Eingabe, Adam-Optimierer, Batchgröße von 150 und 33 Iterationen pro Epoche.
  • 📉 Messergebnis: Über 100 Epochen hinweg sinkt der Trainingsverlust von 2,934 auf etwa 1,454, bevor die Rekonstruktion dargestellt wird.

Autoencoder in TensorFlow

Was ist Autoencoder im Deep Learning?

An Autoencoder ist ein Werkzeug zum effizienten Erlernen der Datenkodierung in einem unbeaufsichtigt Art und Weise. Es ist eine Art von künstliche neuronale Netz Das hilft Ihnen, die Repräsentation von Datensätzen für die Dimensionsreduktion zu erlernen, indem das neuronale Netzwerk darauf trainiert wird, das Signalrauschen zu ignorieren. Es ist ein hervorragendes Werkzeug zur Rekonstruktion eines Eingangssignals.

Vereinfacht gesagt, nimmt die Maschine beispielsweise ein Bild und kann ein sehr ähnliches Bild erzeugen. Die Eingabe in diesem neuronalen Netzwerk ist unbeschriftet, das heißt, das Netzwerk kann ohne Überwachung lernen. Genauer gesagt, wird die Eingabe vom Netzwerk so kodiert, dass es sich nur auf das wichtigste Merkmal konzentriert. Dies ist einer der Gründe, warum Autoencoder zur Dimensionsreduktion so beliebt sind. Darüber hinaus können Autoencoder zur Erstellung generativer Lernmodelle verwendet werden. Beispielsweise kann das neuronale Netzwerk mit einer Reihe von Gesichtern trainiert werden und anschließend neue Gesichter erzeugen.

Wie funktioniert der TensorFlow Autoencoder?

Der Zweck eines Autoencoders besteht darin, eine Annäherung an die Eingabe zu erzeugen, indem er sich nur auf die wesentlichen Merkmale konzentriert. Sie denken vielleicht, warum nicht einfach lernen, wie man die Eingabe kopiert und einfügt, um die Ausgabe zu erzeugen. Tatsächlich handelt es sich bei einem Autoencoder um eine Reihe von Einschränkungen, die das Netzwerk dazu zwingen, neue Wege zur Darstellung der Daten zu erlernen, die sich vom bloßen Kopieren der Ausgabe unterscheiden.

Ein typischer Autoencoder besteht aus einem Input, einer internen Repräsentation und einem Output (einer Approximation des Inputs). Das Lernen findet in den Schichten statt, die mit der internen Repräsentation verbunden sind. Tatsächlich gibt es zwei Hauptblöcke von Schichten, die einem traditionellen neuronalen Netzwerk ähneln. Der kleine Unterschied besteht darin, dass die Schicht, die den Output enthält, dem Input entsprechen muss. Im folgenden Diagramm gelangt der ursprüngliche Input in den ersten Block, den sogenannten Encoder. Diese interne Repräsentation komprimiert (reduziert) den Input. Im zweiten Block erfolgt die Rekonstruktion des Inputs. Dies ist die Dekodierungsphase.

Encoder- und Decoderblöcke eines Autoencoders mit der komprimierten internen Darstellung in der Mitte
Funktionsweise des Autoencoders

Das Modell aktualisiert die Gewichte durch Minimierung der Verlustfunktion. Das Modell wird bestraft, wenn sich die Rekonstruktionsausgabe von der Eingabe unterscheidet.

Konkret stellen wir uns ein Bild mit einer Größe von 50×50 (also 2,500 Pixel) und ein neuronales Netzwerk mit nur einer verborgenen Schicht aus einhundert Neuronen vor. Das Lernen erfolgt anhand einer Merkmalskarte, die 25-mal kleiner als die Eingabe ist. Das Netzwerk muss also einen Weg finden, 2,500 Pixel mit nur einem Vektor von 100 Neuronen zu rekonstruieren.

Beispiel für einen gestapelten Autoencoder

In diesem Autoencoder-Tutorial lernen Sie die Verwendung eines gestapelten Autoencoders. Die Architektur ähnelt einem traditionellen neuronalen Netzwerk. Die Eingabedaten werden in einer verborgenen Schicht komprimiert, d. h. ihre Größe reduziert, und gelangen anschließend zu den Rekonstruktionsschichten. Ziel ist es, ein Ausgabebild zu erzeugen, das dem Original so nahe wie möglich kommt. Das Modell muss lernen, diese Aufgabe unter bestimmten Einschränkungen, also mit einer geringeren Dimensionalität, zu erfüllen.

Heutzutage werden Autoencoder im Deep Learning hauptsächlich zur Bildrauschentfernung eingesetzt. Stellen Sie sich ein Bild mit Kratzern vor; ein Mensch kann den Inhalt dennoch erkennen. Die Idee des Rauschunterdrückungs-Autoencoders besteht darin, dem Bild Rauschen hinzuzufügen, um das Netzwerk dazu zu bringen, das Muster hinter den Daten zu lernen.

Die andere nützliche Familie der Autoencoder Tiefes Lernen Es handelt sich um einen Variations-Autoencoder. Dieser Netzwerktyp kann neue Bilder generieren. Stellen Sie sich vor, Sie trainieren ein Netzwerk mit dem Bild eines Mannes; ein solches Netzwerk kann neue Gesichter erzeugen.

In der folgenden Tabelle wird der in diesem Tutorial erstellte gestapelte Autoencoder neben die anderen Familien gestellt, denen Sie wahrscheinlich begegnen werden, sodass die von jedem einzelnen hinzugefügte Einschränkung leicht verglichen werden kann.

Autoencoder-Typ Einschränkung hinzugefügt Typische Verwendung
Unvollständig / gestapelt Codierungsschicht schmaler als die Eingabe Dimensionsreduktion, MerkmalsextraktiontracProduktion
Entrauschen Dem Eingangssignal wurde Rauschen hinzugefügt, das Ziel ist sauber Bild- und Signalbereinigung
Spärlich Strafe für die Anzahl aktiver Einheiten Interpretierbare, teilbasierte Merkmale
Variationen Die Codierungsschicht lernt eine Wahrscheinlichkeitsverteilung Neue Proben generieren

So erstellen Sie einen Autoencoder mit TensorFlow

In diesem Tutorial erfahren Sie, wie Sie einen gestapelten Autoencoder erstellen, um ein Bild zu rekonstruieren.

Sie verwenden den CIFAR-10-Datensatz, der 60000 Farbbilder der Größe 32×32 enthält. Der Autoencoder-Datensatz ist bereits in 50000 Bilder für das Training und 10000 für das Testen aufgeteilt. Es gibt bis zu zehn Klassen:

  • Flugzeug
  • Automobil
  • Vogel
  • Katze
  • Hirsch
  • Hund
  • Frosch
  • Pferd
  • Schiff
  • LKW

Sie müssen die Bilder von der CIFAR-10-Datensatzseite und entpacken Sie das Archiv. Der Ordner cifar-10-batches-py enthält fünf Datenpakete mit jeweils 10000 Bildern in zufälliger Reihenfolge.

Bevor Sie Ihr Modell erstellen und trainieren, müssen Sie einige Datenverarbeitungsvorgänge durchführen. Sie gehen wie folgt vor:

  1. Importieren Sie die Daten
  2. Konvertieren Sie die Daten in das Schwarzweißformat
  3. Hängen Sie alle Stapel an
  4. Konstruieren Sie den Trainingsdatensatz
  5. Konstruieren Sie einen Bildvisualisierer

Versionshinweis: Der Code in diesem Tutorial ist für TensorFlow 1.x ausgelegt. In TensorFlow 2 existiert das Modul `tf.contrib` nicht mehr; Platzhalter, Sitzungen und der initialisierbare Iterator befinden sich unter `tf.compat.v1`. Der schnellste Weg, die Listings unverändert auszuführen, ist der Aufruf von `tf.compat.v1.disable_v2_behavior()` nach dem Import.

Bildvorverarbeitung

Schritt 1) ​​Importieren Sie die Daten

Laut der offiziellen Website können Sie die Daten mit dem folgenden Code hochladen. Der Autoencoder-Code lädt die Daten in ein Dictionary, das die Daten und die zugehörigen Labels enthält. Beachten Sie, dass es sich bei dem Code um eine Funktion handelt.

import numpy as np
import tensorflow as tf
import pickle
def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='latin1')
    return dict

Schritt 2) Konvertieren Sie die Daten in das Schwarzweißformat

Der Einfachheit halber konvertieren Sie die Daten in Graustufen. Das heißt, mit nur einer Dimension gegenüber drei für das Farbbild. Die meisten neuronalen Netzwerke funktionieren nur mit einer eindimensionalen Eingabe.

def grayscale(im):
    return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)

Schritt 3) Hängen Sie alle Stapel an

Nachdem beide Funktionen erstellt und der Datensatz geladen wurden, können Sie eine Schleife schreiben, um die Daten im Speicher anzuhängen. Die entpackte Datei mit den Daten heißt „data_batch_“ und trägt eine Nummer von 1 bis 5. Sie können die Dateien durchlaufen und die Daten jeweils an die Variable „data“ anhängen.

Nach diesem Schritt werden die Farbdaten in ein Graustufenformat umgewandelt. Wie Sie sehen, haben die Daten die Dimensionen 50000 und 1024. Die 32x32 Pixel wurden nun auf 1024 reduziert.

# Load the data into memory
data, labels = [], []
## Loop over the b
for i in range(1, 6):
    filename = './cifar-10-batches-py/data_batch_' + str(i)
    open_data = unpickle(filename)
    if len(data) > 0:
        data = np.vstack((data, open_data['data']))
        labels = np.hstack((labels, open_data['labels']))
    else:
        data = open_data['data']
        labels = open_data['labels']

data = grayscale(data)
x = np.matrix(data)
y = np.array(labels)
print(x.shape)
(50000, 1024)

Hinweis: Ändern Sie './cifar-10-batches.py/data_batch_' in den tatsächlichen Speicherort Ihrer Datei. Zum Beispiel für eine Windows Maschine, der Pfad könnte sein: filename = 'E:\cifar-10-batches-py\data_batch_' + str(i)

Schritt 4) Erstellen Sie den Trainingsdatensatz

Um das Training zu beschleunigen und zu vereinfachen, trainieren Sie ein Modell ausschließlich mit den Pferdebildern. Die Pferde tragen in den Labeldaten die Kennzeichnung 7. Wie in der Dokumentation des CIFAR-10-Datensatzes erwähnt, enthält jede Klasse 5000 Bilder. Sie können die Datenstruktur ausgeben, um zu bestätigen, dass es 5,000 Bilder mit 1024 Spalten gibt, wie im folgenden Beispielschritt des TensorFlow Autoencoders gezeigt.

horse_i = np.where(y == 7)[0]
horse_x = x[horse_i]
print(np.shape(horse_x)) 
(5000, 1024)

Schritt 5) Erstellen Sie einen Bildvisualisierer

Schließlich erstellen Sie eine Funktion zum Plotten der Bilder. Sie benötigen diese Funktion, um das rekonstruierte Bild vom Autoencoder zu drucken.

Eine einfache Möglichkeit, Bilder auszugeben, bietet die Funktion `imshow()` aus der Matplotlib-Bibliothek. Beachten Sie, dass Sie die Datenform von 1024 in 32x32 (Bildformat) konvertieren müssen.

# To plot pretty figures
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
def plot_image(image, shape=[32, 32], cmap = "Greys_r"):
    plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest")
    plt.axis("off")   

Die Funktion benötigt 3 Argumente:

  • Bild: die Eingabe
  • Form: Liste, die Dimension des Bildes
  • Cmap: Farbpalette auswählen. Standardmäßig Grau.

Sie können versuchen, das erste Bild im Datensatz darzustellen. Sie sollten einen Mann auf einem Pferd sehen.

plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")

Der Aufruf liefert das untenstehende Graustufen-Miniaturbild zurück und bestätigt, dass die Umformung von 1024 Werten zurück zu einem 32×32 Bild korrekt ist.

Graustufen-Miniaturansicht eines Reiters auf einem Pferd (32x32 CIFAR-10), erstellt mit plot_image()

Stellen Sie den Datensatzschätzer ein

Okay, jetzt, da der Datensatz einsatzbereit ist, können Sie mit TensorFlow arbeiten. Bevor Sie das Modell erstellen, verwenden Sie den Dataset-Estimator von TensorFlow, um das Netzwerk zu trainieren.

Sie erstellen einen Datensatz mit dem TensorFlow-Schätzer. Um Ihren Geist zu erfrischen, müssen Sie Folgendes verwenden:

  • from_tensor_slices
  • wiederholen
  • Portion

Der vollständige Code zum Erstellen des Datensatzes lautet:

dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)

Beachten Sie, dass x ein Platzhalter der Form [None,n_inputs] ist. Die erste Dimension ist auf None gesetzt, da die Anzahl der dem Netzwerk zugeführten Bilder der Batchgröße entspricht, die erst zur Laufzeit festgelegt wird. Weitere Details finden Sie im Tutorial unter [Link einfügen]. Lineare Regression mit TensorFlow.

Danach müssen Sie den Iterator erstellen. Ohne diese Codezeile werden keine Daten durch die Pipeline geleitet.

iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()

Da die Pipeline nun fertig ist, können Sie überprüfen, ob das erste Bild dasselbe wie zuvor ist (z. B. ein Mann auf einem Pferd).

Sie haben die Batchgröße auf 1 gesetzt, da Sie dem Datensatz nur ein Bild zuführen möchten. Die Dimension der Daten können Sie mit `print(sess.run(features).shape)` anzeigen. Sie beträgt (1, 1024). Die 1 bedeutet, dass jeweils ein einzelnes Bild mit 1024 Werten verarbeitet wird. Bei einer Batchgröße von 2 durchlaufen zwei Bilder die Pipeline. Ändern Sie die Batchgröße nicht, da sonst ein Fehler auftritt, weil die Funktion `plot_image()` immer nur ein Bild gleichzeitig verarbeiten kann.

## Parameters
n_inputs = 32 * 32
BATCH_SIZE = 1
batch_size = tf.placeholder(tf.int64)

# using a placeholder
x = tf.placeholder(tf.float32, shape=[None,n_inputs])
## Dataset
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
iter = dataset.make_initializable_iterator() # create the iterator
features = iter.get_next()

## Print the image
with tf.Session() as sess:
    # feed the placeholder with data
    sess.run(iter.initializer, feed_dict={x: horse_x,
                                         batch_size: BATCH_SIZE}) 
    print(sess.run(features).shape) 
    plot_image(sess.run(features), shape=[32, 32], cmap = "Greys_r")
(1, 1024)

Die Pipeline gibt denselben Rider zurück, der direkt aus der NumPy-Matrix geplottet wurde, was beweist, dass der Platzhalter, der Iterator und die Batchgröße korrekt verbunden sind.

Dasselbe Pferde-Thumbnail wird ausgegeben, nachdem das Bild den TensorFlow Dataset-Iterator durchlaufen hat.

Bauen Sie das Netzwerk auf

Es ist Zeit, das Netzwerk aufzubauen. Sie trainieren einen gestapelten Autoencoder, also ein Netzwerk mit mehreren verborgenen Schichten.

Ihr Netzwerk wird eine Eingabeschicht mit 1024 Punkten haben, d.h. 32×32, entsprechend der Form des Bildes.

Der Encoder-Block besteht aus einer verborgenen Schicht mit 300 Neuronen und einer zentralen Schicht mit 150 Neuronen. Der Decoder-Block ist symmetrisch zum Encoder aufgebaut. Das Netzwerk ist im folgenden Diagramm dargestellt. Die Werte der verborgenen und zentralen Schicht können angepasst werden.

Symmetrische Autoencoder-Architektur mit 1024 Eingängen, 300 und 150 Encoder-Schichten und einem gespiegelten Decoder

Aufbau des Netzwerks für Autoencoder

Der Aufbau eines Autoencoders ist jedem anderen Deep-Learning-Modell sehr ähnlich.

Sie erstellen das Modell in den folgenden Schritten:

  1. Definieren Sie die Parameter
  2. Definieren Sie die Ebenen
  3. Definieren Sie die Architektur
  4. Definieren Sie die Optimierung
  5. Führen Sie das Modell aus
  6. Bewerten Sie das Modell

Im vorherigen Abschnitt haben Sie gelernt, wie Sie eine Pipeline zur Eingabe der Daten in das Modell erstellen. Daher ist es nicht nötig, den Datensatz erneut anzulegen. Sie konstruieren einen Autoencoder mit vier Schichten. Sie verwenden die Xavier-Initialisierung. Diese Technik legt die Anfangsgewichte anhand der Varianz von Eingabe und Ausgabe fest. Abschließend verwenden Sie die ELU-Aktivierungsfunktion. Die Verlustfunktion wird mit einem L2-Regularisierer regularisiert.

Schritt 1) ​​Definieren Sie die Parameter

Der erste Schritt besteht darin, die Anzahl der Neuronen in jeder Schicht, die Lernrate und den Hyperparameter des Regularisierers zu definieren.

Zuvor importieren Sie die Funktion `partial`. Dies ist eine bessere Methode, um die Parameter der Dense-Layer zu definieren. Der folgende Code definiert die Werte der Autoencoder-Architektur. Wie bereits erwähnt, verfügt der Encoder über zwei Layer mit 300 Neuronen im ersten und 150 im zweiten Layer. Ihre Werte werden in `n_hidden_1` und `n_hidden_2` gespeichert.

Sie müssen die Lernrate und den L2-Hyperparameter definieren. Die Werte werden in learning_rate und l2_reg gespeichert.

from functools import partial

## Encoder
n_hidden_1 = 300
n_hidden_2 = 150  # codings

## Decoder
n_hidden_3 = n_hidden_1
n_outputs = n_inputs

learning_rate = 0.01
l2_reg = 0.0001

Die Xavier-Initialisierungstechnik wird mit dem Objekt `xavier_initializer` aus dem Estimator `contrib` aufgerufen. Im selben Estimator kann der Regularisierer mit `l2_regularizer` hinzugefügt werden.

## Define the Xavier initialization
xav_init =  tf.contrib.layers.xavier_initializer()
## Define the L2 regularizer
l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)

Versionshinweis: tf.contrib wurde in TensorFlow 2 entfernt. Die direkten Ersatzfunktionen sind tf.keras.initializers.GlorotUniform() für xavier_initializer() und tf.keras.regularizers.l2() für l2_regularizer().

Schritt 2) Definieren Sie die Ebenen

Alle Parameter der Dense-Layer sind festgelegt; Sie können alles in der Variable `dense_layer` mithilfe des Objekts `partial` bündeln. `dense_layer` verwendet dann bei jedem Aufruf die ELU-Aktivierung, die Xavier-Initialisierung und die L2-Regularisierung.

## Create the dense layer
dense_layer = partial(tf.layers.dense,
                         activation=tf.nn.elu,
                         kernel_initializer=xav_init,
                         kernel_regularizer=l2_regularizer)

Schritt 3) Definieren Sie die Architektur

Betrachtet man das Architekturdiagramm, fällt auf, dass das Netzwerk aus drei Schichten und einer Ausgabeschicht besteht. Im folgenden Code werden die entsprechenden Schichten verbunden. Die erste Schicht berechnet beispielsweise das Skalarprodukt der Eingabematrixmerkmale mit der Matrix der 300 Gewichte. Nach der Berechnung des Skalarprodukts wird die Ausgabe an die ELU-Aktivierungsfunktion übergeben. Die Ausgabe dient als Eingabe für die nächste Schicht, weshalb sie zur Berechnung von hidden_2 usw. verwendet wird. Die Matrixmultiplikation ist für jede Schicht identisch, da dieselbe Aktivierungsfunktion verwendet wird. Die letzte Schicht, die Ausgabeschicht, wendet keine Aktivierungsfunktion an. Dies ist sinnvoll, da es sich hier um die rekonstruierte Eingabe handelt.

## Make the mat mul
hidden_1 = dense_layer(features, n_hidden_1)
hidden_2 = dense_layer(hidden_1, n_hidden_2)
hidden_3 = dense_layer(hidden_2, n_hidden_3)
outputs = dense_layer(hidden_3, n_outputs, activation=None)

Schritt 4) Optimierung definieren

Der letzte Schritt ist die Konstruktion des Optimierers. Als Verlustfunktion wird der mittlere quadratische Fehler (MSE) verwendet. Wie Sie vielleicht aus dem Tutorial zur linearen Regression wissen, berechnet sich der MSE aus der Differenz zwischen dem vorhergesagten Wert und dem tatsächlichen Wert. Hierbei ist der Wert das Merkmal, da das Modell versucht, die Eingabe zu rekonstruieren. Daher benötigen Sie den Mittelwert der Summe der quadrierten Differenzen zwischen vorhergesagtem Wert und Eingabe. Mit TensorFlow können Sie die Verlustfunktion wie folgt kodieren:

loss = tf.reduce_mean(tf.square(outputs - features))

Anschließend muss die Verlustfunktion optimiert werden. Zur Berechnung der Gradienten wird der Adam-Optimierer verwendet. Die Zielfunktion besteht darin, den Verlust zu minimieren.

## Optimize
loss = tf.reduce_mean(tf.square(outputs - features))
optimizer = tf.train.AdamOptimizer(learning_rate)
train  = optimizer.minimize(loss)

Noch eine Einstellung vor dem Training des Modells. Sie möchten eine Stapelgröße von 150 verwenden, d. h. die Pipeline mit 150 Bildern pro Iteration versorgen. Sie müssen die Anzahl der Iterationen manuell berechnen. Dies ist trivial:

Wenn Sie jeweils 150 Bilder verarbeiten möchten und wissen, dass der Datensatz 5000 Bilder enthält, entspricht die Anzahl der Iterationen 5000 geteilt durch 150. Python Sie können die folgenden Codes ausführen und sicherstellen, dass die Ausgabe 33 lautet:

BATCH_SIZE = 150
### Number of batches :  length dataset / batch size
n_batches = horse_x.shape[0] // BATCH_SIZE
print(n_batches)
33

Schritt 5) Führen Sie das Modell aus.

Zu guter Letzt trainieren Sie das Modell. Sie trainieren das Modell über 100 Epochen. Das heißt, das Modell sieht die Bilder 100 Mal und optimiert dabei die Gewichte.

Sie kennen bereits die Codes zum Trainieren eines Modells in TensorFlow. Der kleine Unterschied besteht darin, die Daten vor dem Training zu verarbeiten. Dadurch wird das Modell schneller trainiert.

Sie möchten den Verlust nach zehn Epochen ausdrucken, um zu sehen, ob das Modell etwas lernt (dh der Verlust abnimmt). Die Schulung dauert je nach Maschinenhardware 2 bis 5 Minuten.

## Set params
n_epochs = 100

## Call Saver to save the model and re-use it later during evaluation
saver = tf.train.Saver()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # initialise iterator with train data
    sess.run(iter.initializer, feed_dict={x: horse_x,
                                          batch_size: BATCH_SIZE})
    print('Training...')
    print(sess.run(features).shape) 
    for epoch in range(n_epochs):       
        for iteration in range(n_batches):
            sess.run(train)
        if epoch % 10 == 0:
            loss_train = loss.eval()   # not shown
            print("\r{}".format(epoch), "Train MSE:", loss_train) 
        #saver.save(sess, "./my_model_all_layers.ckpt") 
    save_path = saver.save(sess, "./model.ckpt")    
    print("Model saved in path: %s" % save_path)  
Training...
(150, 1024)
0 Train MSE: 2934.455
10 Train MSE: 1672.676
20 Train MSE: 1514.709
30 Train MSE: 1404.3118
40 Train MSE: 1425.058
50 Train MSE: 1479.0631
60 Train MSE: 1609.5259
70 Train MSE: 1482.3223
80 Train MSE: 1445.7035
90 Train MSE: 1453.8597
Model saved in path: ./model.ckpt

Schritt 6) Bewerten Sie das Modell

Nachdem Ihr Modell trainiert wurde, ist es nun an der Zeit, es zu evaluieren. Sie müssen dazu den Testdatensatz aus der Datei /cifar-10-batches-py/ importieren.

test_data = unpickle('./cifar-10-batches-py/test_batch')
test_x = grayscale(test_data['data'])
#test_labels = np.array(test_data['labels'])

Hinweis: Für einen Windows Maschine wird der Code zu test_data = unpickle(r“E:\cifar-10-batches-py\test_batch“)

Sie können versuchen, Bild 13 auszudrucken, das ein Pferd zeigt.

plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")

Die Grafik bestätigt, dass der Testdatensatz korrekt geladen wurde und dass Bild 13 zu der Klasse gehört, mit der das Modell trainiert wurde.

Testbild Nummer 13 aus der CIFAR-10-Testreihe, das ein Pferd in Graustufen zeigt.

Zur Evaluierung des Modells verwenden Sie den Pixelwert dieses Bildes und prüfen, ob der Encoder dasselbe Bild nach der Verkleinerung auf 1024 Pixel rekonstruieren kann. Beachten Sie, dass Sie eine Funktion definieren, um das Modell anhand verschiedener Bilder zu evaluieren. Das Modell sollte nur bei Pferden besser funktionieren.

Die Funktion benötigt zwei Argumente:

  • df: Testdaten importieren
  • Bildnummer: Gibt an, welches Bild importiert werden soll.

Die Funktion gliedert sich in drei Teile:

  1. Formen Sie das Bild auf die richtige Dimension um, z. B. 1, 1024
  2. Füttere das Modell mit dem unsichtbaren Bild und kodiere/dekodiere das Bild
  3. Drucken Sie das echte und rekonstruierte Bild
def reconstruct_image(df, image_number = 1):
    ## Part 1: Reshape the image to the correct dimension i.e 1, 1024
    x_test = df[image_number]
    x_test_1 = x_test.reshape((1, 32*32))
    
    ## Part 2: Feed the model with the unseen image, encode/decode the image
    with tf.Session() as sess:     
        sess.run(tf.global_variables_initializer()) 
        sess.run(iter.initializer, feed_dict={x: x_test_1,
                                      batch_size: 1})
    ## Part 3:  Print the real and reconstructed image
      # Restore variables from disk.
        saver.restore(sess, "./model.ckpt")  
        print("Model restored.")
      # Reconstruct image
        outputs_val = outputs.eval()
        print(outputs_val.shape)
        fig = plt.figure()
      # Plot real
        ax1 = fig.add_subplot(121)
        plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r")
      # Plot estimated
        ax2 = fig.add_subplot(122)
        plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r")
        plt.tight_layout()
        fig = plt.gcf()

Nachdem die Auswertungsfunktion nun definiert ist, können Sie sich das rekonstruierte Bild Nummer dreizehn ansehen.

reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt
Model restored.
(1, 1024)

Die Abbildung zeigt das ursprüngliche Testbild links und die Ausgabe des Autoencoders rechts, sodass der Verlust feiner Details nach der Komprimierung von 1024 auf 150 leicht zu beurteilen ist.

Direkter Vergleich des Originalbildes des Pferdes und der unschärferen Autoencoder-Rekonstruktion.

Häufig gestellte Fragen

Beide Verfahren reduzieren die Dimensionalität, jedoch ist die PCA auf lineare Projektionen beschränkt. Ein Autoencoder kombiniert nichtlineare Aktivierungsfunktionen wie ELU und erfasst so gekrümmte Strukturen, die die PCA nicht erfasst. Mit einer einzigen linearen Schicht und dem quadratischen Fehler reproduziert ein Autoencoder die PCA nahezu exakt.

Nicht unverändert. Das tf.contrib-Modul wurde entfernt, und Platzhalter und Sitzungen wurden nach tf.compat.v1 verschoben. Das Hinzufügen von disable_v2_behavior() ermöglicht eine schnelle Portierung der Listings, während eine native TensorFlow 2. Neuschreiben verwendet tf.keras.layers.Dense mit GlorotUniform-Initialisierung.

Automatisierte Suchwerkzeuge testen zahlreiche Codierungsschichtbreiten, Aktivierungszahlen und Regularisierungsstärken deutlich schneller als die manuelle Optimierung und ordnen die Ergebnisse anschließend nach Rekonstruktionsfehler. Sie verkürzen die Suche, wobei jedoch weiterhin ein Mensch überprüft, ob die Rekonstruktionen für die vorliegenden Daten plausibel erscheinen.

Ja. GitHub-Copilot Entwirft die Symmetrie von Encoder und Decoder, die Trainingsschleife und die Plot-Hilfsfunktion anhand eines kurzen Kommentars und entfernt so den größten Teil des Boilerplate-Codes. Überprüfen Sie die Tensorformen und die Verlustdefinition selbst, da der generierte Code häufig Syntax von TensorFlow 1 und 2 vermischt.

Beginnen Sie mit etwa zehn bis zwanzig Prozent der Eingabebreite, wie es die 150-Einheiten-Schicht hier bei 1024 Pixeln tut. Zu wenige Einheiten führen zu verschwimmenden Details, während zu viele dazu führen, dass das Netzwerk die Eingabe kopiert, anstatt einen kompakten Code zu lernen.

Die Graustufenkonvertierung reduziert drei Farbkanäle auf einen und damit die Anzahl der Eingangswerte von 3072 auf 1024. Das Training läuft schneller, die dichten Schichten bleiben klein, und die Rekonstruktionsaufgabe zeigt weiterhin deutlich, was der Autoencoder gelernt hat.

Die Anzahl der gedruckten Einträge sinkt bis zur Epoche 30 von 2,934 auf etwa 1,404 und oszilliert dann zwischen 1,425 und 1,609. Eine feste Lernrate von 0.01 überschreitet an diesem Punkt das Minimum – eine Senkung der Lernrate oder das Hinzufügen eines Abklingplans führt in der Regel zu weiteren Fortschritten.

Zu den Produktionsanwendungen gehören die Anomalieerkennung in Serverprotokollen und Transaktionen, wobei ein hoher Rekonstruktionsfehler einen Ausreißer kennzeichnet, sowie Empfehlungseinbettungen, Rauschunterdrückung von Sensoren und das Vortraining von Merkmalen.tracTors, die einen nachgelagerten Klassifikator speisen.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: