[PYTHON] Deep Learning Bildanalyse beginnend mit Kaggle und Keras

Einführung

Dieser Artikel führt in die Klassifizierung von MNIST-Datensätzen unter Verwendung der Kaggle-Entwicklungsumgebung (Kernel-Notizbuch) und von Keras als Einführung in die Analyse von Malmönchen ein. Der Kernel ist auf Kaggle für die Öffentlichkeit zugänglich. Schauen Sie also bitte nach, ob Sie ihn selbst ausführen möchten.

Wenn Sie Fehler, Fragen oder Kommentare haben, lassen Sie es uns bitte wissen. Es wird ermutigend sein, wenn Sie LGTM bekommen können!

Was ist Kaggle?

Kaggle ist der weltweit größte Online-Analysewettbewerb. Darüber hinaus gibt es eine Online-Entwicklungsumgebung namens Kernel Notebook, mit der Sie sofort an der Analyse arbeiten können. Dies ist ideal, um mit der Datenanalyse zu beginnen. Dieser Artikel richtet sich an Personen, die sich bereits bei Kaggle registriert haben und wissen, wie man Kernel verwendet. (Es gibt viele Artikel, die selbst diejenigen, die es nicht wissen, hilfreich sein können. Ich denke, Sie können sie sofort nachholen.)

Siehe unten für weitere Details.

Was ist Keras?

Keras ist eine Deep-Learning-Bibliothek, die auf Tensorflow basiert und dafür bekannt ist, sehr schnell Deep-Learning-Modelle erstellen zu können.

Siehe unten für weitere Details.

Was ist MNIST?

Es ist ein sehr berühmter Bilddatensatz, der aus handgeschriebenen Zahlen (0-9) und den Zahlen besteht, die sie wirklich darstellen (korrekte Bezeichnung). image.png

Siehe unten für weitere Details.

Hauptthema

Auch dieser Artikel ist auch auf Kaggles Kernel veröffentlicht. Wenn Sie also eine Gabelung wünschen, lesen Sie dies bitte ebenfalls.

Laden und Überprüfen von Daten

Sie sehen, dass die Trainingsdaten aus 42000 Daten bestehen. Obwohl es 785 Spalten gibt, ist die richtige Bezeichnung die erste, sodass Sie sehen können, dass die zum Lernen verwendete Merkmalsmenge aus 784 besteht. Sie können sehen, dass die Beschriftung eine Ganzzahl ist und die Feature-Menge für die meisten Elemente 0 ist.

#Trainingsdaten laden
train = pd.read_csv("../input/train.csv")
print(train.shape)
train.head()

image.png

Es gibt 28000 Testdaten. Es gibt keine korrekte Bezeichnung, daher besteht sie aus 784 Spalten.

#Testdaten laden
test= pd.read_csv("../input/test.csv")
print(test.shape)
test.head()

image.png

Typkonvertierung und Konvertierung in benutzerfreundliche Numpy-Daten.


#Schneiden Sie den Teil der Merkmalsmenge der Trainingsdaten ohne das richtige Antwortetikett aus.
X_train = train.iloc[:,1:].values.astype('float32')
#Schneiden Sie nur das richtige Antwortetikett aus den Trainingsdaten aus.
y_train = train.iloc[:,0].values.astype('int32')
#Dies sind Testdaten.
X_test = test.values.astype('float32')

Schauen wir uns den Prozentsatz von 0 in den Daten an. Das Verhältnis von 0 beträgt ungefähr 80%, und Sie können sehen, dass die meisten Elemente 0 sind. In diesem Datensatz bedeutet 0 leer = nicht charakterisierter Bereich.


print(f"Der Prozentsatz der Elemente ungleich Null{round((X_train > 0).sum()/(X_train >= 0 ).sum()*100)}%ist")
print(f"Der Prozentsatz von 0 Elementen{round((X_train == 0).sum()/(X_train >= 0 ).sum()*100)}%ist")

image.png

Wenn wir uns die Verteilung der korrekten Etiketten ansehen, sehen wir, dass jedes Etikett von 0 bis 9 etwa 10% ausmacht. Daher scheint eine Anpassung aufgrund eines Klassenungleichgewichts nicht erforderlich zu sein.



