Dies ist ein Studienmemo (4.) zur Bildklassifizierung (Google Colaboratory-Umgebung) mit TensorFlow2 + Keras. Das Thema ist die Klassifizierung von handgeschriebenen numerischen Bildern (MNIST), die ein Standardelement ist.
Letztes Mal bildete die erfassten MNIST-Daten (handschriftliche Zeichendaten) mit matplotlib ab. Dieses Mal werden wir "** Vorhersage **" mit dem trainierten Modell versuchen. Außerdem werden Berichtsbilder für Prognosen generiert, z.
Der in Teil 1 gezeigte Beispielcode für "Vorerst verschieben" war wie folgt.
python
import tensorflow as tf
# (1)Laden Sie den handschriftlichen numerischen Bilddatensatz (MNIST) herunter und speichern Sie ihn in einer Variablen
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# (2)Datennormalisierung (Vorverarbeitung)
x_train, x_test = x_train / 255.0, x_test / 255.0
# (3)Erstellen eines NN-Modells
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
# (4)Kompilieren des Modells (einschließlich Einstellungen zur Lernmethode)
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
# (5)Modelltraining (unter Verwendung von Eingabedaten und korrekten Antwortdaten für das Training)
model.fit(x_train, y_train, epochs=5)
# (6)Modellbewertung (unter Verwendung von Testeingabedaten und korrekten Antwortdaten)
model.evaluate(x_test, y_test, verbose=2)
In diesem Prozess wird ** (6) ** model.evaluate (...)
, "** Vorhersage (Klassifizierung) unter Verwendung eines trainierten Modells **" für die Eingabedaten x_test
zum Testen durchgeführt. Dann wurden die korrekten Antwortdaten "y_test" verwendet, um mit den Vorhersageergebnissen übereinzustimmen, und das Ergebnis der Bewertung der Modellleistung wie "Verlust: 0,0766 - Genauigkeit: 0,9762" wurde ausgegeben.
In diesem model.evaluate (...)
ist es jedoch nicht möglich, spezifisch zu bestätigen, "welche Art von Eingabedaten vorhergesagt (klassifiziert) wurden?". Um dies zu überprüfen, verwenden Sie die folgenden "Predict_classes (...)" oder "Predict (...)".
Verwenden Sie "Predict_classes (...)", um die ** Vorhersageergebnisse ** aller handgeschriebenen Textdaten unter Verwendung des trainierten Modells zu erhalten.
Als Beispiel möchte ich die Vorhersage und das Ergebnis für die ersten 5 Blätter der Testeingabedaten "x_test [: 5]" erhalten. Außerdem werden die Antworten durch Vergleichen mit den korrekten Antwortdaten "y_test" abgeglichen.
python
# x_Testvorhersage (Klassifizierung)
s = model.predict_classes( x_test[:5] )
print(s) #Ausführungsergebnis-> [7 2 1 0 4]
# y_Stimmen Sie die Antworten durch Vergleich mit dem Test ab
a = y_test[:5]
print(a) #Ausführungsergebnis-> [7 2 1 0 4]
print(a==s) #Ausführungsergebnis-> [True True True True True]
Wenn Sie dem Argument "Predict_classes (...)" ein Array von Eingabedaten vom Typ numpy.ndarray geben, wird das Vorhersageergebnis vom Typ numpy.ndarray angegeben.
Gehen Sie wie folgt vor, um nur einzelne Daten (ein Bild) vorherzusagen (zu klassifizieren).
python
import numpy as np
target = x_test[0] #Bereiten Sie einzelne Eingabedaten vor
s = model.predict_classes( np.array([target]) )
#s = model.predict_classes( target.reshape([1,28,28]) ) #Auch hier OK
print(s[0]) #Ausführungsergebnis-> 7
Der Rückgabewert von "Predict_classes (...)" hat uns ein Vorhersageergebnis (Klassifizierungsergebnis) geliefert, aber Sie möchten vielleicht mehr darüber erfahren **. Mit anderen Worten, im obigen Beispiel gab es für die Informationen in der Phase vor Erreichen der Schlussfolgerung von "7" beispielsweise keine Möglichkeit, dass sie als ** "1" ** oder ** "1" betrachtet werden könnten? Die Möglichkeit war ziemlich hoch, aber sind Sie mit einem kleinen Vorsprung zum Schluss von "7" gekommen? Die Information ist **.
Verwenden Sie "Vorhersagen (...)", um diese Informationen zu erhalten. Der Rückgabewert ist eine Information wie der "Sicherheitsgrad", dessen Kategorie von 0 bis 9 klassifiziert werden kann (Wert in der Ausgabeschicht des NN-Modells). Der Wert reicht von 0,0 bis 1,0 und je näher er an 1,0 liegt, desto größer ist die Sicherheit, dass er in die Kategorie eingeteilt werden kann.
Ich denke, es ist einfacher zu verstehen, wenn man es konkret betrachtet. Wie im vorherigen Beispiel bestätigt, wurde "x_test [0]" als "7" vorhergesagt (klassifiziert), was aus dem Ausgabewert der Ausgabeschicht wie folgt beurteilt wird.
import numpy as np
target = x_test[0]
s = model.predict( np.array([target]) )
print(s[0]) #Ausführungsergebnis-> [2.8493771e-08 2.6985079e-08 8.6063519e-06 3.0076344e-04 1.7041087e-10
# 1.2664158e-07 1.4036484e-13 9.9965346e-01 4.4914569e-07 3.6610269e-05]
#Formatiert, um bis zum zweiten Bruch anzuzeigen
s = [ f'{s:.2f}' for s in s[0]]
print(s) #Ausführungsergebnis-> ['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '1.00', '0.00', '0.00']
Dies ist die endgültige Ausgabe von "print (s)", aber ab dem 0. zählt der 7. "1.00". Mit anderen Worten, wir können sehen, dass das NN-Modell ein starkes Vertrauen in die prädiktive Klassifizierung von "7" hat.
In diesem Beispiel ist es jedoch nicht sehr interessant, daher werde ich versuchen, ein leicht subtiles handgeschriebenes Zeichen zu verwenden. "x_test [1003]" sind die folgenden Daten, wenn sie abgebildet werden (sie können durch "y_test [1003]" bestätigt werden, aber "5" ist die richtige Antwort).
Wenn Sie für diesen "x_test [1003]" den Rückgabewert von "Vorhersagen (...)" erhalten und ihn überprüfen, ist dies wie folgt.
python
import numpy as np
target = x_test[1003]
s = model.predict( np.array([target]) )
s = [ f'{s:.2f}' for s in s[0]] #Gestaltung
print(s)
#Ausführungsergebnis-> ['0.00', '0.00', '0.00', '0.27', '0.00', '0.73', '0.00', '0.00', '0.01', '0.00']
Es stellt sich heraus, dass das NN-Modell mit der Möglichkeit endet, dass es mit starker Überzeugung eher eine "3" als eine "5" sein kann.
Beachten Sie, dass argmax ()
inPredict (...)
Matches Predict_classes (...)
wie folgt übereinstimmt: argmax () gibt die Indexnummer des Elements mit dem höchsten Wert im Array zurück.
python
import numpy as np
target = x_test[1003]
s = model.predict( np.array([target]) )
p = model.predict_classes( np.array([target]) )
print( s.argmax() == p[0] ) #Ausführungsergebnis-> True
Wir werden matplotlib verwenden, um den folgenden Bericht zu erstellen, der die Eingabedaten (dh das handgeschriebene numerische Bild) und das vorhergesagte Ausgabediagramm des trainierten Modells kombiniert.
matplotlib_Japanischer Prozess zur Vorbereitung der Ausgabe
!pip install japanize-matplotlib
import japanize_matplotlib
python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as pe
import matplotlib.transforms as ts
idn = 1601 #Index der Zieltestdaten (0 bis 9999)
s_test = model.predict(x_test) #Vorhersage mit einem trainierten Modell
fig, ax = plt.subplots(nrows=2,figsize=(3,4.2), dpi=120,
gridspec_kw={'height_ratios': [3, 1]})
plt.subplots_adjust(hspace=0.05) #Abstand zwischen oberen und unteren Diagrammen
#Zeigen Sie das Bild der handgeschriebenen Zahlen auf der Oberseite an
ax[0].imshow(x_test[idn],interpolation='nearest',vmin=0.,vmax=1.,cmap='Greys')
ax[0].tick_params(axis='both', which='both', left=False,
labelleft=False, bottom=False, labelbottom=False)
#Der richtige Antwortwert und der vorhergesagte Wert werden oben links angezeigt
t = ax[0].text(0.5, 0.5, f'Richtige Antwort:{y_test[idn]}',
verticalalignment='top', fontsize=9, color='tab:red')
t.set_path_effects([pe.Stroke(linewidth=2, foreground='white'), pe.Normal()])
t = ax[0].text(0.5, 2.5, f'Prognose:{s_test[idn].argmax()}',
verticalalignment='top', fontsize=9, color='tab:red')
t.set_path_effects([pe.Stroke(linewidth=2, foreground='white'), pe.Normal()])
#Zeigen Sie die NN-Vorhersageausgabe unten an
b = ax[1].bar(np.arange(0,10),s_test[idn],width=0.95)
b[s_test[idn].argmax()].set_facecolor('tab:red') #Machen Sie den maximalen Gegenstand rot
#X-Achseneinstellung
ax[1].tick_params(axis='x',bottom=False)
ax[1].set_xticks(np.arange(0,10))
t = ax[1].set_xticklabels(np.arange(0,10),fontsize=11)
t[s_test[idn].argmax()].set_color('tab:red') #Machen Sie den maximalen Gegenstand rot
offset = ts.ScaledTranslation(0, 0.03, plt.gcf().dpi_scale_trans)
for label in ax[1].xaxis.get_majorticklabels() :
label.set_transform(label.get_transform() + offset)
#Einstellung der Y-Achse
ax[1].tick_params(axis='y',direction='in')
ax[1].set_ylim(0,1)
ax[1].set_yticks(np.linspace(0,1,5))
ax[1].set_axisbelow(True)
ax[1].grid(axis='y')
――Nächstes Mal, wie unten gezeigt, welche Art von handgeschriebenen Zahlen nicht vorhersagen (klassifizieren) und welche Art von Fehlklassifizierung vorliegt („7“ und „1“ sind falsch) Ist es einfach?) Würde ich gerne sehen. matplotlib funktioniert gut.
■ Fälle, in denen der richtige Antwortwert "6" nicht richtig vorhergesagt (klassifiziert) werden konnte
Recommended Posts