So implementieren Sie ein CNN mit Deeplearning4j

1. Übersicht

In diesem Tutorial erstellen und trainieren wir ein Faltungsmodell für neuronale Netze mithilfe der Deeplearning4j-Bibliothek in Java.

Weitere Informationen zum Einrichten der Bibliothek finden Sie in unserem Handbuch zu Deeplearning4j.

2. Bildklassifizierung

2.1. Problemstellung

Angenommen, wir haben eine Reihe von Bildern. Jedes Bild repräsentiert ein Objekt einer bestimmten Klasse. Darüber hinaus gehört das Objekt auf dem Bild zur einzigen bekannten Klasse. So ist das Problem Anweisung zum Erstellen des Modells in der Lage sein wird , die Klasse des Objekts auf dem gegebene Bild zu erkennen .

Nehmen wir zum Beispiel an, wir haben eine Reihe von Bildern mit zehn Handgesten. Wir bauen ein Modell und trainieren es, um sie zu klassifizieren. Dann können wir nach dem Training andere Bilder übergeben und die Handgesten darauf klassifizieren. Natürlich sollte die gegebene Geste zu den bekannten Klassen gehören.

2.2. Bilddarstellung

Im Computerspeicher kann das Bild als Zahlenmatrix dargestellt werden. Jede Zahl ist ein Pixelwert im Bereich von 0 bis 255.

Ein Graustufenbild ist eine 2D-Matrix. In ähnlicher Weise ist das RGB-Bild eine 3D-Matrix mit Abmessungen für Breite, Höhe und Tiefe.

Wie wir vielleicht sehen, ist das Bild eine Reihe von Zahlen . Daher können wir mehrschichtige Netzwerkmodelle erstellen, um sie für die Klassifizierung von Bildern zu trainieren.

3. Faltungsneurale Netze

Ein Convolutional Neural Network (CNN) ist ein mehrschichtiges Netzwerkmodell mit einer bestimmten Struktur. Die Struktur eines CNN kann in zwei Blöcke unterteilt werden: Faltungsschichten und vollständig verbundene (oder dichte) Schichten . Schauen wir uns jeden an.

3.1. Faltungsschicht

Jede Faltungsschicht besteht aus einer Reihe quadratischer Matrizen, die als Kernel bezeichnet werden . Vor allem brauchen wir sie, um das Eingabebild zu falten. Ihre Menge und Größe kann je nach gegebenem Datensatz variieren. Wir verwenden meistens 3 × 3 oder 5 × 5 Kernel und selten 7 × 7. Die genaue Größe und Menge werden durch Ausprobieren ausgewählt.

Außerdem wählen wir die Variablen der Kernel-Matrizen zu Beginn des Zuges zufällig aus. Sie sind die Gewichte des Netzwerks.

Um eine Faltung durchzuführen, können wir den Kernel als Schiebefenster verwenden. Wir werden die Kernelgewichte mit den entsprechenden Bildpixeln multiplizieren und die Summe berechnen. Dann können wir den Kernel bewegen, um den nächsten Teil des Bildes mit Schritt (nach rechts bewegen) und Auffüllen (nach unten bewegen) abzudecken. Als Ergebnis haben wir Werte, die für weitere Berechnungen verwendet werden.

Kurz gesagt, mit dieser Ebene erhalten wir ein gefaltetes Bild . Einige Variablen sind möglicherweise kleiner als Null. Dies bedeutet normalerweise, dass diese Variablen weniger wichtig sind als die anderen. Aus diesem Grund ist die Anwendung der ReLU-Funktion ein guter Ansatz, um weniger Berechnungen durchzuführen.

3.2. Unterabtastungsschicht

Die Unterabtast- (oder Pool-) Schicht ist eine Schicht des Netzwerks, die normalerweise nach der Faltungsschicht verwendet wird. Nach der Faltung erhalten wir viele berechnete Variablen . Unsere Aufgabe ist es jedoch, die wertvollsten unter ihnen auszuwählen .

Der Ansatz besteht darin, einen Schiebefensteralgorithmus auf das gefaltete Bild anzuwenden. Bei jedem Schritt wählen wir den Maximalwert im quadratischen Fenster einer vordefinierten Größe, normalerweise zwischen 2 × 2 und 5 × 5 Pixel. Infolgedessen haben wir weniger berechnete Parameter. Dies reduziert daher die Berechnungen.

3.3. Dichte Schicht

Eine dichte (oder vollständig verbundene) Schicht besteht aus mehreren Neuronen. Wir brauchen diese Schicht, um eine Klassifizierung durchzuführen. Darüber hinaus können zwei oder mehr solcher aufeinander folgenden Schichten vorhanden sein. Wichtig ist, dass die letzte Ebene eine Größe hat, die der Anzahl der zu klassifizierenden Klassen entspricht.

Die Ausgabe des Netzwerks ist die Wahrscheinlichkeit, dass das Bild zu jeder der Klassen gehört . Um die Wahrscheinlichkeiten vorherzusagen, verwenden wir die Softmax-Aktivierungsfunktion.

3.4. Optimierungstechniken

Um ein Training durchzuführen, müssen wir die Gewichte optimieren. Denken Sie daran, dass wir diese Variablen zunächst zufällig auswählen. Das neuronale Netzwerk ist eine große Funktion . Und es hat viele unbekannte Parameter, unsere Gewichte.

