Dezember 2018
Band 33, Nummer 12
Test Run: Autoencoders für die Visualisierung mit CNTK
Durch James McCaffrey
Nehmen wir an, dass Sie über Daten verfügen, die eine Reihe von Personen zu beschreiben. Jede Person wird durch eine Alter und einen Höhenwert dargestellt. Wenn Sie Ihre Daten grafisch darstellen möchten konnte Sie put Age auf der y-Achse, Höhe, auf der y-Achse und verwenden farbige Punkte als (z. B. "Blau" für "Männlich") "und" Folgendes ein: rosa für Weiblich. Die Daten haben nur zwei Dimensionen, gibt es also kein Problem.
Aber was geschieht, wenn Ihre Daten sechs über Dimensionen verfügt, z. B. Alter, Höhe, Gewicht, Einkommen, Schulden, Postleitzahl? Ein Ansatz werden, um solche Daten grafisch darstellen, die sechs-dimensionalen Daten auf zwei Dimensionen, die mit einem neuronalen Netzwerk Autoencoder zusammenfassen. Sie können einige Informationen gehen verloren, aber ein Direct2D-Diagramm erstellen können.
Wenn Sie erfahren möchten, womit sich dieser Artikel beschäftigt, werfen Sie am besten einen Blick auf das Demoprogramm in Abbildung 1. Die Demodaten hat 1,797 Elemente. Jedes Element verfügt über 64 Dimensionen und fällt in eine der 10 Klassen. Das Demoprogramm erstellt ein neuronales Netzwerk Autoencoder Microsoft Cognitive Toolkit (CNTK), um jedes Element auf zwei Dimensionen, die mit der Bezeichnung component1 und componet2, zusammenfassen und stellt dann das Ergebnis. Interessante Muster in den Daten auf den Markt kommen. Beispielsweise sind die Datenelemente, die Klasse 0 (schwarze Punkte) werden sich maßgeblich von der 7 Klassenelemente (orangefarbene Punkte). Aber 8-Klassenelemente (rote Punkte) viel Ähnlichkeit mit der 5 Klassenelemente (hell Grün Punkte).
Abbildung 1 Autoencoder-Visualisierung mithilfe von CNTK: Demoausführung
In diesem Artikel wird vorausgesetzt, Sie verfügen über mittlere oder fortgeschrittene besseres Programmierungsmodell Kenntnisse in einer C-Sprache und mit Machine Learning vertraut sind, aber nicht voraus, dass Sie irgendetwas über Autoencoders wissen. Alle der Democode ist in diesem Artikel vorgestellten. Den vollständigen Quellcode und die Datendatei, die im Demoprogramm verwendet stehen außerdem in den Download, der diesen Artikel begleitet. Die übliche fehlerprüfung wurde entfernt, um die hauptideen so klar wie möglich zu halten.
Verstehen der Daten
Die Demodaten sieht folgendermaßen aus:
0,0,0,1,11,0,0,0,0,0,0,7,8, ... 16,4,0,0,4
0,0,9,14,8,1,0,0,0,0,12,14, ... 5,11,1,0,8
...
1,797 Datenelemente, und zwar eine(n) pro Zeile, vorhanden sind, und jede Zeile verfügt über 65 durch Trennzeichen getrennten Werten. Jede Datenzeile stellt eine 8 x 8 Grobes handgeschriebene Ziffern dar. Die ersten 64 Werte in einer Zeile sind Graustufen-Pixel-Werten zwischen 0 und 16. Der letzte Wert in einer Zeile ist Ziffernwert, damit das erste Element Pixelwerte hat, die eine "4" darstellt und das zweite Element hat Pixelwerte für ein "8".
Das Ziel der Demo Autoencoder werden 64 Dimensionen des ein Datenelement auf nur zwei Werte zu reduzieren, sodass das Element als Punkt in einem Diagramm für die x-und y-dargestellt werden kann. Obwohl die Demodaten ein Bild darstellt, können Autoencoders mit jeder Art von hoher Dimensionalität numerische Daten arbeiten.
Die Demodaten, heißt das UCI-Ziffern-Dataset, und finden Sie unter bit.ly/2xDW3IY, oder klicken Sie in den Dateidownload, der diesen Artikel begleitet.
Installieren von CNTK
Microsoft CNTK ist eine leistungsstarke open-Source-neural Network-Codebibliothek. CNTK in C++ geschrieben ist, für die Leistung, aber Sie verfügt über eine Python-API zur Vereinfachung und integritätsprüfung. CNTK als eigenständiges System wird nicht installiert. Zuerst installieren Sie eine Verteilung von Python, die den Kern-Python-Interpreter und mehrere Hundert weitere Pakete enthält. Danach installieren Sie CNTK als Python-Add-On-Paket.
Installieren von CNTK kann schwierig sein. Für die Demo installiert ich zunächst die Anaconda3 4.1.1 Verteilung für Windows, repo.continuum.io/archive die schöne selbstextrahierende ausführbare Datei verwenden. Die Verteilung enthält Python 3.5.2 und mehrere Pakete, die von CNTK erforderlich.
Als Nächstes CNTK v2. 4 durch Herunterladen der kompatiblen installiert reine CPU-(Mein Computer verfügt nicht über eine GPU) CNTK whl-Datei mit meinem lokalen Computer aus bit.ly/2OfCCQg. Klicken Sie dann eine Befehlsshell geöffnet ich, zu dem Verzeichnis, enthält die CNTK-whl-Datei navigiert sind, und den Befehl eingegeben:
> pip install cntk-2.4-cp35-cp35m-win_amd64.whl
Wenn Sie mit Python vertraut sind, können Sie eine .whl-Datei als etwas Ähnliches wie eine MSI-Installationsdatei und Pip als etwas Ähnliches wie das Windows Installer-Programm lose vorstellen. Python ist im Hinblick auf die versionsverwaltung, sehr fehleranfällig, daher Sie sehr darauf achten, kompatible Versionen von Anaconda Python und CNTK zu installieren müssen. Die große Mehrheit von CNTK-Installationsprobleme, die ich sehe hängen direkt zusammen, um Inkompatibilitäten der Versionen.
Das Demoprogramm
Die Struktur des Demoprogramms mit einigen kleinen Bearbeitungen, um Platz zu sparen wird angezeigt, in der Auflistung in abbildung2. Ich einrücken mit zwei Leerzeichen anstelle der üblichen vier Leerzeichen, um Platz zu sparen. Und beachten Sie, dass Python das Zeichen "\" für die zeilenfortsetzung verwendet. Ich habe verwendet Editor so bearbeiten Sie das Programm an. Die meisten meiner Kollegen bevorzugen einen höher entwickelten-Editor, aber ich danke Ihnen für die Einfachheit des Editors.
Abbildung 2: Struktur des Demoprogramms für Autoencoder
# digits_autoenc.py
# condense the UCI digits to two dimensions
# CNTK 2.4 Anaconda3 4.1.1 (Python 3.5.2)
import numpy as np
import cntk as C
import matplotlib.pyplot as plt
def main():
# 0. get started
print("Begin UCI digits autoencoder with CNTK demo ")
np.random.seed(1)
# 1. load data into memory
# 2. define autoencoder
# 3. train model
# 4. generate (x,y) pairs for each data item
# 5. graph the data in 2D
print("End autoencoder using CNTK demo ")
if __name__ == "__main__":
main()
Das Demoprogramm digits_autoenc.py Namen, und es beginnt mit der die NumPy "," CNTK "und" Pyplot Pakete importieren. NumPy ermöglicht grundlegende numerische Vorgänge in Python und Pyplot wird verwendet, um dargestellt im Punktdiagramm zeigt Abbildung1. Nachdem eine Nachricht starten beginnt die programmausführung durch die globale NumPy zufälliger Ausgangswert festlegen, damit Ergebnisse reproduziert werden können.
Die Demo lädt die Trainingsdaten im Arbeitsspeicher, die mithilfe der NumPy Loadtxt-Funktion:
data_file = ".\\Data\\digits_uci_test_1797.txt"
data_x = np.loadtxt(data_file, delimiter=",",
usecols=range(0,64), dtype=np.float32)
labels = np.loadtxt(data_file, delimiter=",",
usecols=[64], dtype=np.float32)
data_x = data_x / 16
Der Code wird davon ausgegangen, dass die Daten in ein Unterverzeichnis namens Daten gespeichert sind. Die Loadtxt-Funktion weist viele optionale Parameter. In diesem Fall gibt der Funktionsaufruf an, dass die Daten durch Trennzeichen getrennte. Der float32-Datentyp ist die Standardeinstellung für CNTK, damit ich auslasse, kann er explizit angeben. Das Data_x-Objekt enthält alle 1,797 Zeilen der 64-Pixel-Werte, und das Objekt für die Bezeichnungen enthält, die entsprechenden Klassenwerte für die 10. Das Objekt Data_x wird geändert, durch Division durch 16, sodass alle Pixelwerte zwischen 0,0 und 1,0 skaliert werden.
Definieren der Autoencoder
Das Demoprogramm erstellt ein 64-32-2-32-64 Modell des neuronalen Netzwerks Autoencoder mit diesen Anweisungen:
my_init = C.initializer.glorot_uniform(seed=1)
X = C.ops.input_variable(64, np.float32) # inputs
layer1 = C.layers.Dense(32, init=my_init,
activation=C.ops.sigmoid)(X)
layer2 = C.layers.Dense(2, init=my_init,
activation=C.ops.sigmoid)(layer1)
layer3 = C.layers.Dense(32, init=my_init,
activation=C.ops.sigmoid)(layer2)
layer4 = C.layers.Dense(64, init=my_init,
activation=C.ops.sigmoid)(layer3)
Das Initialisierungsobjekt gibt den Glorot Algorithmus an, die häufig eine bessere Leistung als eine gleichmäßige Verteilung bei Tiefen neuronalen Netzwerken funktioniert. Die X-Objekt wird zum Speichern von 64 der Eingabewerten eingerichtet. Die nächsten vier Ebenen erstellen eine Autoencoder, Crunches 64 Eingabewerte auf 32-Werte, und verarbeitet dann die auf nur zwei Werten. Ein Autoencoder ist eine spezielle Form von einem Encoder / Decoder-Netzwerk. Das Diagramm in Abbildung 3 Autoencoder Architektur veranschaulicht.
Abbildung 3 Autoencoder-Architektur
Zu klein ist, behalten Sie die Größe des Diagramms Abbildung 3 zeigt ein 6-3-2-3-6 Autoencoder statt der 64-32-2-32-64-Architektur der Demo Autoencoder.
Beachten Sie, dass die Ausgabewerte identisch sind, da die Eingabewerte, damit die Autoencoder lernt, eigene Eingaben vorhergesagt. Der Decoderteil des der Autoencoder erweitert die beiden Werte in der mittleren Ebene Sicherung auf die ursprünglichen 64 Werte. Ergebnis ist jedoch, dass jedes Datenelement für die 64-dimensionalen auf nur zwei Werten zugeordnet ist. Um diese Werte erhalten das Demoprogramm definiert:
enc_dec = C.ops.alias(layer4)
encoder = C.ops.alias(layer2)
In Worten ausgedrückt der Encoder-Decoder akzeptiert die Werte in der X-Objekt und generiert eine Ausgabe in Schicht Schicht 4 mit 64 Knoten. Der Encoder die Werte in der X-Objekt akzeptiert und generiert eine Ausgabe in der Schicht-2 mit zwei Knoten.
Die Demo verwendet sigmoidaktivierung auf allen Ebenen. Dies führt dazu, dass alle zwischen 0,0 und 1,0 Inner-Ebene-Knoten. Es gibt viele Entwurfsoptionen zur Verfügung, Autoencoders. Sie können in jeder Schicht unterschiedlich viele Ebenen von inneren und unterschiedlicher Anzahl von Knoten verwenden. Sie können eine anderen Aktivierungsfunktion, einschließlich der selten verwendeten linearen Funktion verwenden. Wenn Sie eine Autoencoder zur Verringerung der Dimensionalität für die datenvisualisierung zu verwenden, ist die Qualität der resultierenden Visualisierung subjektiv sein, daher Ihre Entwurfsoptionen hauptsächlich eine Frage der Versuch und Irrtum.
Trainieren der Autoencoder
Mithilfe dieser Anweisungen sieben Training vorbereitet:
Y = C.ops.input_variable(64, np.float32) # targets
loss = C.squared_error(enc_dec, Y)
learner = C.adam(enc_dec.parameters, lr=0.005, momentum=0.90)
trainer = C.Trainer(enc_dec, (loss), [learner])
N = len(data_x)
bat_size = 2
max_epochs = 10000
Die Y-Objekt enthält die gleichen Werte wie das X-Objekt, und die Training-Loss-Funktion vergleicht die Werte. Gibt an, die Demo quadratischen Fehler für die verlustfunktion, aber da ist jeden Wert zwischen 0,0 und 1,0 aufgrund der Verwendung der Funktion sigmoidaktivierung, Kreuzentropie-Fehlerfunktion kann verwendet.
Bei Tiefen neuronalen Netzen führt der Adam-Algorithmus (adaptive Moment Schätzung) häufig eine bessere Leistung als grundlegenden stochastischen gradientenverfahren. Das Learning Rate (0,005) und momentumwert (0,90) werden hyperparameter und muss durch Versuch und Irrtum ermittelt werden. Die Batchgröße (zwei) und maximale Anzahl der trainingsiterationen (10.000) sind ebenfalls hyperparameter.
Training erfolgt folgendermaßen:
for i in range(0, max_epochs):
rows = np.random.choice(N, bat_size, replace=False)
trainer.train_minibatch({ X: data_x[rows], Y: data_x[rows] })
if i > 0 and i % int(max_epochs/10) == 0:
mse = trainer.previous_minibatch_loss_average
print("epoch = " + str(i) + " MSE = %0.4f " % mse)
In jeder trainingsiteration wählt die random.choice-Funktion zwei Zeilen aus der 1,797 Zeilen mit Daten aus. Dies ist ein relativ primitiven Ansatz, da einige Zeilen häufiger als andere Zeilen ausgewählt werden können. Sie könnten eine anspruchsvolle Batchverarbeitung System, aber für Autoencoders der Ansatz der Demo ist einfach und effektiv.
Die Demo überwacht Schulungen durch die quadratische Abweichung Verlust anzeigen, auf den aktuellen Batch mit zwei Elementen, die alle 10.000 / 10 = 1.000 Epochen. Die Idee besteht darin, sicherzustellen, dass der Fehler ist während des Trainings verringern; Da jedoch die Batchgröße so klein ist, es ist einiges an Fluktuation des Verlusts während des Trainings.
Verwenden den Encoder
Nach dem Training das Demoprogramm generiert (X, y)-Paar für jede der 1,797 Datenelemente:
reduced = encoder.eval(data_x)
Der Rückgabewert ist eine Matrix mit 1,797 Zeilen und zwei Spalten. Jede Zeile stellt eine reduzierte Dimensionalität-Version der ursprünglichen Daten. Die Werte in beide Spalten sind zwischen 0,0 und 1,0, da die Autoencoder sigmoidaktivierung auf allen Ebenen verwendet.
Das Demoprogramm wird vorbereitet, die Visualisierung mit diesen Anweisungen:
print("Displaying 64-dim data in 2D: \n")
plt.scatter(x=reduced[:, 0], y=reduced[:, 1],
c=labels, edgecolors='none', alpha=0.9,
cmap=plt.cm.get_cmap('nipy_spectral', 10), s=20)
Die x- und y-Parameter der Funktion Punktdiagramm werden Werte für die x-Achse und y-Achse. Reduziert die Syntax [:, 0] bedeutet, dass alle Zeilen der Matrix, aber nur die erste Spalte. Der C-Parameter gibt die Farben an. In diesem Fall wird das Bezeichnungen-Objekt, und enthält alle von der 0 bis 9 Werte für jedes Datenelement an c übergeben.
Der alpha-Parameter gibt an, die Transparenzebene eines einzelnen Punkts Marker. Der Cmap-Parameter akzeptiert eine farbzuordnung. Die Werte "Nipy_spectral" und 10, 10 Werte aus einem spektrale Farbverlauf zu abzurufen, die zwischen 0 bedeutet = Schwarz, bis 4 = Green, 9 = grau. Die Pyplot-Bibliothek unterstützt viele verschiedene Farbzuordnungstypen an. Die s-Parameter ist die Größe der Marker aus Punkten, gemessen in Pixel.
Nach dem Festlegen der Punktdiagramm, das Demoprogramm wird abgeschlossen, z. B. so:
plt.xlabel('component 1')
plt.ylabel('component 2')
plt.colorbar()
print("End autoencoder using CNTK demo ")
plt.show()
if __name__ == "__main__":
main()
Die integrierten Colorbar-Funktion verwendet 10 Werte aus den Nipy_spectral Farbverlauf. Ein alternativer Ansatz ist die Verwendung die Funktion für die Legende.
Zusammenfassung
Es gibt mehrere alternative Ansätzen zur Verringerung der Dimensionalität für die datenvisualisierung. Principal Component Analysis (PCA) ist ein klassisches statistisches Verfahren, die seit Jahrzehnten verwendet wurde. Eine neuere Technik, die aus dem Jahr 2008, t verteilte stochastischen Nachbarn einbetten (t-SNE) wird aufgerufen, und es häufig funktioniert gut, aber nur mit relativ kleinen Datasets.
Autoencoders kann für andere Zwecke als für die datenvisualisierung die Verringerung der Dimensionalität verwendet werden. Beispielsweise können Sie eine Autoencoder verwenden, um Rauschen aus Bildern oder Dokumenten zu entfernen. Die Idee ist zum Reduzieren dieser Daten auf eine Art der wichtigsten Komponenten von Rauschen im Prozess entfernt, und erweitern dann auf die Daten zurück, was Bereinigung von Daten in gewisser Weise.
Dr. James McCaffreyist in Redmond (Washington, USA) für Microsoft Research tätig. Er arbeitet in mehreren wichtigen Microsoft-Produkten, einschließlich Internet Explorer und Bing. Dr. McCaffrey erreichen Sie unter jamccaff@microsoft.com.
Unser Dank gilt den folgenden Microsoft-Experten die Durchsicht dieses Artikels: Chris Lee, Ricky Loynd