#Zeigen Sie den Prozentsatz der korrekten Beschriftungen in einem Kreisdiagramm an
f, ax = plt.subplots(1,figsize=(6,6))
y_count = pd.Series(y_train).value_counts().sort_index()
ax.pie(y_count.values , 
       labels=y_count.index, 
       autopct='%1.1f%%', 
       counterclock = False,
       startangle = 90)
plt.show()

image.png

Als nächstes transformieren Sie die Daten in ein Formular, das einfach als Bild zu verarbeiten ist. Wie wir zuvor gesehen haben, besteht jedes Bild aus 784 Elementen, aber dies war tatsächlich ein eindimensionaler Zusammenbruch von quadratischen Daten, die aus 28 vertikalen und 28 horizontalen Elementen bestehen. Transformiert für alle Trainingsdaten in 28x28 (42000 = X_train.shape [0]).


#Datentransformation
X_train = X_train.reshape(X_train.shape[0], 28, 28)

Lassen Sie uns die transformierten Rohdaten visualisieren. Um die Bedeutung von Rohdaten zu berücksichtigen, drücken wir die Daten hier als Zeichenfolge aus, ohne eine Bildbibliothek zu verwenden. Zeigen wir den Teil, in dem das Nicht-Null-Element vorhanden ist, als # an. Dann können Sie die Ausgabe wie handgeschriebene Zahlen erhalten.

Die Originaldaten sind eine Liste von Zahlen, die für den Menschen schwer zu verstehen sind, aber es waren tatsächlich Daten, die aus der Absicht der Tinte (ob sie nicht 0 ist oder nicht) und ihrer Dichte (Wert der Zahl) bestehen.


#Daten in Zeichenfolge konvertieren und anzeigen
def visualize_str(d):
    d = d.astype("int32").astype("str")    
    d[d != "0"] = "# "
    d[d == "0"] = ". "
    d = pd.DataFrame(d)
    for i in range(d.shape[0]):
        print("".join(d.iloc[i,:]))
    print("") 
        
for i in range(1):
    visualize_str(X_train[i])

image.png

Wenn Sie versuchen, es als Bild anzuzeigen, erhalten Sie immer noch die gleiche Ausgabe wie bei der vorherigen Zeichenfolgenanzeige.


#Mit Bild visualisieren
f, ax = plt.subplots(1,3)
for i in range(3):   
    ax[i].imshow(X_train[i], cmap=plt.get_cmap('gray'))

image.png

Da bei der Bildanalyse manchmal farbige Bilder verwendet werden, wird davon ausgegangen, dass die Eingabe in das Modell eine Dimension aufweist, die als Farbkanal bezeichnet wird und Farbtöne enthält (hauptsächlich Mihara). Da es sich diesmal um eine Graustufe handelt, gibt es keine neuen Daten, aber wir werden den Tensor gemäß der obigen Idee konvertieren. Stellen Sie außerdem vor dem Lernen eine Hot-Codierung und Zufallszahlen als Vorbereitung ein.


#Farbkanal hinzufügen
X_train = X_train.reshape(X_train.shape[0], 28, 28,1)
X_test = X_test.reshape(X_test.shape[0], 28, 28,1)

#Eine heiße Codierung
from keras.utils.np_utils import to_categorical
y_train= to_categorical(y_train)

#Zufällige Zahlen für die Reproduzierbarkeit behoben
seed = 0
np.random.seed(seed)

Modell 1: Lineares Modell

Es ist endlich Modellierung, aber zuerst versuchen wir es mit einem sehr einfachen linearen Modell.

Definieren Sie zuvor die erforderlichen Funktionen zum Importieren und Standardisieren von Modulen.

from keras.models import  Sequential
from keras.layers.core import  Lambda , Dense, Flatten, Dropout
#from keras.callbacks import EarlyStopping
from keras.layers import BatchNormalization, Convolution2D , MaxPooling2D

#Definition der Standardisierungsfunktion
mean_X = X_train.mean().astype(np.float32)
std_X = X_train.std().astype(np.float32)

def standardize(x): 
    return (x-mean_X)/std_X

Nun erstellen wir das Modell.


#Definition des linearen Modells

model_linear= Sequential()
#Standardisierung
model_linear.add(Lambda(standardize,input_shape=(28,28,1)))
#Machen Sie es eindimensional, um es in die vollständig verbundene Ebene zu legen
model_linear.add(Flatten())
#Vollständig verbundene Schicht
model_linear.add(Dense(10, activation='softmax'))
#Modellvisualisierung
print("model_linear")
model_linear.summary()