Wenn wir ein Bild an das Netzwerk übergeben, erhalten wir die Antwort . Dann können wir eine Verlustfunktion aufbauen, die von dieser Antwort abhängt . In Bezug auf betreutes Lernen haben wir auch eine tatsächliche Antwort - die wahre Klasse. Unsere Mission ist es, diese Verlustfunktion zu minimieren . Wenn wir Erfolg haben, ist unser Modell gut ausgebildet.

Um die Funktion zu minimieren, müssen wir die Gewichte des Netzwerks aktualisieren . Dazu können wir die Ableitung der Verlustfunktion in Bezug auf jeden dieser unbekannten Parameter berechnen. Dann können wir jedes Gewicht aktualisieren.

Wir können den Gewichtswert erhöhen oder verringern, um das lokale Minimum unserer Verlustfunktion zu finden, da wir die Steigung kennen. Darüber hinaus ist dieser Prozess iterativ und wird als Gradientenabstieg bezeichnet . Die Backpropagation verwendet einen Gradientenabstieg, um die Gewichtsaktualisierung vom Ende bis zum Anfang des Netzwerks zu verbreiten.

In diesem Tutorial verwenden wir den Optimierungsalgorithmus Stochastic Gradient Decent (SGD). Die Hauptidee ist, dass wir bei jedem Schritt zufällig die Stapel von Zugbildern auswählen. Dann wenden wir Backpropagation an.

3.5. Bewertungsmetriken

Schließlich müssen wir nach dem Training des Netzwerks Informationen darüber erhalten, wie gut unser Modell funktioniert.

Die am häufigsten verwendete Metrik ist die Genauigkeit . Dies ist das Verhältnis von korrekt klassifizierten Bildern zu allen Bildern. In der Zwischenzeit sind Rückruf, Präzision und F1-Score ebenfalls sehr wichtige Messgrößen für die Bildklassifizierung .

4. Datensatzvorbereitung

In diesem Abschnitt bereiten wir die Bilder vor. Verwenden wir in diesem Lernprogramm den eingebetteten CIFAR10-Datensatz. Wir werden Iteratoren erstellen, um auf die Bilder zuzugreifen:

public class CifarDatasetService implements IDataSetService { private CifarDataSetIterator trainIterator; private CifarDataSetIterator testIterator; public CifarDatasetService() { trainIterator = new CifarDataSetIterator(trainBatch, trainImagesNum, true); testIterator = new CifarDataSetIterator(testBatch, testImagesNum, false); } // other methods and fields declaration }

We can choose some parameters on our own. TrainBatch and testBatch are the numbers of images per train and evaluation step respectively. TrainImagesNum and testImagesNum are the numbers of images for training and testing. One epoch lasts trainImagesNum / trainBatch steps. So, having 2048 train images with a batch size = 32 will lead to 2048 / 32 = 64 steps per one epoch.

5. Convolutional Neural Network in Deeplearning4j

5.1. Building the Model

Next, let's build our CNN model from scratch. To do it, we'll use convolutional, subsampling (pooling), and fully connected (dense) layers.

MultiLayerConfiguration configuration = new NeuralNetConfiguration.Builder() .seed(1611) .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT) .learningRate(properties.getLearningRate()) .regularization(true) .updater(properties.getOptimizer()) .list() .layer(0, conv5x5()) .layer(1, pooling2x2Stride2()) .layer(2, conv3x3Stride1Padding2()) .layer(3, pooling2x2Stride1()) .layer(4, conv3x3Stride1Padding1()) .layer(5, pooling2x2Stride1()) .layer(6, dense()) .pretrain(false) .backprop(true) .setInputType(dataSetService.inputType()) .build(); network = new MultiLayerNetwork(configuration);

Here we specify the learning rate, the update algorithm, the input type of our model, and the layered architecture. We can experiment on these configurations. Thus, we can train many models with different architectures and training parameters. Furthermore, we can compare the results and choose the best model.

5.2. Training the Model

Then, we'll train the built model. This can be done in a few lines of code:

public void train() { network.init(); IntStream.range(1, epochsNum + 1).forEach(epoch -> { network.fit(dataSetService.trainIterator()); }); }

The number of epochs is the parameter that we can specify ourselves. We have a small dataset. As a result, several hundred epochs will be enough.

5.3. Evaluating the Model

Finally, we can evaluate the now-trained model. Deeplearning4j library provides an ability to do it easily:

public Evaluation evaluate() { return network.evaluate(dataSetService.testIterator()); }

Die Auswertung ist ein Objekt, das nach dem Training des Modells berechnete Metriken enthält. Dies sind Genauigkeit, Präzision, Rückruf und F1-Punktzahl . Darüber hinaus verfügt es über eine benutzerfreundliche druckbare Oberfläche:

==========================Scores===================== # of classes: 11 Accuracy: 0,8406 Precision: 0,7303 Recall: 0,6820 F1 Score: 0,6466 =====================================================

6. Fazit

In diesem Tutorial haben wir die Architektur von CNN-Modellen, Optimierungstechniken und Bewertungsmetriken kennengelernt. Darüber hinaus haben wir das Modell mithilfe der Deeplearning4j-Bibliothek in Java implementiert.

Wie üblich ist der Code für dieses Beispiel auf GitHub verfügbar.