Neuronale Netzwerke mit Keras auf Rescale

Blogvorlage 39

markblog
Rescale unterstützt nun die Ausführung einer Reihe von Softwarepaketen für neuronale Netzwerke, darunter das auf Theano basierende Keras. Keras ist ein Python-Paket, mit dem Benutzer ein neuronales Netzwerk Schicht für Schicht definieren, trainieren, validieren und anschließend zum Beschriften neuer Bilder verwenden können. In diesem Beitrag trainieren wir ein Faltungs-Neuronales Netzwerk (CNN) zur Klassifizierung von Bildern basierend auf CIFAR10 Datensatz. Dieses trainierte Modell verwenden wir dann zur Klassifizierung neuer Bilder.

Wir verwenden eine modifizierte Version des Keras CIFAR10 CNN-Trainingsbeispiel und beginnen damit, Schritt für Schritt unsere modifizierte Version des Trainingsskripts durchzugehen.

CIFAR10-Datensatz

Der CIFAR10-Bildklassifizierungsdatensatz kann heruntergeladen werden werden auf dieser Seite erläutert. Es besteht aus etwa 60000 Bildern im Format 32×32 Pixel, die jeweils einer von zehn Kategorien zugeordnet sind. Sie können entweder die Python-Version des Datensatzes direkt herunterladen oder den in Keras integrierten Datensatz-Downloader verwenden (mehr dazu später).

Wir werden diesen Datensatz mit dem folgenden Code laden:

von keras.datasets importiere cifar10 von keras.utils importiere np_utils nb_classes = 10 def load_dataset(): # die Daten, gemischt und aufgeteilt zwischen Trainings- und Testsätzen (X_train, y_train), (X_test, y_test) = cifar10.load_data() print('X_train shape:', X_train.shape) print(X_train.shape[0], 'train samples') print(X_test.shape[0], 'test samples') # konvertiere Klassenvektoren in binäre Klassenmatrizen Y_train = np_utils.to_categorical(y_train, nb_classes) Y_test = np_utils.to_categorical(y_test, nb_classes) X_train = X_train.astype('float32') X_test = X_test.astype('float32') X_train /= 255 X_test /= 255 return X_train, Y_train, X_test, Y_test

Wir benutzen die cifar10 Datenlader hier, der die Kategoriebezeichnungen in eine One-Hot-Kodierung konvertiert und dann die 8-Bit-RGB-Werte auf einen Bereich von 0 bis 1.0 skaliert.
Das X_Zug und X_test Die Ausgaben sind Numpy-Matrizen mit RGB-Pixelwerten für jedes Bild im Trainings- und Testsatz. Da es 50000 Trainingsbilder und 10000 Testbilder gibt und jedes Bild 32 x 32 Pixel mit drei Farbkanälen umfasst, ist die Form jeder Matrix wie folgt:

X_Zug(50000, 3, 32, 32)
Y_Zug(50000)
X_test(10000, 3, 32, 32)
Y_test(10000)

Die Y-Matrizen entsprechen einem Ordinalwert, der eine der 10 Bildklassen für die 50000- und 10000-Bildgruppen darstellt:

Flugzeug0
Auto1
Vogelarten2
Katze3
Hirsch4
Hund5
Frosch6
Pferd7
Schiff8
LKW9

Der Einfachheit halber führen wir in diesem Beispiel keine weitere Vorverarbeitung der korrekt dimensionierten Bilder durch. Bei einem realen Bilderkennungsproblem würden wir eine Art Normalisierung durchführen, ZCA-Bleachingund/oder Jittering. Keras integriert einen Teil dieser Vorverarbeitung mit der Bilddatengenerator Klasse.
Definieren des Netzwerks
Der nächste Schritt besteht darin, die Architektur des neuronalen Netzwerks zu definieren, das wir trainieren möchten:

