[PYTHON] Fordern Sie die Bildklassifizierung durch TensorFlow2 + Keras 5 heraus ~ Beobachten Sie Bilder, die nicht klassifiziert werden können ~

Einführung

Dies ist ein Studienmemo (5.) zur Bildklassifizierung (Google Colaboratory-Umgebung) mit TensorFlow2 + Keras. Das Thema ist die Klassifizierung von handgeschriebenen numerischen Bildern (MNIST), die ein Standardelement ist.

Letztes Mal machte Vorhersagen (Klassifizierungen) unter Verwendung trainierter Modelle. Diesmal schlägt in dem von TF Official HP Tutorial erstellten Modell ** welche Art von Bild die Vorhersage (Klassifizierung) fehl? ** Auch ** Welche Art von Fehlklassifizierung wird auftreten? Ich werde ** beobachten.

Insbesondere mit matplotlib wird wie folgt ausgegeben.

■ Fälle, in denen der richtige Antwortwert "6" nicht richtig vorhergesagt (klassifiziert) werden konnte x6.png

Wir werden auch ein Diagramm erstellen, das die folgenden Fehlklassifizierungsbeziehungen zeigt.

Heat map.png

Extraktion handschriftlicher numerischer Daten, die nicht klassifiziert werden konnten

Extrahieren Sie aus den 10.000 Testeingabedaten (Bilder handgeschriebener Zahlen) ** diejenigen, die nicht korrekt klassifiziert werden konnten **, indem Sie das Modell des TF-Tutorials verwenden.