image.png

Keras wird nach dem Definieren des Modells kompiliert. Beim Kompilieren werden der Index angegeben, der durch Lernen = Verlust optimiert werden soll, und der Index, der wirklich optimiert werden soll.

#Modell kompilieren
#Geben Sie den zu optimierenden Index und den zu beobachtenden Index an
from keras.optimizers import Adam ,RMSprop

model_linear.compile(optimizer=RMSprop(lr=0.001),
                     loss='categorical_crossentropy',
                     metrics=['accuracy'])

Nachdem das Modell fertig ist, möchte ich das Modell mit Daten füllen, aber ich muss die Daten vorbereiten. Bereiten Sie einen Generator vor und teilen Sie die Daten für die Kreuzvalidierung auf. (Dies sollte als Holdout-Methode bezeichnet werden, aber in Kaggle wird sie üblicherweise als Kreuzvalidierung ausgedrückt, daher bin ich mir des Missverständnisses bewusst und drücke es so aus.)


#Daten für die Eingabe vorbereiten

#Definition des Generators
from keras.preprocessing import image
generator = image.ImageDataGenerator()

#Alle zum Zeitpunkt der Einreichung verwendeten Lerndaten
X = X_train
y = y_train

#Kreuzvalidierung
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.15, random_state=seed)
train_generator = generator.flow(X_train, y_train, batch_size=64)
val_generator = generator.flow(X_val, y_val, batch_size=64)

Bereiten Sie auch eine Tensorplatte vor, um die Lernsituation und die Ergebnisse besser erkennen zu können. Die Standardausgabe gibt eine URL aus. Öffnen Sie sie daher in Ihrem Browser.


#Start von Tensorboard

import tensorflow as tf 
!rm -rf ./logs/ 
!mkdir ./logs/
!wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
!unzip ngrok-stable-linux-amd64.zip

import os
import multiprocessing
import datetime

pool = multiprocessing.Pool(processes = 10)
results_of_processes = [pool.apply_async(os.system, args=(cmd, ), callback = None )
                        for cmd in [
                        f"tensorboard --logdir ./logs/ --host 0.0.0.0 --port 6006 &",
                        "./ngrok http 6006 &","y"
                        ]]
! curl -s http://localhost:4040/api/tunnels | python3 -c \
    "import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])"

        
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=0)

Jetzt, da wir bereit sind, ist es Zeit zu lernen. Es zeigt den Lernfortschritt mit dem Fortschrittsbalken und dem durch Kompilieren angegebenen Index.


#Daten lernen mit epoch3
# ~Ich denke, es wird ungefähr 15 Minuten dauern
import tensorflow as tf
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    history_linear=model_linear.fit_generator(generator=train_generator,
                                              steps_per_epoch=train_generator.n, 
                                              epochs=3, 
                                              validation_data=val_generator, 
                                              validation_steps=val_generator.n, 
                                              callbacks=[tensorboard_callback]
                                             )

image.png

Die obigen Ergebnisse zeigen, wie gelernt wird, aber wir werden die Ergebnisse für ein intuitiveres Verständnis visualisieren.

Wenn wir uns die Verluste ansehen, können wir sehen, dass Überlernen auftritt, weil die Validierungsergebnisse mit fortschreitendem Lernen zunehmen. Beachten Sie andererseits, dass die Validierung von ACC (korrekte Antwortrate) nicht monoton abgenommen hat. Diskontinuierliche Indikatoren wie ACC sind schwer zu handhaben. Stattdessen optimieren Sie mit einer benutzerfreundlichen Verlustfunktion.

#Visualisierung der Ergebnisse

#Definition der Funktion zum Zeichnen des Ergebnisses
def plt_history(history,keys):
    history_dict = history.history
    n = len(keys)
    f, ax = plt.subplots(n,figsize=(8,4*n))
    for i in range(n):
        train_value = history_dict[keys[i][0]]
        val_value = history_dict[keys[i][1]]
        epochs = range(1, len(train_value) + 1)
        if n==1:
            ax.plot(epochs, train_value, 'bo',label = keys[i][0])
            ax.plot(epochs, val_value, 'b+',label = keys[i][1])
            ax.legend()
            ax.set_xlabel('Epochs')
            ax.set_ylabel(keys[i][0])
        else:
            ax[i].plot(epochs, train_value, 'bo',label = keys[i][0])
            ax[i].plot(epochs, val_value, 'b+',label = keys[i][1])
            ax[i].legend()
            ax[i].set_xlabel('Epochs')
            ax[i].set_ylabel(keys[i][0])

    plt.show()

