[PYTHON] [Für KI-Anfänger] Erklären Sie mnist_cnn.py Zeile für Zeile (lernen Sie MNIST mit Keras)

Einführung

Dieser Artikel ist der zweite Artikel, der für alle drei Male geplant ist. Dieser Artikel ist nur eine zeilenweise Erklärung von mnist_cnn.py. Es gibt einige Überschneidungen mit dem vorherigen, aber bitte beachten Sie, dass ein Teil des Inhalts möglicherweise dupliziert wird, um das Lesen des Artikels zu erleichtern.

Es ist für Leute gedacht, die sich für KI interessieren, diese aber noch nicht berührt haben. Ich denke, wenn Sie dies lesen, sollten Sie in der Lage sein, den grundlegenden Lernfluss des tiefen Lernens zu verstehen. (Ursprünglich wurde es im eigenen Haus erstellt, um es für Schulungen zu verwenden.)

  1. [Für KI-Anfänger] Erklären Sie mnist_mlp.py Zeile für Zeile (lernen Sie MNIST mit Keras)
  2. [Für KI-Anfänger] Erklären Sie mnist_cnn.py Zeile für Zeile (lernen Sie MNIST mit Keras)
  3. [Für KI-Anfänger] Erklären Sie mnist_transfer_cnn.py Zeile für Zeile (lernen Sie MNIST mit Keras)

Informationen zur Funktionsprüfungsmethode

Da MNIST ein Image ist, ist es besser, eine GPU zu haben, um diesen Code auszuführen (es ist ein bisschen schmerzhaft für eine CPU). Die empfohlene Methode ist die Verwendung von Google Colaboratory. colab.gif Es gibt nur zwei Dinge zu tun. · Öffnen Sie ein neues Python 3-Notizbuch · Aktivieren Sie die GPU zur Laufzeit Sie können jetzt die GPU verwenden. Fügen Sie einfach den Code in die Zelle ein und führen Sie ihn aus (Verknüpfung ist STRG + EINGABETASTE), und es wird funktionieren.

Über Mnist

Ein Datensatz handgeschriebener Textbilder, der häufig in Tutorials zum maschinellen Lernen verwendet wird. Inhalt: Handschriftliche Zeichen von 0 bis 9 Bildgröße: 28px * 28px Farbe: schwarz und weiß Datengröße: 70.000 Blatt (60.000 Trainingsdaten, 10.000 Testdatenbilder und Etiketten sind verfügbar)

Was ist cnn

Convolutional Neural Network, ein Faltungs-Neuronales Netzwerk. Dieser Artikel dient nur zu Codezwecken, daher werde ich nicht näher auf den Faltungsprozess eingehen. Um es schrecklich einfach auszudrücken: Sie können die Merkmale eines Bildes extrahieren, indem Sie einen Faltungsprozess durchführen.

Über mnist_cnn.py

Dies ist der Code zum Erstellen eines Modells, das die handgeschriebenen Zeichen von mnist mithilfe von Keras und TensorFlow beurteilt. Empfängt 10 Arten handgeschriebener Zeichen von 0 bis 9 als Eingabe und erstellt ein Modell, das sie in 10 Typen von 0 bis 9 klassifiziert.

Die Funktion ist dieselbe wie die erste mnist_mlp.py, aber die Verarbeitung im Modell ist unterschiedlich.

Auch in mlp 28 * 28 zweidimensionale Daten (solche Daten → [[0, 0, ..., 0, 0], ... [0, 0, ..., 0, 0]]) 784 eindimensional Es wurde in Daten konvertiert (solche Daten → [0, 0, ... 0, 0]) und als Eingabewert verwendet. In diesem cnn werden 28 * 28 zweidimensionale Daten als Eingabewert verwendet.

Codebeschreibung

Vorbereitung