von keras.models importiere Sequential von keras.layers.core importiere Dense, Dropout, Aktivierung, Flatten von keras.layers.convolutional importiere Convolution2D, MaxPooling2D def make_network(): model = Sequential() model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(img_channels, img_rows, img_cols))) model.add(Activation('relu')) model.add(Convolution2D(32, 3, 3)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Convolution2D(64, 3, 3, border_mode='same')) model.add(Activation('relu')) model.add(Convolution2D(64, 3, 3)) model.add(Aktivierung('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Aktivierung('relu')) model.add(Dropout(0.5)) model.add(Dense(nb_classes)) model.add(Aktivierung('softmax')) Modell zurückgeben

Dieses Netzwerk besteht aus 4 Faltungsschichten, gefolgt von 2 dichten Schichten. Weitere Schichten können hinzugefügt, entfernt oder geändert werden. Die erste Schicht muss jedoch die gleiche Größe wie ein Eingabebild (3, 32, 32) haben und die letzte dichte Schicht muss die gleiche Anzahl von Ausgaben wie die Anzahl der Klassen haben, die wir als Beschriftungen verwenden (10). Nach der letzten dichten Schicht folgt ein Softmax Schicht, die die Ausgabe auf einen (0, 1)-Bereich komprimiert, der sich zu 1 summiert.

Schulung und Prüfung
Als nächstes trainieren und testen wir das Netzwerk:

def train_model(Modell, X_Zug, Y_Zug, X_Test, Y_Test): sgd = SGD(lr=0.01, Zerfall=1e-6, Impuls=0.9, Nesterov=Wahr) model.compile(Verlust='kategoriale_Kreuzentropie', Optimierer=sgd) model.fit(X_Zug, Y_Zug, nb_Epoche=nb_Epoche, Batch_Größe=Batch_Größe, Validierungsaufteilung=0.1, Genauigkeit anzeigen=Wahr, ausführlich=1) drucken('Testen...') res = model.evaluate(X_Test, Y_Test, Batch_Größe=Batch_Größe, ausführlich=1, Genauigkeit anzeigen=Wahr) drucken('Testgenauigkeit: {0}'.format(res[1]))

Hier haben wir gewählt stochastischer Gradientenabstieg als unsere Optimierungsmethode mit einem Kreuzentropieverlust. Anschließend trainieren wir das Modell mit dem passen() Methode. Wir geben die Anzahl der Trainingsepochen (Wie oft wir die Daten durchlaufen) und die Größe unserer Batches (die Anzahl der gleichzeitig im Netzwerk auszuwertenden Eingaben) an. Größere Batches bedeuten einen höheren Speicherverbrauch während des Trainings. Nachdem unser Netzwerk trainiert ist, evaluieren wir das Modell anhand des Testdatensatzes und geben die Genauigkeit an.

Speichern des Modells
Abschließend speichern wir unser trainiertes Modell in Dateien, um es später wiederverwenden zu können:

def save_model(Modell): model_json = model.to_json() öffnen('cifar10_architecture.json', 'w').schreiben(model_json) model.save_weights('cifar10_weights.h5', überschreiben=Wahr)

Keras unterscheidet zwischen dem Speichern der Modellarchitektur (in unserem Fall, was ausgegeben wird von make_network()) und die trainierten Gewichte. Die Gewichte werden im HDF5-Format gespeichert.
Beachten Sie, dass Keras nicht garantiert, dass das gespeicherte Modell mit verschiedenen Versionen von Keras und Theano kompatibel ist. Wir empfehlen Ihnen, gespeicherte Modelle nach Möglichkeit mit derselben Version von Keras und Theano zu laden.

Rescale-Trainingsjob
Nachdem wir nun den Inhalt der cifar10_cnn.py Trainingsskript, das wir ausführen werden, erstellen wir einen Rescale-Job, um auf einem GPU-Knoten zu trainieren, der bereits für die Ausführung auf optimiert ist NVIDIA GPUsDieser Job ist öffentlich verfügbar auf Rescale. Zuerst laden wir das Trainingsskript und den CIFAR10-Datensatz hoch:
Trainings-Eingabedateien
Hier laden wir die vorverarbeitete Version der CIFAR10-Bilder hoch, wie sie von Keras heruntergeladen wurden, um zu vermeiden, dass der Datensatz bei jedem Job erneut von der CIFAR-Site heruntergeladen werden muss. Dieser Schritt ist optional. Wir könnten stattdessen einfach die cifar10_cnn.py Skripte.
Als nächstes wählen wir Keras aus und geben die Befehlszeile an:
Trainingssoftware
Wir wählen Keras aus der Softwareauswahl und anschließend die Theano-basierte K520-GPU-Version von Keras. Die Kommandozeile packt den hochgeladenen Datensatz neu und verschiebt das Archiv anschließend an den Standardspeicherort des Keras-Datensatzes unter ~/.keras/datasetsAnschließend wird das Trainingsskript aufgerufen. Wenn wir den CIFAR10-Satz nicht selbst hochladen möchten, können wir alle Befehle zur Archivbearbeitung weglassen und nur das Trainingsskript ausführen. Der Datensatz wird dann automatisch in den Job-Cluster heruntergeladen.
Im letzten Schritt wählen wir die GPU-Hardware aus, auf der wir laufen möchten:
Trainingshardware
Hier haben wir ausgewählt, Jade Kerntyp und die minimale 4 Kerne für diesen Typ. Senden Sie abschließend den Auftrag.
Es dauert etwa 15 Minuten, um den Cluster bereitzustellen und das Netzwerk zu kompilieren, bevor das Training beginnt. Sobald es beginnt, können Sie den Fortschritt verfolgen, indem Sie process_output.log.
Trainingsfortschritt
Sobald der Job abgeschlossen ist, können Sie Ihre trainierten Modelldateien verwenden. Sie können sie entweder von der Jobergebnisseite herunterladen oder in einem neuen Job verwenden, wie wir jetzt zeigen.

Klassifizieren neuer Bilder
Wir haben für unseren Trainingsjob einen vorverarbeiteten Datensatz im Numpy-Format verwendet. Was also tun wir, wenn wir echte Bilder aus dem Internet nehmen wollen? und diese klassifizieren? Da Hund und Katze sind 2 der 10 Klassen von Bilder, die in CIFAR10 dargestellt sind, wählen wir ein Hunde- und ein Katzenbild aus Internet und versuchen Sie, sie zu klassifizieren:
stehende Katze        Hundegesicht
Wir beginnen mit dem Laden und Verkleinern der Bilder:

importiere Numpy als np importiere scipy.misc def load_and_scale_imgs(): img_names = ['standing-cat.jpg', 'dog-face.jpg'] imgs = [np.transpose(scipy.misc.imresize(scipy.misc.imread(img_name), (32, 32)), (2, 0, 1)).astype('float32') für img_name in img_names] returniere np.array(imgs) / 255

Wir verwenden scipy's imlesen Laden Sie die JPGs und skalieren Sie die Bilder anschließend auf 32 x 32 Pixel. Der resultierende Bildtensor hat die Dimensionen (32, 32, 3), und wir möchten, dass die Farbdimension zuerst statt zuletzt steht, daher nehmen wir die Transponierung vor. Abschließend kombinieren wir die Liste der Bildtensoren zu einem einzigen Tensor und normalisieren die Werte wie zuvor auf einen Wert zwischen 0 und 1.0. Nach der Verarbeitung sind die Bilder kleiner:
stehende-katze-klein    Hundegesicht-klein
Beachten Sie, dass wir hier die einfachste Größenänderung durchgeführt haben, bei der nicht einmal das Seitenverhältnis des Originalbilds erhalten bleibt. Wenn wir die Trainingsbilder normalisiert hätten, würden wir diese Transformationen auch auf diese Bilder anwenden wollen.

Laden des Modells und Beschriften
Das Zusammensetzen des gespeicherten Modells erfolgt in zwei Schritten, wie hier gezeigt:

aus keras.models importiere model_from_json def load_model(model_def_fname, model_weight_fname): model = model_from_json(öffnen(model_def_fname).lesen()) model.load_weights(model_weight_fname) returniere model

Zusammenfassend nehmen wir das Modell, das wir geladen haben, und rufen Vorhersageklassen um die Klassenordinalwerte für unsere 2 Bilder zu erhalten.

wenn __name__ == '__main__': Bilder = Bilder laden und skalieren() Modell = Modell laden('cifar10_architecture.json', 'cifar10_weights.h5') Vorhersagen = Modell.Vorhersageklassen(Bilder) Drucken(Vorhersagen)

Beschriftungsauftrag neu skalieren
Nun fügen wir unser Beschriftungsskript in einen Job ein und beschriften unsere Beispielbilder. Dieser Job ist öffentlich verfügbar auf RescaleWir beginnen mit der Auswahl der von uns erstellten trainierten Modelle. „Dateien aus dem Cloud-Speicher verwenden“ und wählen dann die vom Trainingsjob erstellten JSON- und HDF5-Modelldateien aus:
Label-Eingabemodell
Dann laden Sie unser neues Beschriftungsskript hoch hund_katze.py und Hunde- und Katzenbilder.
Label-Eingabe-Rest
Wählen Sie die Keras GPU-Software aus und führen Sie das Beschriftungsskript aus. In diesem Fall werden die Hunde- und Katzenbilder aus dem aktuellen Verzeichnis geladen, aus dem der Job ausgeführt wird. Es müssen also keine Dateien verschoben werden.
Etikettensoftware
Die Beschriftungen werden dann angezeigt in process_output.log wenn der Auftrag abgeschlossen ist.
Etikettenausgabe
Label-Ergebnisse
Die Ausgabe ist [3, 5] das entspricht Katze und Hund aus unserer Bildklassentabelle oben.
Damit ist dieses Tutorial abgeschlossen. Wir haben erfolgreich ein Convolutional Neural Network zur Bilderkennung auf Rescale trainiert und dieses Netzwerk anschließend zum Beschriften weiterer Bilder verwendet. In Kürze werden wir in einem weiteren Beitrag über die Verwendung komplexerer Rescale-Workflows zur Optimierung des Netzwerktrainings sprechen.

Autorin

  • Mark Whitney

    Mark Whitney ist technischer Leiter bei Rescale. Zu seinen Fachgebieten gehören Hochleistungsrechnerarchitekturen, Quanteninformationsforschung und Cloud Computing. Er promovierte in Informatik an der University of California, Berkeley.