#Visualisierung
plt_history(history_linear, [["loss","val_loss"],["acc","val_acc"]])

image.png

Modell 2: Voll gekoppeltes Modell

In diesem Modell wird eine vollständig verbundene Ebene hinzugefügt, um die Ebene zu vertiefen. Wir haben auch den Optimierungsalgorithmus in Adam geändert. (Dies sollte experimentell verglichen werden, um das optimale zu bestimmen.)

Obwohl wir Modelle früher nacheinander definiert und verarbeitet haben, definieren wir im Allgemeinen Modelltypen mit Klassen und Funktionen und erstellen verschiedene Trainingsmodelle mit mehreren verschiedenen Parametern und Trainingsdaten. Daher definieren wir ab hier das Modell mit einer Funktion.

#Modelldefinition
def get_fc_model():
    model = Sequential()
    model.add(Lambda(standardize,input_shape=(28,28,1)))
    model.add(Flatten())
    model.add(Dense(512, activation='relu'))
    model.add(Dense(10, activation='softmax'))
    model.compile(optimizer = Adam(), 
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])
    return model


model_fc = get_fc_model()
model_fc.optimizer.lr=0.01
model_fc.summary()

image.png

Lernen Sie das Modell auf die gleiche Weise wie zuvor. Wenn Sie mehrere Modelle in kurzer Zeit ausprobieren möchten, müssen Sie einen Kompromiss eingehen, z. B. die Anzahl der Epochen reduzieren. Wenn wir uns die Ergebnisse ansehen, können wir sehen, dass die Validierungs-ACC höher ist als zuvor.


#Modelllernen
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    history_fc=model_fc.fit_generator(generator=train_generator, 
                                      steps_per_epoch=train_generator.n, 
                                      epochs=1, 
                                      validation_data=val_generator, 
                                      validation_steps=val_generator.n,
                                      callbacks=[tensorboard_callback]
                                     )

#Lernergebnis
history_dict_fc = history_fc.history
history_dict_fc

image.png

Modell 3: CNN-Modell

Versuchen Sie als nächstes das CNN-Modell, das die Faltschicht und die Poolschicht enthält. Da CNN einen weiten Bereich effizient lernen kann, kann bei Bildanalyseproblemen eine hohe Genauigkeit erwartet werden. Dieses Mal werden wir zwei Arten von Schichttiefen vorbereiten und den Unterschied sehen.

#Modelldefinition


from keras.layers import Convolution2D, MaxPooling2D

#Ein Modell mit zwei Falten und zwei Pools
def get_cnn_model1():
    model = Sequential([
        Lambda(standardize, input_shape=(28,28,1)),
        Convolution2D(32,(3,3), activation='relu'),
        MaxPooling2D(),
        Convolution2D(64,(3,3), activation='relu'),
        MaxPooling2D(),
        Flatten(),
        Dense(512, activation='relu'),
        Dense(10, activation='softmax')
        ])
    model.compile(optimizer = Adam(), loss='categorical_crossentropy',
                  metrics=['accuracy'])
    return model

#Ein Modell mit jeweils 3 Falten und Poolen
def get_cnn_model2():
    model = Sequential([
        Lambda(standardize, input_shape=(28,28,1)),
        Convolution2D(32,(3,3), activation='relu'),
        MaxPooling2D(),
        Convolution2D(64,(3,3), activation='relu'),
        MaxPooling2D(),
        Convolution2D(128,(3,3), activation='relu'),
        MaxPooling2D(),
        Flatten(),
        Dense(512, activation='relu'),
        Dense(10, activation='softmax')
        ])
    model.compile(optimizer = Adam(), loss='categorical_crossentropy',
                  metrics=['accuracy'])
    return model

model_cnn1 = get_cnn_model1()
model_cnn2 = get_cnn_model2()
model_cnn1.optimizer.lr=0.01
model_cnn2.optimizer.lr=0.01

Das flache Modell lernt 843.658 Parameter

model_cnn1.summary()

image.png