'''Trains a simple convnet on the MNIST dataset.
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''

#Kein spezieller Code erforderlich (erforderlich, wenn Python Version 3, aber Code in Python 2 geschrieben ist)
from __future__ import print_function

#Importieren Sie die erforderlichen Bibliotheken
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

#Konstante
batch_size = 128  #Chargengröße. Datengröße auf einmal zu lernen
num_classes = 10  #Anzahl der zu klassifizierenden Etiketten. Dieses Mal werden wir handgeschriebene Bilder in 10 Typen von 0 bis 9 klassifizieren.
epochs = 12       #Anzahl der Epochen. Wie oft müssen alle Daten gelernt werden?(Im vorherigen Artikel mlp waren dies 20)
img_rows, img_cols = 28, 28  #Anzahl der Dimensionen des Eingabebildes

Dicht: Vollständig verbundene Schicht Es gibt einen Prozess namens Dropout: Dropout, der die Ausgabe (0) mit einer bestimmten Rate (Wahrscheinlichkeit) deaktiviert. Reduzieren: Konvertieren Sie Daten in eine Dimension Conv2D: Faltschicht MaxPooling2D: Pooling-Ebene

Von den zu Beginn definierten Konstanten sind batch_size und Epochen ** Hyperparameter **, die der Mensch anpassen muss. Wenn Sie dies ändern, ändert sich die Leistung des Modells.

Um es kurz zu erklären: Je größer die batch_size ist, desto stabiler ist das Lernen, aber desto mehr Speicher wird benötigt. Epochen ist die Häufigkeit, mit der trainiert wird. Ich denke, es wird klüger sein, viel zu lernen, aber wenn es zu groß ist, wird es in einen Zustand des ** Überlernens ** geraten und die Generalisierungsleistung wird abnehmen. (= Sie können die zum Lernen verwendeten Daten beurteilen, aber Sie werden nicht in der Lage sein, mit unbekannten Daten umzugehen.) Natürlich bleibt es zumindest aufgrund mangelnden Lernens verrückt.

Datenvorverarbeitung

#Lesen Sie die wichtigsten Daten und Zugdaten(60.000 Fälle)Und Testdaten(10.000 Fälle)Teilen in
(x_train, y_train), (x_test, y_test) = mnist.load_data()

#Konvertieren Sie die Form von Daten
'''
Keras Backend ist Theano(channels_first)Oder Tensorflow(channels_last)Das Format des Bildes ist je nach unterschiedlich
K.image_data_format()Ist"channels_last"Oder"channels_first"Gibt eine der oben genannten Optionen zurück. Klassifizieren Sie sie daher entsprechend
Bei Schwarzweiß beträgt die Anzahl der Kanäle 1. Wenn es sich um ein RGB-Farbbild handelt, beträgt die Anzahl der Kanäle 3.
Diesmal x_train:(60000, 28, 28)->(60000, 28, 28, 1)werden
'''
if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

#Bilddaten haben einen Wert von 0 bis 255, standardisieren Sie die Daten also durch Teilen durch 255.
# .astype('float32')Konvertieren Sie den Datentyp mit.(Andernfalls sollte beim Brechen eine Fehlermeldung angezeigt werden)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

#Überprüfen Sie dies, indem Sie die Dimension und Anzahl der Daten ausgeben
print('x_train shape:', x_train.shape)    # x_train shape: (60000, 28, 28, 1)
print(x_train.shape[0], 'train samples')  # 60000 train samples
print(x_test.shape[0], 'test samples')    # 10000 test samples

#Beschriften Sie die Daten eins-hot-Vektorisieren
'''one-hot-Das Bild des Vektors sieht so aus
label  0 1 2 3 4 5 6 7 8 9
0:    [1,0,0,0,0,0,0,0,0,0]
8:    [0,0,0,0,0,0,0,0,1,0]'''
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

Informationen zur Standardisierung: Der Wert jedes Pixels im Bild beträgt 0 bis 255. Dies ist ein Bild, das dies in 0 ~ 1 konvertiert. Beim maschinellen Lernen mit Bildern wird der Wert durch Teilen durch 255 standardisiert.

Über One-Hot-Vector: Dieses Mal gibt es 10 Arten von Beschriftungen von 0 bis 9, die jeweils durch eine Zahl von 0 bis 9 dargestellt werden. Die Zahlen auf dem Etikett selbst sind jedoch bedeutungslos, da ich sie nur in 10 Typen einteilen möchte. Daher wird es durch einen Ein-Hot-Vektor so konvertiert, dass nur 0 und 1 welches Label darstellen können.

Modelldefinition

#Sequentielle Klasse instanziieren
model = Sequential()

#Mittelschicht
#Faltschicht (Filter: 32 Blatt, Filtergröße:(3, 3), Aktivierungsfunktion: Relu, Eingangsgröße empfangen:( 28, 28, 1))Hinzufügen
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
#Faltschicht (Filter: 64 Blatt, Filtergröße:(3, 3), Aktivierungsfunktion: Relu, Empfangene Eingabegröße wird automatisch ermittelt)Hinzufügen
model.add(Conv2D(64, (3, 3), activation='relu'))
#Pooling-Schicht
model.add(MaxPooling2D(pool_size=(2, 2)))
# 0.25 Ausfallchancen
model.add(Dropout(0.25))
#Konvertieren Sie Daten in eine Dimension
model.add(Flatten())
#Vollständig verbundene Schicht hinzugefügt (128 Einheiten, Aktivierungsfunktion: Relu, zu empfangende Eingangsgröße wird automatisch bestimmt)
model.add(Dense(128, activation='relu'))
# 0.5 Chance auszusteigen
model.add(Dropout(0.5))

#Ausgabeschicht
#Vollständig verbundene Schicht hinzugefügt (10 Einheiten, Aktivierungsfunktion: SoftMax, empfangene Eingangsgröße wird automatisch bestimmt)
model.add(Dense(num_classes, activation='softmax'))

Das sequentielle Modell ist ein Modell, das durch Stapeln von DNN-Schichten erstellt wird. Sie müssen input_shape nur für die allererste Ebene angeben. Da die Aktivierungsfunktion der Ausgabeschicht diesmal ein mehrwertiges Klassifizierungsmodell ist, wird Softmax verwendet.

Dicht (vollständig verbundene Schicht) kann nur als eindimensionale Daten empfangen werden. Vor Dense müssen Sie die Daten mit ** Flatten () ** in 1D konvertieren.

Lernen

#Richten Sie den Lernprozess ein

model.compile(
              #Stellen Sie die Verlustfunktion ein. Diesmal ist es eine Klassifizierung, also kategorisch_crossentropy
              loss=keras.losses.categorical_crossentropy,
              #Der Optimierungsalgorithmus ist Adadelta(Unterschied zu mlp)
              optimizer=keras.optimizers.Adadelta(),
              #Bewertungsfunktion angeben
              metrics=['accuracy'])

#Lernen
model.fit(x_train, y_train,      #Trainingsdaten, Etikett
          batch_size=batch_size, #Chargengröße (128)
          epochs=epochs,         #Anzahl der Epochen (12)
          verbose=1,             # #Zeigen Sie den Lernfortschritt in Echtzeit als Balkendiagramm an(Bei 0 verstecken)
          validation_data=(x_test, y_test))  #Testdaten(Um jede Epoche zu testen und den Fehler zu berechnen)

Geben Sie nach der Definition des Modells die Verlustfunktion und den Optimierungsalgorithmus an und kompilieren Sie. Übergeben Sie dann die Daten zum Training an das Modell.

Der hier angegebene Optimierungsalgorithmus Adadelta ist ebenfalls eine Art Hyperparameter. Ich denke, dass der Algorithmus namens Adam oft verwendet wird, aber es gibt absolut nichts Gutes, also muss man Versuch und Irrtum machen.

Auswertung

#Testdaten bestehen(verbose=0 gibt keine Fortschrittsmeldung aus)
score = model.evaluate(x_test, y_test, verbose=0)
#Fehler bei der Ausgabeverallgemeinerung
print('Test loss:', score[0])
#Leistung der Ausgabeverallgemeinerung
print('Test accuracy:', score[1])

Verwenden Sie nach dem Lernen die Testdaten, um zu bewerten, wie viel Leistung Sie erzielt haben. Je geringer der Verlust und je höher die Genauigkeit, desto besser das Modell.

Recommended Posts

[Für KI-Anfänger] Erklären Sie mnist_cnn.py Zeile für Zeile (lernen Sie MNIST mit Keras)
[Für KI-Anfänger] Ich werde mnist_transfer_cnn.py Zeile für Zeile erklären (MNIST mit Keras lernen)
[Für KI-Anfänger] Erklären Sie mnist_mlp.py Zeile für Zeile (lernen Sie MNIST mit Keras)
[Für Anfänger] Ich habe mit Raspberry Pi einen menschlichen Sensor erstellt und LINE benachrichtigt!
Ich habe versucht, GAN (mnist) mit Keras zu bewegen
Ich habe das MNIST-Tutorial von tensorflow für Anfänger ausprobiert.
Klassifizieren Sie Mnist-Zahlen nach Keras, ohne dass der Lehrer etwas lernt [Auto Encoder Edition]
Ich habe versucht, MNIST nach GNN zu klassifizieren (mit PyTorch-Geometrie).
Für Anfänger, wie man mit häufigen Fehlern in Keras umgeht
Abnormalitätserkennung durch Auto-Encoder mit Keras [Implementierungsbeispiel für Anfänger]