[PYTHON] Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras heraus. 6-Versuchen Sie, die von Ihnen erstellten Bilder vorzuverarbeiten und zu klassifizieren.

Einführung

Dies ist ein Studienmemo (6. Ausgabe) 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 eine Vorhersage (Klassifizierung) unter Verwendung des handgeschriebenen numerischen Bildes, das zuvor von MNIST erstellt wurde. Dieses Mal möchte ich ein Bild verwenden, das ich selbst erstellt habe, um die Modelle als trainiert zu klassifizieren. Darüber hinaus möchte ich das Python-Programm (unter Verwendung der Pillow-Bibliothek) erläutern, das sich auf die ** Vorverarbeitung bezieht, z. B. das Ändern der Größe und das Trimmen **, die zu diesem Zeitpunkt erforderlich waren.

予測.png

前後.png

Erstellen handgeschriebener Zahlenbilder

Ich habe durch Malen ein handgeschriebenes Zeichen von "** 8 **" mit einer Größe von ** 100 ** $ \ mal $ ** 100 ** Pixel erstellt und es als Farb-PNG-Datei (RGB) gespeichert. Ich habe es "test-8.png " genannt.

test-8.png

プロパティ.png

Laden Sie Bilddateien in Google Colab hoch.

Sie können hochladen, indem Sie die Registerkarte Datei im Seitenmenü von Google Colab aktivieren und wie folgt per Drag & Drop von Ihrem Desktop ziehen: Die hochgeladene Datei wird ** nach einer bestimmten Zeit ** gelöscht **.

ファイルアップロード.png

Sie können auch über den Dateiauswahldialog hochladen, indem Sie eine Codezelle schreiben und wie folgt ausführen.

ファイルアップロード2.png

Der absolute Pfad der hochgeladenen Datei (test-8.png) lautet / content / test-8.png. Da das aktuelle Verzeichnis "/ content" ist, können Sie auch mit "test-8.png " darauf zugreifen.

Sie können auch Google Drive bereitstellen und danach suchen. Weitere Informationen finden Sie unter Google Colaboratory (von der ersten Verwendung bis zum Laden von Dateien) @ Qiita.

Bilddatei lesen und Inhalt prüfen

Laden Sie die hochgeladene Bilddatei und zeigen Sie sie zur Überprüfung des Inhalts an. Bilder werden mit Pillow (PIL Fork) behandelt. Nur 3 Zeilen.

python


import PIL.Image as Image
img = Image.open('test-8.png')
display(img)

In ein Format konvertieren, das in das trainierte Modell eingegeben werden kann

Die folgende ** Vorverarbeitung ** ist erforderlich, um das trainierte Modell auszufüllen.

  1. Machen Sie ein Graustufenbild.
  2. Ändern Sie die Größe auf 28 $ \ mal 28 Pixel.
  3. Erstellen Sie ein zweidimensionales Array vom Typ numpy.ndarray.
  4. Machen Sie weiß "0.0" und schwarz "1.0".

Sie können die obige Vorverarbeitung mit dem folgenden Code durchführen. Es ist zu beachten, dass ein normales Graustufenbild mit 256 Schritten ** Weiß "255" und Schwarz "0" ** ist, daher muss es invertiert werden.

python


import numpy as np
import PIL.Image as Image
import matplotlib.pyplot as plt

img = Image.open('test-8.png')

img = img.convert('L')             # 1.In Graustufen konvertieren
img = img.resize((28,28))          # 2.Größe geändert auf 28x28
x_sample = np.array(img)           # 3. numpy.In ndarray-Typ konvertieren
x_sample = 1.0 - x_sample / 255.0  # 4.Inversion / Normalisierung
y_sample = 8  #Richtige Antwortdaten

#Bestätigungsausgabe
print(f'x_sample.type = {type(x_sample)}')
print(f'x_sample.shape = {x_sample.shape}')
plt.figure()
plt.imshow(x_sample,vmin=0.,vmax=1.,cmap='Greys')
plt.show()