Das tiefere Modell lernt 163.850 Parameter, was weniger als model_cnn1 ist. Dies liegt daran, dass der periphere Effekt der Faltschicht und der Poolschicht die Dateneingabe in die vollständig verbundene Schicht stark reduziert. In Bezug auf die Abflachungsdimensionen waren es 1600 für cnn1, aber nur 128 für cnn2. Wenn die Größe des Bildes groß ist, ist es wünschenswert, die Größe der Daten auf diese Weise zu verringern, aber welche Art von Ergebnis wird mit kompakten Daten wie dieser Zeit erzielt?

model_cnn2.summary()

image.png

Wir werden jeden studieren.


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    history_cnn1=model_cnn1.fit_generator(generator=train_generator, 
                                     steps_per_epoch=train_generator.n, 
                                     epochs=1, 
                                     validation_data=val_generator, 
                                     validation_steps=val_generator.n, 
                                     callbacks=[tensorboard_callback]
                                    )

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    history_cnn2=model_cnn2.fit_generator(generator=train_generator, 
                                     steps_per_epoch=train_generator.n, 
                                     epochs=1, 
                                     validation_data=val_generator, 
                                     validation_steps=val_generator.n, 
                                     #callbacks=[tensorboard_callback]
                                    )

Lassen Sie uns das Ergebnis überprüfen.

Im Vergleich zum CNN-Modell mit einer flachen Schicht weist das CNN-Modell mit einer tiefen Schicht sowohl hinsichtlich der Verlust- als auch der Genauigkeitsrate sowohl für Trainingsdaten als auch für Validierungsdaten schlechte Ergebnisse auf. Dafür gibt es mehrere mögliche Gründe.

① Das Modell ist schlecht Der Grund, warum das Modell schlecht ist, ist, dass die Trainingsparameter abgenommen haben. Die Tatsache, dass viele Parameter angepasst werden können, bedeutet, dass Sie einen vielfältigeren Ausdruck erstellen können. Dieses Modell hat eine kleine Anzahl von Parametern, so dass es möglicherweise nicht ausreichend aussagekräftig war.

② Die Lerndaten sind schlecht Übertraining tritt wahrscheinlich auf, wenn die Anzahl der Trainingsdaten nicht ausreicht. Diesmal ist die korrekte Antwortrate der Trainingsdaten nicht so schlecht, aber das Validierungsergebnis weist eine große Divergenz auf, was ein typischer Übertrainingszustand ist. Möglicherweise können Verbesserungen vorgenommen werden, indem die zu testenden Daten von nun an erweitert werden.

③ Mangel an Lernen Möglicherweise wurde das Modell noch nicht vollständig trainiert. In diesem Fall ist der Verlust von Trainingsdaten größer als der von cnn1. Wenn Sie also die Epoche verlängern, kann das Training fortgesetzt werden. Die Abweichung von der Validierung ist jedoch ein weiteres Problem, sodass eine Erhöhung der Epoche in diesem Zustand keine wesentliche Lösung darstellt.

history_cnn1.history

image.png

history_cnn2.history

image.png

Datenerweiterung

Es wird angenommen, dass je mehr Trainingsdaten vorhanden sind, desto höher ist die Generalisierungsleistung = Überlernen ist weniger wahrscheinlich. Die Datenerweiterung ist eine Methode zum künstlichen Erhöhen von Trainingsdaten aus einer begrenzten Anzahl von Daten. Die Datenerweiterung ist eine Technik zum Aufblasen von Daten, indem geringfügige Änderungen an den angegebenen Daten vorgenommen werden.

#Datenerweiterung

from keras.preprocessing import image


DA_generator =image.ImageDataGenerator(rotation_range=10, 
                                 width_shift_range=0.1, 
                                 shear_range=0.1,
                                 height_shift_range=0.1, 
                                 zoom_range=0.1)
train_DA_generator = DA_generator.flow(X_train, y_train, batch_size=64)
val_DA_generator = DA_generator.flow(X_val, y_val, batch_size=64)

#Beispiel für erweiterte Daten
tmp_gen = DA_generator.flow(X_train[0].reshape((1,28,28,1)), batch_size = 1)
for i, tmp in enumerate(tmp_gen):
    plt.subplot(330 + (i+1))
    plt.imshow(tmp.reshape((28,28)), cmap=plt.get_cmap('gray'))
    if i == 8:
        break