Übrigens, als das trainierte Modell mit "model.evaluate (x_test, y_test, verbose = 2)" bewertet wurde, betrug die korrekte Antwortrate (Genauigkeit) 0,9759. Daher konnten $ (1-0.9759) \ mal 10.000 = 241 $ handgeschriebene Zahlen nicht klassifiziert werden (das für jeden Trainingslauf generierte trainierte Modell unterscheidet sich geringfügig, was zu einer Klassifizierung führt. Bitte beachten Sie, dass die fehlgeschlagenen Bilder ebenfalls geringfügig abweichen.

Für diesen Extraktionsprozess verwenden wir die Bibliothek "pandas", die für die Datenanalyse geeignet ist. Da die Erklärung zu den Grundlagen von Pandas nicht enthalten ist, lesen Sie dazu bitte andere Artikel.

Der folgende Code speichert die korrekten und vorhergesagten Werte in einer Spalte des Datenrahmens. Hier stimmt der Zeilenindex mit dem Index "x_test" überein.

python


import numpy as np
import pandas as pd
p_test = model.predict_classes(x_test) #Prognose
df = pd.DataFrame({'Richtiger Antwortwert':y_test, 'Voraussichtlicher Wert':p_test})
display(df.head(5))  #Zeigen Sie 5 Zeilen von Anfang an an
display(df.tail(5))  #Zeigen Sie 5 Zeilen vom Ende an

Das Ausführungsergebnis ist wie folgt. Für die ersten 5 Fälle und die letzten 5 Fälle stimmen der richtige Antwortwert und der vorhergesagte Wert überein.

pd1.png

Als nächstes ** extrahieren Sie die Zeilen, in denen die korrekten und vorhergesagten Werte nicht übereinstimmen ** und speichern sie in einem neuen Datenrahmen "df2". Es sortiert auch.

python


#Extrahieren Sie Zeilen, in denen "richtige Antwort" und "Vorhersage" nicht übereinstimmen
df2 = df[df['Richtiger Antwortwert']!=df['Voraussichtlicher Wert']]
display(df2.head(5))

#In aufsteigender Reihenfolge sortieren 1. Schlüssel'Richtiger Antwortwert', 2. Taste'Voraussichtlicher Wert'
df2 = df2.sort_values(['Richtiger Antwortwert', 'Voraussichtlicher Wert'])
display(df2.head(5))

Das Ausführungsergebnis ist wie folgt. pd2.png

Daraus können wir erkennen, dass "x_test [9634]" "**" ist. Die richtige Antwort ist "0", aber die Vorhersage ist "1" ** ".

Listenanzeige von handgeschriebenen Zahlenbildern, die nicht klassifiziert werden konnten

Der x_test [9634], der ** welche Art von handgeschriebener Zahl ** nicht klassifizieren konnte ** und ** fälschlicherweise "1" vorhersagt. Wie überzeugt war das? ** Ich bin neugierig.

** Was für eine handschriftliche Nummer ist ** ist ein Bild, wenn Sie imshow (...) von matplotlib verwenden, wie in Teil 2 erläutert. Sie können ausgeben und überprüfen.

Außerdem wurde in 4. erklärt, wie sicher es war, dass ich fälschlicherweise "1" vorhergesagt habe. Wie Sie sehen können, kann es aus den Informationen von model.predict (...) abgerufen werden. Insbesondere kann es erhalten werden, indem das Folgende getan wird.

python


idn = 9634
s = model.predict( np.array([x_test[idn]]) ) #Ausgabeschichtwert
s = s[0]
print( f'Die prädiktive Klassifizierung lautet "{s.argmax()}, Der Ausgabewert des entsprechenden Neurons in der Ausgabeschicht{s[s.argmax()]:.2f}' ) 
print( f'Die richtige Antwortklassifizierung lautet "{y_test[idn]}, Der Ausgabewert des entsprechenden Neurons in der Ausgabeschicht{s[y_test[idn]]:.2f}' )

Die prädiktive Klassifizierung ist "1" und der Ausgabewert des entsprechenden Neurons in der Ausgabeschicht beträgt 0,62. Die korrekte Antwortklassifizierung lautet "0" und der Ausgabewert des entsprechenden Neurons in der Ausgabeschicht beträgt 0,00.

Alternativ können Sie den Code (Berichtsausgabe der prädiktiven Klassifizierung) verwenden, der am Ende von 4. angezeigt wird, um Folgendes zu überprüfen.

9634.png

Die richtige Antwort "0" ist nicht einmal schwach. Es kann unvermeidlich sein, da es sich um ein Bild mit Staub oben links handelt. Wenn Sie diese Dinge jedoch beobachten können, können Sie möglicherweise einige Hinweise zur Vorverarbeitung erhalten **.

Es ist jedoch mühsam, diese einzeln auszugeben, daher möchte ich sie alle zusammen ausgeben.

python


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as pe

for t in range(0,10):

  print(f'■ Richtiger Antwortwert "{t}Wurde nicht richtig vorhergesagt (klassifiziert)')

  #Zeilen mit korrektem Wert t extrahieren
  index_list = list(df2[df2['Richtiger Antwortwert']==t].index.values)

  #matplotlib Ausgabe
  n_cols = 7
  n_rows = ((len(index_list)-1)//n_cols)+1
  fig, ax = plt.subplots(nrows=n_rows, ncols=n_cols, figsize=(6.5, 0.9*n_rows), dpi=120)
  for i,ax in enumerate( np.ravel(ax) ):
    if i < len(index_list):
      
      p = index_list[i]
      ax.imshow(x_test[p],interpolation='nearest',vmin=0.,vmax=1.,cmap='Greys')

      #Die Vorhersage (Klassifizierung) wird oben links angezeigt
      t = ax.text(1, 1, f'{p_test[p]}', verticalalignment='top', fontsize=8, color='tab:red')
      t.set_path_effects([pe.Stroke(linewidth=2, foreground='white'), pe.Normal()]) 

      #Die Werte der Neuronen in der Ausgabeschicht, die der Vorhersage (Trennung) entsprechen, werden in Klammern angezeigt.
      t = ax.text(5, 2, f'({s_test[p].max():.1f})', verticalalignment='top', fontsize=6, color='tab:red')
      t.set_path_effects([pe.Stroke(linewidth=2, foreground='white'), pe.Normal()]) 
      
      #Skala ausblenden usw.
      ax.tick_params(axis='both', which='both', left=False, labelleft=False, 
                     bottom=False, labelbottom=False)
      
      #Index wird blau angezeigt
      ax.set_title(index_list[i],fontsize=7,pad=1.5,color='tab:blue')

    else :
      ax.axis('off') #Margin-Verarbeitung

  plt.show()

Dies ist das Ausführungsergebnis (nur das als Text ausgegebene Teil ist leicht formatiert).

■ Fall, in dem der richtige Antwortwert "0" nicht richtig vorhergesagt (klassifiziert) werden konnte x0.png

■ Fälle, in denen der richtige Antwortwert "1" nicht richtig vorhergesagt (klassifiziert) werden konnte x1.png

■ Fälle, in denen der richtige Antwortwert "2" nicht richtig vorhergesagt (klassifiziert) werden konnte x2.png

■ Fälle, in denen der richtige Antwortwert "3" nicht richtig vorhergesagt (klassifiziert) werden konnte x3.png

■ Fälle, in denen der richtige Antwortwert "4" nicht richtig vorhergesagt (klassifiziert) werden konnte x4.png

■ Fälle, in denen der richtige Antwortwert "5" nicht richtig vorhergesagt (klassifiziert) werden konnte x5.png

■ Fälle, in denen der richtige Antwortwert "6" nicht richtig vorhergesagt (klassifiziert) werden konnte x6.png

■ Fälle, in denen der richtige Antwortwert "7" nicht richtig vorhergesagt (klassifiziert) werden konnte x7.png

■ Fälle, in denen der richtige Antwortwert "8" nicht richtig vorhergesagt (klassifiziert) werden konnte x8.png

■ Fälle, in denen der richtige Antwortwert "9" nicht richtig vorhergesagt (klassifiziert) werden konnte x9.png

Impressionen

Wenn Sie es so betrachten, können Sie sehen, dass es Daten enthält, die auf keinen Fall erkannt werden können (selbst wenn Menschen es beurteilen ...). Auf der anderen Seite, aus menschlicher Sicht, warum missverstehen Sie so etwas? Da ist auch das Ergebnis. Es ist interessant.

Kreuztabelle

Erstellen wir eine ** Kreuztabelle ** für korrekte und vorhergesagte Werte. Dies macht es leicht, welche Nummer ** in welche Nummer falsch einzuordnen? Sie können Informationen wie ** erhalten. Kreuztabellen können einfach mit "Kreuztabelle (...)" erstellt werden.

python


import pandas as pd

p_test = model.predict_classes(x_test) #Prognose
df = pd.DataFrame({'Richtiger Antwortwert':y_test, 'Voraussichtlicher Wert':p_test})

#Kreuztabelle
dfc = pd.crosstab(index=df['Richtiger Antwortwert'], columns=df['Voraussichtlicher Wert']) 
display(dfc)

Das Ausführungsergebnis ist wie folgt.

ct.png

Es scheint, dass es 19 Fälle gibt, in denen "4" als "9" falsch klassifiziert ist (Sie können es irgendwie verstehen). Als nächstes klassifizierten 13 Fälle "3" bis "5" falsch und 12 Fälle "9" bis "3" falsch (dies unterscheidet sich vom menschlichen Gefühl und ist interessant. Apropos).

Visualisierung

Lassen Sie uns die Kreuztabelle mit matplotlib als Heatmap ausgeben. Der Code wird lang sein, daher werde ich zuerst das Ergebnis anzeigen.

ヒートマップ.png

matplotlib_Japanischer Prozess zur Vorbereitung der Ausgabe


!pip install japanize-matplotlib
import japanize_matplotlib

python


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as pe
import matplotlib.ticker as ticker
import matplotlib.colors

p_test = model.predict_classes(x_test) #Prognose
df = pd.DataFrame({'Richtiger Antwortwert':y_test, 'Voraussichtlicher Wert':p_test})

#Kreuztabelle
dfc = pd.crosstab(index=df['Richtiger Antwortwert'], columns=df['Voraussichtlicher Wert']) 
#display(dfc)

for i in dfc.index.values :
  dfc.at[i,i] = 0.0

#Ausgabe als Heatmap
plt.figure(dpi=160)

plt.imshow(dfc,interpolation='nearest',cmap='Oranges')
plt.plot([0,0],[9,9])

n = len(dfc.columns) #Anzahl der Teile
plt.gca().set_xticks(range(n))
plt.gca().set_xticklabels(dfc.columns)
plt.gca().set_yticks(range(n))
plt.gca().set_yticklabels(dfc.columns)

plt.tick_params(axis='x', which='both', direction=None, 
                top=True, bottom=False, labeltop=True, labelbottom=False)
plt.tick_params(axis='both', which='both', top=False, left=False )

#Rastereinstellungen
plt.gca().set_xticks(np.arange(-0.5, n-1), minor=True);
plt.gca().set_yticks(np.arange(-0.5, n-1), minor=True);
plt.grid( which='minor', color='white', linewidth=1)

plt.gca().xaxis.set_label_position('top') 
plt.xlabel('Voraussichtlicher Wert')
plt.ylabel('Richtiger Antwortwert')

plt.plot([-0.5,n-0.5],[-0.5,n-0.5],color='black',linewidth=0.75)

#Korrelationskoeffizienten anzeigen (Text mit Rand)
tp = dict(horizontalalignment='center',verticalalignment='center')
ep = [pe.Stroke(linewidth=3, foreground='white'),pe.Normal()]
for y,i in enumerate(dfc.index.values) :
  for x,c in enumerate(dfc.columns.values) :
    if x != y :
      if dfc.at[i,c] !=  0:
        t = plt.text(x, y, f'{dfc.at[i,c]}',**tp)
        t.set_path_effects(ep) 

nächstes Mal

――Nächstes Mal werde ich anhand der von mir erstellten handschriftlichen Daten eine Vorhersage treffen. Enthält Schritte zum Hochladen von Bildern in Google Colab., Laden von Bildern, Ändern der Größe und andere Vorverarbeitung.

予測.png

Recommended Posts