Das Ausführungsergebnis ist wie folgt. test-8_.png

Erstellen Sie für dieses x_sample eine Vorhersage mit einem trainierten Modell und erstellen Sie einen Vorhersageergebnisbericht mit dem in [4.] gezeigten Programm (https://qiita.com/code0327/items/1047adc050ab6d75ad5c). Es wird wie folgt sein.

test-8_p.png

Ich konnte eine gute Vorhersage treffen (Klassifizierung).

Repost: Programm zur Erstellung von Prognoseergebnisberichten

Grundsätzlich ist es dasselbe wie das in [4.] gezeigte Programm (https://qiita.com/code0327/items/1047adc050ab6d75ad5c), aber "x_sample" sind die einzelnen Eingabedaten, "y_sample" sind die richtigen Antwortdaten. Ich schreibe die Annahme um, dass das trainierte Modell in "Modell" gespeichert ist.

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 

s_sample = model.predict(np.array([x_sample]))[0] #Vorhersage (Klassifizierung)

fig, ax = plt.subplots(nrows=2,figsize=(3,4.2), dpi=120, 
                       gridspec_kw={'height_ratios': [3, 1]})

plt.subplots_adjust(hspace=0.05)

#Zeigen Sie das Bild der handgeschriebenen Zahlen auf der Oberseite an
ax[0].imshow(x_sample,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_sample}',
               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_sample.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_sample,width=0.95)
b[s_sample.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_sample.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')

Vorverarbeitung: Wenn sich in der Bildmitte keine Nummer befindet, entspricht dies dem Schmutz

Wenn Sie selbst ein Bild mit handgeschriebenen Zahlen erstellen, gibt es Fälle, in denen sich ** die Zahlen nicht in der Bildmitte befinden **, wie unten gezeigt. test-2b.png

Wenn Sie ein solches Bild so vorhersagen (klassifizieren), wie es ist, erhalten Sie ** schreckliche Ergebnisse ** wie folgt. test-2_p.png

Aus diesem Grund ist es vor einer Vorhersage erforderlich, den Zeichenteil in die Mitte zu verschieben und eine Vorverarbeitung durchzuführen, so dass der Nettozeichenteil etwa 90% der Größe der Figur beträgt. es gibt. Außerdem müssen ** Schmutz ** und ** Staub ** außer Zeichen entfernt werden.

Hier möchte ich die folgende (automatisierte) Vorverarbeitung durchführen. フロー.png

Vorverarbeitung


import numpy as np
from PIL import Image, ImageChops,ImageFilter, ImageOps, ImageDraw
import matplotlib.pyplot as plt

#Fügen Sie oben, unten, links und rechts in der Abbildung Ränder (weiß) mit der angegebenen Breite hinzu
def add_margin(img, margin):
    w, h = img.size
    w2 = w + 2 * margin
    h2 = h + 2 * margin
    result = Image.new('L', (w2, h2), 255)
    result.paste(img, (margin, margin))
    return result

#Die Größe, die zur langen Seite des durch das Argument angegebenen Rechtecks passt
#Berechnen Sie ein Quadrat (aber etwas größer)
def to_square( rect ):
  x1, y1, x2, y2 = rect   # (x1,y1)Ist die obere linke, (x2,y2)Ist die untere rechte Koordinate
  s = max( x2-x1, y2-y1 ) #Holen Sie sich die Länge der langen Seite
  s = int(s*1.3)          #Ein bisschen größer
  nx1 = (x1+x2)/2 - s/2
  nx2 = (x1+x2)/2 + s/2
  ny1 = (y1+y2)/2 - s/2
  ny2 = (y1+y2)/2 + s/2
  return (nx1,ny1,nx2,ny2)

img = Image.open('test-2x.png')

img  = img.convert('L')
#display(img)

#Fügen Sie oben, unten, links und rechts im Bild weiße Ränder hinzu
img  = add_margin(img,int(max(img.size)*0.2))
#display(img)

#Erstellen Sie ein invertiertes Bild
img2 = ImageOps.invert(img)

#Verwischen
img2 = img2.filter(ImageFilter.GaussianBlur(1.5))
#display(img2)

#Binarisierung
img2 = img2.point(lambda p: p > 150 and 255)  
#display(img2)

#Holen Sie sich den kleinsten Bereich (rechteckig) außer schwarz
rect = img2.getbbox() 
# tmp = img2.convert('RGB')
# ImageDraw.Draw(tmp).rectangle(rect, fill=None, outline='red')
# display(tmp)

#Konvertieren Sie ein Rechteck in ein Quadrat, das zur langen Seite passt
sqr = to_square(rect)
# tmp = img2.convert('RGB')
# ImageDraw.Draw(tmp).rectangle(sqr, fill=None, outline='red')
# display(tmp)

#Mit einem Quadrat getrimmt
img = img.crop(sqr)
#display(img)

#Danach das gleiche wie zuvor
img = img.convert('L')             # 1.In Graustufen konvertieren
img = img.resize((28,28))          # 2.Größe geändert auf 28x28
x_sample = np.array(img)           # 3. numpy.In ndarray-Typ konvertieren
x_sample = 1.0 - x_sample / 255.0  # 4.Inversion / Normalisierung
y_sample = 2  #Richtige Antwortdaten

#Bestätigungsausgabe
print(f'x_sample.type = {type(x_sample)}')
print(f'x_sample.shape = {x_sample.shape}')
plt.figure()
plt.imshow(x_sample,vmin=0.,vmax=1.,cmap='Greys')
plt.show()

Dies ist ein Vergleich der Ergebnisse der ** prädiktiven Klassifizierung ohne Vorverarbeitung und der ** prädiktiven Klassifizierung nach der Vorverarbeitung. Ich erkenne noch einmal, dass die Vorverarbeitung wichtig ist, bevor ich das Vorhersagemodell versuche und Fehler mache.

前後.png

nächstes Mal

――Da der äußere Wassergraben aufgefüllt ist, möchte ich endlich den ** Modellbau ** des neuronalen Netzes untersuchen.

Recommended Posts

Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras heraus. 6-Versuchen Sie, die von Ihnen erstellten Bilder vorzuverarbeiten und zu klassifizieren.
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 4 heraus. ~ Lassen Sie uns mit dem trainierten Modell ~ vorhersagen
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 9 heraus. Lernen, Speichern und Laden von Modellen
Fordern Sie die Bildklassifizierung durch TensorFlow2 + Keras 5 heraus ~ Beobachten Sie Bilder, die nicht klassifiziert werden können ~
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras heraus. 7 - Grundlegendes zu Layertypen und Aktivierungsfunktionen -
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 3 heraus ~ Visualisieren Sie MNIST-Daten ~
Bildklassifizierung mit selbst erstelltem neuronalen Netzwerk von Keras und PyTorch
Fordern Sie die Bildklassifizierung durch TensorFlow2 + Keras 1-Move vorerst heraus.
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 2 heraus ~ Schauen wir uns die Eingabedaten genauer an ~
Bildklassifizierung mit Keras-Von der Vorverarbeitung zum Klassifizierungstest-
Vergleichen Sie rohen TensorFlow mit tf.contrib.learn und Keras
Fordern Sie die Textklassifizierung von Naive Bayes mit sklearn heraus
Richter Yosakoi Naruko nach Bildklassifikation von Tensorflow.
Deep Learning Bildanalyse beginnend mit Kaggle und Keras
Identifizieren Sie den Namen aus dem Blumenbild mit Keras (Tensorfluss)
Ich habe versucht, Grad-CAM mit Keras und Tensorflow zu implementieren
Lernen Sie Wasserstein GAN mit Keras-Modell und TensorFlow-Optimierung