image.png

Ich denke, das Lernen wird ungefähr 15 Minuten dauern. Durch die Datenerweiterung wurden die Validierungsergebnisse verbessert. Die Trainingsdatenergebnisse und Validierungsergebnisse werden für jede Epoche verbessert. Wenn Sie also Zeit haben, versuchen Sie, die Epoche zu verlängern und zu experimentieren.

#CNN 1 Schicht flache CNN

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    model_cnn1.optimizer.lr=0.005
    history_cnn1_DA=model_cnn1.fit_generator(generator=train_DA_generator, 
                                          steps_per_epoch=train_DA_generator.n, 
                                          epochs=1, 
                                          validation_data=val_DA_generator, 
                                          validation_steps=val_DA_generator.n, 
                                          callbacks=[tensorboard_callback]
                                         )

history_cnn1_DA.history

image.png

Modell 4: Chargennormalisierung

In den Vorgängermodellen wurde die Eingabe standardisiert. Dies garantiert jedoch nicht, dass die Ausgabe jeder Schicht standardisiert ist. Nach einer bestimmten Schicht wird die Ausgabe sehr groß und die Parameter können sehr klein werden. Oder umgekehrt, die Parameter können sehr groß sein.

In einem solchen Fall kann das Lernen nicht gut durchgeführt werden, aber dieses Problem kann durch Hinzufügen einer Batch-Normalisierungsschicht gelöst werden, die für jede Schicht standardisiert wird. Dies soll sowohl die Generalisierungsleistung als auch die Lerngeschwindigkeit verbessern.

Die Anzahl der Epochen wird auch dieses Mal auf 1 gesetzt. Wenn Sie jedoch Zeit haben, erhöhen Sie die Anzahl der Epochen und beobachten Sie den Zustand des Überlernens.


from keras.layers.normalization import BatchNormalization

def get_bn_model():
    model = Sequential([
        Lambda(standardize, input_shape=(28,28,1)),
        Convolution2D(32,(3,3), activation='relu'),
        BatchNormalization(axis=1),
        MaxPooling2D(),
        BatchNormalization(axis=1),
        Convolution2D(64,(3,3), activation='relu'),
        BatchNormalization(axis=1),
        MaxPooling2D(),
        BatchNormalization(axis=1),
        Flatten(),
        BatchNormalization(),
        Dense(512, activation='relu'),
        BatchNormalization(),
        Dense(10, activation='softmax')
        ])
    model.compile(optimizer = Adam(), loss='categorical_crossentropy', metrics=['accuracy'])
    return model
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    model_bn= get_bn_model()
    model_bn.optimizer.lr=0.01
    history_bn=model_bn.fit_generator(generator=train_DA_generator, 
                                      steps_per_epoch=train_DA_generator.n, 
                                      epochs=1, 
                                      validation_data=val_DA_generator, 
                                      validation_steps=val_DA_generator.n,
                                      callbacks=[tensorboard_callback]
                                     )

history_bn.history

image.png

Modell 5: Optimales Modell

Abschließend werde ich das Modell mit der höchsten Punktzahl unter den in diesem Artikel vorgestellten Modellen vorstellen. Das Entwerfen dieses Modells erfordert Versuch und Irrtum, wie das Hinzufügen von Ebenen und das Ändern von Optimierungsfunktionen, wie wir bisher gesehen haben. Dieses optimale Modell ist ein Modell, das eine Reihe von Versuchen und Fehlern durchlaufen hat (in meinen aktuellen Fähigkeiten und meiner Entwicklungsumgebung).

Wir haben eine Dropout-Ebene, die anfängliche Einstellung von He und einen Rückruf hinzugefügt, der die Lernrate Schritt für Schritt ändert.

Infolgedessen markiert die Variation eine korrekte Antwortrate von 99,4%.


from keras.layers import Dense, Dropout, Flatten, Convolution2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.callbacks import ReduceLROnPlateau

