Zum Inhalt springen

Convolutional Neural Network in TensorFlow mit CIFAR10 Bildern

Mit der Python Bibliothek TensorFlow können wir schnell und einfach ein Convolutional Neural Network aufbauen, das wir beispielsweise dazu nutzen können, Bilder zu klassifizieren. In einem früheren Artikel hatten wir uns in der Theorie angeschaut, wie ein solches Convolutional Neural Network funktioniert. Jetzt wollen wir es erstellen und trainieren.

Datensatz

TensorFlow verfügt über verschiedenste Datensätze, die wir mit wenigen Codezeilen downloaden und nutzen können. Das ist besonders dann hilfreich, wenn man neue Modelle und deren Umsetzung testen will und deshalb nicht lange nach Daten suchen will. Darüber hinaus bietet auch Google eine Datensatz Recherche an, mit welcher man innerhalb weniger Klicks einen passenden Datensatz findet.

Für unser beispielhaftes Convolutional Neural Network nutzen wir den CIFAR10 Datensatz, welcher über TensorFlow verfügbar ist. Der Datensatz enthält insgesamt 60.000 Bilder in Farbe, die in zehn verschiedene Bildklassen aufgeteilt sind. Wir merken, dass es sich dabei um einen perfekten Trainingsdatensatz handelt, da jede Klasse exakt 6.000 Bilder beinhaltet. Bei Klassifizierungsmodellen müssen wir immer darauf achten, dass jede Klasse nach Möglichkeit gleich oft im Datensatz enthalten ist. Für den Testdatensatz nehmen wir insgesamt 10.000 Bilder und somit 50.000 Bilder für den Trainingsdatensatz.

Jedes dieser Bilder ist 32×32 Pixel groß. Die Pixel wiederum haben einen Wert zwischen 0 und 255, wobei jede Zahl einen Farbcode repräsentiert. Deshalb teilen wir jeden Pixelwert durch 255, sodass wir die Pixelwerte auf den Bereich zwischen 0 und 1 normalisieren.

# Bibliothek zur Darstellung der Bilder und der Verlustfunktion
import matplotlib.pyplot as plt

# Von Tensorflow importieren wir den Datensatz und bauen das Modell auf
import tensorflow as tf
from tensorflow.keras import datasets, layers, models

# Herunterladen des Datensatzes
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()

# Normalisieren der Pixelwerte zwischen 0 und 1
train_images, test_images = train_images / 255.0, test_images / 255.0

Um zu prüfen, dass alle Bilder richtig dargestellt werden, lassen wir uns die ersten zehn Bilder printen inklusive der Klasse zu der sie gehören. Da es sich dabei lediglich um 32×32 Bilder handelt sind die Bilder zwar relativ unscharf, man erkennt jedoch trotzdem, um welche Klasse es sich handelt.

# Definieren der 10 Bildklassen
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

# Anzeigen der ersten 10 Bilder
plt.figure(figsize=(10,10))
for i in range(10):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i])
    # Die CIFAR Labels sind Arrays, deshalb benötigen wir den extra Index
    plt.xlabel(class_names[train_labels[i][0]])
plt.show()
Das Bild zeigt die ersten 10 Bilder aus dem CIFAR10 Datensatz, den wir zur Erstellung des Convolutional Neural Networks nutzen,
CIFAR10 Bilder

Convolutional Neural Network aufbauen

In TensorFlow können wir nun das Convolutional Neural Network bauen, indem wir die Abfolge der einzelnen Schichten definieren. Da es sich um relativ kleine Bilder handelt werden wir zweimal den Stapel aus Convolutional Layer und Max Pooling Layer nutzen. Die Bilder haben, wie wir es bereits kennen, 32 Höhen-, 32 Breitendimensionen und 3 Farbkanäle (Rot, Grün, Blau).

Die Convolutional Layer nutzen erst 32 und dann 64 Filter mit einem 3×3 Kernel als Filter und die Max Pooling Layer sucht den maximalen Wert innerhalb einer 2×2 Matrix. Wem diese Vorgehensweise noch fremd ist, der kann gerne den theoretischen Beitrag zu Convolutional Neural Networks nochmal nachlesen.

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

Nach diesen zwei Stapeln haben wir die Dimensionen der Bilder schon deutlich herabgesetzt, auf 6 Höhenpixel, 6 Breitenpixel und insgesamt 64 Filter. Mit einer dritten und letzten Convolutional Layer reduzieren wir diese Dimensionen weiter auf 4x4x64. Bevor wir daraus nun ein vollvermaschtes Netzwerk aufbauen, ersetzen wir die 3×3 Matrix pro Bild, durch einen Vektor aus 1024 Elemente (4*4*64), ohne dabei Informationen zu verlieren.

Nun haben wir die Dimensionen der Bilder ausreichend reduziert und können noch eine Hidden Layer mit insgesamt 64 Neuronen einfügen, bevor das Modell in der Ausgabeschicht mit den zehn Neuronen für die zehn verschiedenen Klassen endet.

model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))

model.summary()

Out:
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 30, 30, 32)        896       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 15, 15, 32)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 13, 13, 64)        18496     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 6, 6, 64)         0         
 2D)                                                             
                                                                 
 conv2d_2 (Conv2D)           (None, 4, 4, 64)          36928     
                                                                 
 flatten (Flatten)           (None, 1024)              0         
                                                                 
 dense (Dense)               (None, 64)                65600     
                                                                 
 dense_1 (Dense)             (None, 10)                650       
                                                                 
=================================================================
Total params: 122,570
Trainable params: 122,570
Non-trainable params: 0
_________________________________________________________________

Das Modell mit insgesamt 122.570 Parametern ist nun fertig aufgebaut und kann trainiert werden.

Modell kompilieren und trainieren

Bevor wir mit dem Training des Convolutional Neural Networks beginnen können, müssen wir das Modell noch kompilieren. Darin definieren, nach welcher Verlustfunktion das Modell trainiert werden soll, den Optimizer, also nach welchem Algorithmus sich die Parameter ändern, und welche Metrik wir gezeigt bekommen wollen, um den Trainingsverlauf überwachen zu können.

model.compile(optimizer='adam', 
             loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
             metrics=['accuracy'])

history = model.fit(train_images, train_labels, epochs=10, 
                    validation_data=(test_images, test_labels))

Modell Bewertung

Nachdem wir das Convolutional Nerual Network für insgesamt 10 Epochen trainiert haben, können wir uns den Verlauf der Genauigkeit des Modells anschauen, um festzustellen, ob wir mit dem Training zufrieden sind.

plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
Der Graph zeigt die Trainings- und Validationgenauigkeit eines CNN Modells nach 10 Epochen Trainingszeit.
CNN Training- und Validation-Genauigkeit

Unsere Vorhersage der Bildklasse ist in etwa 80 % der Fällen richtig. Dies ist kein schlechter Wert, aber auch kein besonders guter. Wenn wir diesen noch weiter erhöhen wollen, könnten wir das Convolutional Neural Network für mehr Epochen trainieren lassen oder möglicherweise auch die Dense Layer noch anders konfigurieren.

Das solltest Du mitnehmen

  • Convolutional Neural Networks lassen sich mithilfe von TensorFlow in nur wenigen Schritten selbst programmieren.
  • Wichtig ist die Anordnung der Convolutional und Max Pooling Layer auf den Use Case abzustimmen.

Andere Beiträge zum Thema Convolutional Neural Network in TensorFlow

  • Dieser Beitrag orientiert sich vor allem an dem Beispiel von TensorFlow.
Cookie Consent mit Real Cookie Banner