Merken Sie den Termin vor! Google I / O kehrt vom 18. bis 20. Mai zurück Registrieren Sie sich jetzt
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Faltungs-Neuronales Netz (CNN)

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Dieses Tutorial zeigt das Training eines einfachen Convolutional Neural Network (CNN) zur Klassifizierung von CIFAR-Bildern . Da in diesem Lernprogramm die Keras Sequential API verwendet wird , sind für das Erstellen und Trainieren unseres Modells nur wenige Codezeilen erforderlich.

TensorFlow importieren

import tensorflow as tf

from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

Laden Sie den CIFAR10-Datensatz herunter und bereiten Sie ihn vor

Der CIFAR10-Datensatz enthält 60.000 Farbbilder in 10 Klassen mit 6.000 Bildern in jeder Klasse. Der Datensatz ist in 50.000 Trainingsbilder und 10.000 Testbilder unterteilt. Die Klassen schließen sich gegenseitig aus und es gibt keine Überlappung zwischen ihnen.

(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()

# Normalize pixel values to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 11s 0us/step

Überprüfen Sie die Daten

Um zu überprüfen, ob der Datensatz korrekt aussieht, zeichnen wir die ersten 25 Bilder aus dem Trainingssatz und zeigen den Klassennamen unter jedem Bild an.

class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    # The CIFAR labels happen to be arrays, 
    # which is why you need the extra index
    plt.xlabel(class_names[train_labels[i][0]])
plt.show()

png

Erstellen Sie die Faltungsbasis

Die folgenden 6 Codezeilen definieren die Faltungsbasis anhand eines gemeinsamen Musters: eines Stapels von Conv2D- und MaxPooling2D- Ebenen.

Als Eingabe nimmt ein CNN Tensoren der Form (Bildhöhe, Bildbreite, Farbkanäle) an und ignoriert die Stapelgröße. Wenn Sie mit diesen Dimensionen noch nicht vertraut sind, bezieht sich color_channels auf (R, G, B). In diesem Beispiel konfigurieren Sie unser CNN so, dass Eingaben der Form (32, 32, 3) verarbeitet werden. Dies ist das Format von CIFAR-Bildern. Sie können dies tun, indem Sie das Argument input_shape an unsere erste Ebene übergeben.

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)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

Lassen Sie uns die Architektur unseres Modells bis jetzt zeigen.

model.summary()
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 (MaxPooling2 (None, 6, 6, 64)          0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 4, 4, 64)          36928     
=================================================================
Total params: 56,320
Trainable params: 56,320
Non-trainable params: 0
_________________________________________________________________

Oben sehen Sie, dass die Ausgabe jeder Conv2D- und MaxPooling2D-Ebene ein 3D-Tensor der Form (Höhe, Breite, Kanäle) ist. Die Abmessungen für Breite und Höhe schrumpfen tendenziell, wenn Sie tiefer in das Netzwerk eindringen. Die Anzahl der Ausgangskanäle für jede Conv2D-Schicht wird durch das erste Argument gesteuert (z. B. 32 oder 64). Wenn die Breite und Höhe schrumpfen, können Sie es sich normalerweise leisten (rechnerisch), mehr Ausgangskanäle in jede Conv2D-Schicht einzufügen.

Fügen Sie dichte Ebenen hinzu

Um unser Modell zu vervollständigen, geben Sie den letzten Ausgangstensor von der Faltungsbasis (der Form (4, 4, 64)) in eine oder mehrere dichte Schichten ein, um eine Klassifizierung durchzuführen. Dichte Schichten nehmen Vektoren als Eingabe (die 1D sind), während die aktuelle Ausgabe ein 3D-Tensor ist. Zuerst werden Sie die 3D-Ausgabe auf 1D reduzieren (oder abrollen) und dann eine oder mehrere dichte Ebenen hinzufügen. CIFAR verfügt über 10 Ausgabeklassen, sodass Sie eine letzte dichte Ebene mit 10 Ausgaben verwenden.

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

Hier ist die komplette Architektur unseres Modells.

model.summary()
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 (MaxPooling2 (None, 6, 6, 64)          0         
_________________________________________________________________
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
_________________________________________________________________

Wie Sie sehen können, wurden unsere (4, 4, 64) Ausgaben in Formvektoren (1024) abgeflacht, bevor zwei dichte Schichten durchlaufen wurden.

Kompilieren und trainieren Sie das Modell

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))
Epoch 1/10
1563/1563 [==============================] - 18s 4ms/step - loss: 1.7606 - accuracy: 0.3488 - val_loss: 1.2753 - val_accuracy: 0.5504
Epoch 2/10
1563/1563 [==============================] - 6s 4ms/step - loss: 1.1977 - accuracy: 0.5751 - val_loss: 1.0409 - val_accuracy: 0.6371
Epoch 3/10
1563/1563 [==============================] - 6s 4ms/step - loss: 1.0137 - accuracy: 0.6439 - val_loss: 0.9613 - val_accuracy: 0.6597
Epoch 4/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.8844 - accuracy: 0.6908 - val_loss: 0.9272 - val_accuracy: 0.6766
Epoch 5/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.7950 - accuracy: 0.7205 - val_loss: 0.8712 - val_accuracy: 0.6923
Epoch 6/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.7410 - accuracy: 0.7388 - val_loss: 0.8894 - val_accuracy: 0.6943
Epoch 7/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.6924 - accuracy: 0.7547 - val_loss: 0.8980 - val_accuracy: 0.6993
Epoch 8/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.6453 - accuracy: 0.7728 - val_loss: 0.8695 - val_accuracy: 0.7109
Epoch 9/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.5999 - accuracy: 0.7881 - val_loss: 0.8887 - val_accuracy: 0.7098
Epoch 10/10
1563/1563 [==============================] - 6s 4ms/step - loss: 0.5461 - accuracy: 0.8088 - val_loss: 0.8840 - val_accuracy: 0.7157

Bewerten Sie das Modell

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')

test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
313/313 - 1s - loss: 0.8840 - accuracy: 0.7157

png

print(test_acc)
0.7156999707221985

Unser einfaches CNN hat eine Testgenauigkeit von über 70% erreicht. Nicht schlecht für ein paar Codezeilen! Ein anderes CNN-tf.GradientTape hier in einem Beispiel mit der Keras-Unterklassen-API und einemtf.GradientTape .