def get_opt_model():
    model = Sequential([
        Lambda(standardize, input_shape=(28,28,1)),
        Convolution2D(32,(3,3), activation='relu',kernel_initializer='he_normal'),
        Convolution2D(32,(3,3), activation='relu',kernel_initializer='he_normal'),
        MaxPooling2D(),
        Dropout(0.20),
        Convolution2D(32,(3,3), activation='relu',kernel_initializer='he_normal'),
        Convolution2D(32,(3,3), activation='relu',kernel_initializer='he_normal'),
        MaxPooling2D(),
        Dropout(0.25),
        Convolution2D(32,(3,3), activation='relu',kernel_initializer='he_normal'),
        Dropout(0.25),
        Flatten(),
        Dense(128, activation='relu'),
        BatchNormalization(),
        Dropout(0.25),
        Dense(10, activation='softmax')
    ])
    model.compile(optimizer=Adam(),
                  loss='categorical_crossentropy', 
                  metrics=['accuracy'])
    return model


learning_rate_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                            patience=3, 
                                            verbose=1, 
                                            factor=0.5, 
                                            min_lr=0.0001)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    model_opt = get_opt_model()
    history_opt = model_opt.fit_generator(generator=train_DA_generator, 
                                          steps_per_epoch=train_DA_generator.n, 
                                          epochs=3, 
                                          validation_data=val_DA_generator, 
                                          validation_steps=val_DA_generator.n,
                                          callbacks=[tensorboard_callback, learning_rate_reduction]
                                         )
    Y_pred = model_opt.predict_classes(X_val,verbose = 0)
    Y_pred_prob = model_opt.predict(X_val,verbose = 0)

#Visualisierung der Ergebnisse
plt_history(history_opt, [["loss","val_loss"],["acc","val_acc"]])

image.png

history_opt.history

image.png

Überprüfen Sie das Ergebnis

Selbst im optimalen Modell gab es einige falsche Antworten, aber welche Art von Daten sind falsch? Betrachtet man die gemischte Matrix, so scheint es fast keine falschen Antworten zu geben, aber es gibt einige Fälle, in denen 1 mit 7 und 7 mit 2 verwechselt wird.

#Definition einer Funktion, die eine Verwirrungsmatrix anzeigt
import itertools
def plt_confusion_mtx(confusion_mtx):
    cmap=plt.cm.Reds
    title='Confusion matrix'
    f, ax = plt.subplots(1,figsize=(6,6))
    im = ax.imshow(confusion_mtx, interpolation='nearest', cmap=cmap)
    ax.set_title(title)
    ax.set_xticks(np.arange(10))
    ax.set_yticks(np.arange(10))
    ax.set_xlabel('Predicted label')
    ax.set_ylabel('True label')
    f.colorbar(im)
    thresh = confusion_mtx.max() / 2
    for i, j in itertools.product(range(confusion_mtx.shape[0]), range(confusion_mtx.shape[1])):
        ax.text(j, i, confusion_mtx[i, j],
                horizontalalignment="center",
                color="white" if confusion_mtx[i, j] > thresh else "black")

        

#Anzeige der Verwirrungsmatrix
from sklearn.metrics import confusion_matrix
Y_true = np.argmax(y_val,axis=1) 
confusion_mtx = confusion_matrix(Y_true, Y_pred) 
plt_confusion_mtx(confusion_mtx)

image.png

#Präzision für jede Weltklasse,Rückrufbestätigung etc.

from sklearn.metrics import classification_report
target_names = ["Class {}".format(i) for i in range(10)]
print(classification_report(Y_true, Y_pred, target_names=target_names))

image.png

Wenn Sie sich tatsächlich die falschen Antwortdaten ansehen, gibt es einige Fälle, in denen es für Menschen schwierig ist, sie zu unterscheiden, sondern es wird vermutet, dass die Kennzeichnung falsch ist.

#Bestätigung falscher Antwortdaten

errors = (Y_pred - Y_true != 0)
Y_pred_errors = Y_pred[errors]
Y_pred_prob_errors = Y_pred_prob[errors]
Y_true_errors = Y_true[errors]
X_val_errors = X_val[errors]

def display_errors(errors_index,img_errors,pred_errors, obs_errors):
    """ This function shows 6 images with their predicted and real labels"""
    n = 0
    nrows = 2
    ncols = 3
    fig, ax = plt.subplots(nrows,ncols, figsize = (8,8))
    for row in range(nrows):
        for col in range(ncols):
            error = errors_index[n]
            ax[row,col].imshow((img_errors[error]).reshape((28,28)))
            ax[row,col].set_title("Predicted label :{}\nTrue label :{}".format(pred_errors[error],obs_errors[error]))
            n += 1

errors = (Y_pred - Y_true != 0)
tmp = Y_pred_prob[errors] - to_categorical(Y_pred[errors])
display_index = np.argsort(tmp.max(axis=1))[:6]
display_errors(display_index, X_val_errors, Y_pred_errors, Y_true_errors)

image.png

Man kann sagen, dass das optimale Modell eine ausreichende Leistung aufweist, um dem praktischen Gebrauch standzuhalten.

abschließend

Damit ist die Einführung in die Deep Learning-Bildanalyse von Keras abgeschlossen. Von hier an können Sie versuchen, mit komplexeren Datensätzen zu trainieren, das Lernen mit trainierten Modellen zu übertragen, berühmte Deep-Learning-Modelle auszuprobieren und vieles mehr. Ich werde. Wenn dieser Artikel für jemanden nützlich ist, möchte ich diese Tutorial-Artikel in Zukunft aktualisieren. Bitte unterstützen Sie mich bei LGTM.

Außerdem bin ich immer auf der Suche nach einem Job. Bitte lassen Sie mich wissen, wenn Sie die Gelegenheit dazu haben.

Recommended Posts

Deep Learning Bildanalyse beginnend mit Kaggle und Keras
Emotionale Analyse von Tweets mit Deep Learning
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 9 heraus. Lernen, Speichern und Laden von Modellen
Datenanalyse beginnend mit Python (Datenvorverarbeitung - maschinelles Lernen)
Fügen Sie Ihre eigenen Bilddaten in Deep Learning ein und spielen Sie damit
Maschinelles Lernen von Grund auf neu (maschinelles Lernen mit Kaggle)
Paralleles Lernen von Deep Learning durch Keras und Kubernetes
Bilderkennung mit Keras
Vorhersagen von Tags durch Extrahieren von Musikfunktionen mit Deep Learning
Klassifizieren Sie Anime-Gesichter durch Fortsetzung / Deep Learning mit Keras
Versuchen Sie es mit TensorFlow
Ensemble-Lernen und Korbanalyse
Multiple Regressionsanalyse mit Keras
Deep Learning Bilderkennung 1 Theorie
Verbessertes Lernen ab Python
Deep Kernel Learning mit Pyro
Versuchen Sie Deep Learning mit FPGA
Versuchen Sie es mit Kaggle leicht maschinell
Generiere Pokemon mit Deep Learning
Bilderkennung mit Keras + OpenCV
Bildklassifizierung mit selbst erstelltem neuronalen Netzwerk von Keras und PyTorch
Erkennen Sie Ihren Chef mit Deep Learning und verbergen Sie den Bildschirm
[Deep Learning] Bildklassifizierung mit Faltungsnetz [DW Tag 4]
Erstellen Sie eine GPU-Umgebung mit GCP und kaggle offiziellem Image (Docker)
Deep Learning mit Shogi AI auf Mac und Google Colab
HIKAKIN und Max Murai mit Live-Spielvideo und Deep Learning
Probieren Sie Deep Learning mit FPGA-Select-Gurken aus
Identifikation der Katzenrasse mit Deep Learning
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 11
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 1-6
Vorhersage der Titanic von Kaggle mit Keras (kaggle ⑦)
Bildsegmentierung mit Scikit-Image und Scikit-Learn
Ich habe versucht, Deep Learning mit Spark × Keras × Docker skalierbar zu machen
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 8
Versuchen Sie es mit TensorFlow Part 2
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 12 3
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 7
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 10 6-9
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 10
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 7 5-7
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 9
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 12 3
Vergleichen Sie DCGAN und pix2pix mit Keras
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 12 3
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 12 1-2
Organisation von Plattformen für maschinelles Lernen und tiefes Lernen
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 12 3
[Lesehinweis] Praktisches maschinelles Lernen mit Scikit-Learn, Keras und TensorFlow Kapitel 1
Überprüfen Sie die Kniebeugenform mit tiefem Lernen
Deep Learning Bilderkennung 2 Modellimplementierung
Kategorisieren Sie Nachrichtenartikel mit Deep Learning
Snack-Umsatzprognose mit Deep Learning
Bringen Sie Menschen mit Deep Learning zum Lächeln
Datenanalyse beginnend mit Python (Datenvisualisierung 1)
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 12 3 ~ 5
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 7 9
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 8 5-9
Deep Learning mit Shogi AI auf Mac und Google Colab Kapitel 8 1-4