[PYTHON] Ich habe versucht, Runenfiguren mit Scikit-Learn handschriftlich zu erkennen

Dieser Artikel ist der 15. Tagesartikel des Fujitsu Systems Web Technology Adventskalenders. (Versprechen) Der Inhalt dieses Artikels ist meine eigene Meinung und repräsentiert nicht die Organisation, zu der ich gehöre.

Einführung

In diesem Artikel ** mit scikit-learn, der maschinellen Lernbibliothek von Python Dies ist eine Zusammenfassung des Verfahrens und der Ergebnisse, als ich versuchte, Runenzeichen mit handschriftlichen Zeichen zu erkennen **. Während die Pioniere dieses Adventskalenders großartige Funktionen und Know-how veröffentlicht haben, die für die eigentliche Arbeit recht nützlich zu sein scheinen, Ich mache einfach etwas, das mir einfach Spaß macht, und ich kann nichts dagegen tun. .. Ich hoffe, Sie können einen kurzen Blick darauf werfen.

Da der Autor dieses Artikels ein Anfänger im maschinellen Lernen ist, gibt es jetzt möglicherweise mehr Inhalte. Auch für diejenigen, die Python berühren wollen, Scikit-Learn Ich werde mein Bestes tun, um angemessene Informationen bereitzustellen. Vielen Dank.

Hintergrund

Ich fasse es in meiner täglichen Arbeit überhaupt nicht an, aber ich interessiere mich für maschinelles Lernen und möchte die Grundlagen des Lernens und der Bewegung lernen. Ich berührte Scikit-Learn. Ich hätte versuchen können, den Datensatz der Bibliothek zu verwenden, aber Ich möchte wissen, "welche Art von Daten kann ich vorbereiten und was kann ich tun?" Ich beschloss, zunächst die Daten vorzubereiten.

** (beiseite) ** Runencharaktere sind irgendwie cool, nicht wahr?

Was wurde verwendet

--Anaconda: Ein Paket, das Python selbst und häufig verwendete Bibliotheken enthält. --scikit-learn: Eine Bibliothek, die die Verwendung neuronaler Netze in Python vereinfacht. Es ist Open Source. Dieses Mal werden wir ein Modell namens MLP Classifier verwenden, das eine "Klassifizierung" durchführt.

Datenaufbereitung

Dieses Mal konzentrieren wir uns auf "Deutsche gemeinsame Runenzeichen (24 Zeichen)" unter den Runenzeichen. images.png

Es scheint keine geeigneten Daten wie "Runenzeichendaten für maschinelles Lernen" zu geben. Bereiten Sie also Ihr eigenes Bild vor. Dieses Mal habe ich es mit der folgenden Methode erstellt.

(1) Erstellen Sie ein Bild, in dem handgeschriebene Zeichen in regelmäßigen Abständen von Hand aneinandergereiht werden. (Es ist später praktisch, wenn der Name der Bilddatei mit einem Zeichen gezeichnet wird (Beispiel: "ᚠ. Png")) (2) Teilen Sie das Bild mit dem E-Cutter (freie Software) in gleiche Teile. 01_画像取得Ecutter.PNG Das geteilte Bild wurde im angegebenen Ordner mit "[ursprünglicher Dateiname] _ [Zweigstellennummer] .png " gespeichert, was sehr praktisch war. Einmal habe ich 18 Bilddaten für jede Art von Runenzeichen erstellt.

Bilder laden

Von hier aus werden wir in Python verarbeiten. Laden Sie zuerst das Bild.

import cv2 #Bibliothek zur Bildkonvertierung
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import os, glob

#Array zum Speichern von Bilddaten
X = []
#Zeichen, die Bilddaten entsprechen(Antworten)Array zum Speichern
Y = []

#Trainingsdatenverzeichnisdatei
dir = "[Bilddatenspeicherverzeichnis]"
files = glob.glob(dir + "\\*.png ")

#Vertikale und horizontale Größe des Bildes(Pixel)
image_size = 50

#Lesen Sie die Dateien im Verzeichnis und fügen Sie sie der Liste der Trainingsdaten hinzu
for i, file in enumerate(files):
    image = Image.open(file)
    #In 8-Bit-Graustufen konvertieren
    image = image.convert("L")
    image = image.resize((image_size, image_size))
    data = np.asarray(image).flatten()
    X.append(data)
    moji = file.split("\\")[-1].split("_")[0]
    Y.append(moji)
 
X = np.array(X)
Y = np.array(Y)

Lassen Sie uns das geladene Bild anzeigen.

#Visualisieren Sie die ersten Daten
showimage = np.reshape(X[0], (50,50)) #Erstellen Sie ein 50x50-Doppelarray mit Umformung
plt.subplot(121),plt.imshow(showimage),plt.title('Input')
plt.show()
02_画像読み込み.PNG

Es kann als Daten mit einer Größe von 50 * 50 gelesen werden.

◆ Lassen Sie uns lernen und klassifizieren

Die Anzahl der Daten ist recht gering, aber lassen Sie uns diese Daten (24 (Zeichen) * 18 (Blätter)) einmal lernen und klassifizieren!

・ Separate Daten für Training und Test
#Teilen Sie die Daten für Training und Test
x_train, x_test, y_train, y_test = model_selection.train_test_split(X, Y, test_size=0.1, random_state=0)
・ Lernen und urteilen
#Lernen
clf = MLPClassifier(hidden_layer_sizes=(200,))
clf.fit(x_train, y_train)

#Kategorisieren Sie Testdaten
y_pred = clf.predict(x_test)

#Ergebnisse anzeigen
print("---Angenommene Antwort---")
print(y_test)

print("---Die Antwort des Modells---")
print(y_pred)

print("---Richtige Antwortrate---")
accuracy_score(y_test, y_pred)

·Ergebnis

12120023_最初の結果_全然ダメ.PNG

** Der Prozentsatz der richtigen Antworten ist sehr gering ...! !! (7,1%) orz **

Die meisten von ihnen sind als "ᚱ" klassifiziert, und die anderen beurteilten Zeichen sind ebenfalls falsch ... Andere als "ᚱ" klassifizierte scheinen jedoch als Zeichen mit ähnlichen Formen unter den Runenzeichen klassifiziert zu sein. Ich bin ein wenig froh, einen Blick auf den Spross der Intelligenz zu werfen (obwohl ich doch einen Fehler gemacht habe).

Es scheint, dass die Trainingsdaten immer noch nicht ausreichen, aber es ist mühsam, mehr handschriftliche Zeichendaten hinzuzufügen. Versuchen Sie die Datenerweiterung.

Datenerweiterung

Vorbereitet [Zeichentyp] * 18 Bilder reichen also nicht zum Lernen aus Konvertieren Sie Daten, um die Datenmenge zu erhöhen.

Der folgende Artikel war sehr hilfreich für die Datenerweiterung. https://products.sint.co.jp/aisia/blog/vol1-7#toc-3

Es scheint, dass es Methoden wie "Rauschen erhöhen", "Umkehren", "Verschieben" und "Transformieren" gibt. Dieses Mal werden wir darin "Transformation" und "Rotation" durchführen.

Verformung

#Transformiere das Bild
for i, file in enumerate(files):
    image = Image.open(file)   
    image = image.resize((image_size, image_size))
    image = image.convert("L")
    moji = file.split("\\")[-1].split("_")[0]
    
    #Invertieren Sie die Datenbits in ein Array
    image_array = cv2.bitwise_not(np.array(image))
    
    ##Transformation ①
    #Transformationskarte des Bildes erstellen
    pts1 = np.float32([[0,0],[0,100],[100,100],[100,0]])
    pts2 = np.float32([[0,0],[0, 98],[102,102],[100,0]])
    #Bildtransformation
    M = cv2.getPerspectiveTransform(pts1,pts2)
    dst1 = cv2.warpPerspective(image_array,M,(50, 50))
    
    X.append(dst1.flatten())
    Y.append(moji)
    
    ##Transformation ②
    #Transformationskarte des Bildes erstellen
    pts2 = np.float32([[0,0],[0, 102],[98, 98],[100,0]]) 
    #Bildtransformation
    M = cv2.getPerspectiveTransform(pts1,pts2)
    dst2 = cv2.warpPerspective(image_array,M,(50, 50))
    X.append(dst2.flatten())
    Y.append(moji)

#Zeigen Sie die letzten Daten an
showimage = np.reshape(image_array, (50,50)) #Erstellen Sie ein 50x50-Doppelarray mit Umformung
plt.subplot(121),plt.imshow(showimage),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
Anzeige des deformierten Bildes
03_画像変形.PNG

Ich konnte ein Bild erzeugen, das im Vergleich zum Originalbild leicht deformiert war. Generieren Sie zwei deformierte Bilder für jedes Originalbild und fügen Sie sie den Trainingsdaten hinzu.

Drehung

Um die Daten weiter zu erhöhen, erstellen Sie ein Bild mit dem um 15 Grad gedrehten Originalbild und fügen Sie es hinzu.

#Drehen Sie das Bild
for i, file in enumerate(files):
    image = Image.open(file)   
    image = image.resize((image_size, image_size))
    image = image.convert("L")
    moji = file.split("\\")[-1].split("_")[0]
    
    #Invertieren Sie die Datenbits in ein Array
    image = cv2.bitwise_not(np.array(image))
    
    #1. 1. 15 Grad im Uhrzeigersinn drehen
    #Geben Sie den Drehwinkel an
    angle = -15.0
    #Maßstab angeben
    scale = 1.0
    #Verwenden Sie die Funktion getRotationMatrix2D
    trans = cv2.getRotationMatrix2D((24, 24), angle , scale)
    #Affin-Konvertierung
    image1 = cv2.warpAffine(image, trans, (50, 50))
    X.append(image1.flatten())
    Y.append(moji)
    
    #2. 15 Grad gegen den Uhrzeigersinn drehen
    #Geben Sie den Drehwinkel an
    angle = 15.0
    #Maßstab angeben
    scale = 1.0
    #Verwenden Sie die Funktion getRotationMatrix2D(Argumente: Mittelstellung, Drehwinkel, Maßstab)
    trans = cv2.getRotationMatrix2D((24, 24), angle , scale)
    #Affin-Konvertierung
    image2 = cv2.warpAffine(image, trans, (50, 50))
    X.append(image2.flatten())
    Y.append(moji)

#Zeigen Sie die letzten Daten an
showimage = np.reshape(image, (50,50)) #Erstellen Sie ein 50x50-Doppelarray mit Umformung
plt.subplot(121),plt.imshow(showimage),plt.title('Input')
plt.subplot(122),plt.imshow(image1),plt.title('Output')
plt.show()

showimage = np.reshape(image, (50,50)) #Erstellen Sie ein 50x50-Doppelarray mit Umformung
plt.subplot(121),plt.imshow(showimage),plt.title('Input')
plt.subplot(122),plt.imshow(image2),plt.title('Output')
plt.show()
Anzeige des gedrehten Bildes
03_画像回転.PNG

Das Originalbild wurde um 15 Grad nach links und rechts gedreht, um jedes Bild zu erzeugen. Dieses Bild wird auch zu den Trainingsdaten hinzugefügt.

Damit beträgt die Anzahl der zu trainierenden Daten das Fünffache des Originals (Original, Transformation ①, Transformation ②, Rechtsdrehung, Linksdrehung).

Lernen / Erkennen [re]

Versuchen wir erneut, Bilder zum Lernen und Testen zu erkennen (zu klassifizieren)!

·Ergebnis

12152147_次の結果_うまくいった!.PNG

** Genauigkeit hat sich verbessert ...! (86,9%) **

Zurückblicken

Welche Daten waren doch gültig?

Das Ergebnis war so etwas wie "Ich habe die Daten erhöht und die Analysegenauigkeit verbessert! Ich habe es geschafft!" Immerhin habe ich mich gefragt, wie effektiv jedes der deformierten Bilder ist Grob gesagt habe ich versucht, die richtige Antwortrate zu überprüfen, indem ich die Aufschlüsselung der zu trainierenden Daten geändert habe. 雑まとめ.PNG Ich konnte bestätigen, dass die richtige Antwortrate hoch genug war, um das Bild zu variieren.

Was ich in Zukunft machen möchte

Ich möchte weiterhin überprüfen, ob andere Methoden ("Trimmen", "Rauschen" ...) die Genauigkeit weiter verbessern. Auch dieses Mal möchte ich das Muster überprüfen, in dem die Anzahl der Knoten mit versteckten Schichten im neuronalen Netzwerk geändert wurde, das auf 200 festgelegt wurde.

Danke fürs Lesen!

Recommended Posts

Ich habe versucht, Runenfiguren mit Scikit-Learn handschriftlich zu erkennen
Ich habe versucht, die handschriftliche Zeichenerkennung von Runenzeichen mit CNN mithilfe von Keras zu erkennen
Ich habe versucht, Bilder mit CIFAR-10 mit Keras-Learning- zu erkennen.
Ich habe versucht, Bilder von CIFAR-10 mit Keras-Bilderkennung zu erkennen.
Ich habe versucht, das Gesicht mit OpenCV zu erkennen
Ich habe mit Jupyter eine einfache Bilderkennung versucht
Ich habe Hunderte Millionen SQLite mit Python ausprobiert
Ich habe Flask mit Remote-Containern von VS Code ausprobiert
Ich habe versucht, Kanas handschriftliche Zeichenerkennung Teil 3/3 Zusammenarbeit mit der GUI mithilfe von Tkinter durchzuführen
Ich habe versucht, Funktionen mit SIFT von OpenCV zu extrahieren
[OpenCV / Python] Ich habe versucht, Bilder mit OpenCV zu analysieren
Ich habe versucht, das Bild mit Python + OpenCV "morphologisch zu konvertieren"
Ich habe fp-Wachstum mit Python versucht
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, mit Elasticsearch Ranking zu lernen!
Ich habe versucht, das Gesicht mit Face ++ zu erkennen
Ich habe versucht, mit PyCaret zu clustern
Parallele Verarbeitung mit Parallel von Scikit-Learn
Ich habe gRPC mit Python ausprobiert
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich habe versucht, das Bild mit Python + OpenCV "gammakorrektur" zu machen
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln
Ich habe versucht, Djangos Server mit VScode anstelle von Pycharm zu starten
Ich habe versucht, Movidius NCS mit Python von Raspberry Pi3 auszuführen
Ich habe versucht, das Lachproblem mit Keras zu erkennen.
Ich habe versucht, ListNet of Rank Learning mit Chainer zu implementieren
Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren
Rastersuche von Hyperparametern mit Scikit-learn
Ich habe versucht, Sätze mit summpy zusammenzufassen
Ich habe maschinelles Lernen mit liblinear versucht
Ich habe versucht, WebScraping mit Python.
Ich habe versucht, Essen mit SinGAN zu bewegen
Ich habe versucht, GrabCut von OpenCV zu verwenden
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Ich habe versucht, das Gesicht mit MTCNN zu erkennen
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, Sätze mit GPT-2 zu generieren
Ich habe versucht, LightGBM mit Yellowbrick zu lernen
Ich habe versucht, das Ranking des Qiita-Adventskalenders mit Python zu kratzen
Ich habe versucht, eine eigenständige Bereitstellung von Play with Fabric [AWS-Operation mit Boto] [Play Deployment] durchzuführen.
Ich habe versucht, die Bewässerung des Pflanzgefäßes mit Raspberry Pi zu automatisieren
Ich habe eine Kreuzvalidierung basierend auf dem Rastersuchergebnis mit scikit-learn versucht
Ich habe versucht, Kanas handschriftliche Zeichenerkennung Teil 1/3 zuerst von MNIST zu machen
Ich habe versucht, mit Python eine Liste von Primzahlen zu erstellen
Ich habe versucht zu beheben "Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren"
Ich habe versucht, die Größe des logischen Volumes mit LVM zu erweitern
Ich habe versucht, den DNN-Teil von OpenPose mit Chainer-CPU auszuführen
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Ich habe versucht, automatisch Bilder von Kanna Hashimoto mit Python zu sammeln! !!
Ich habe versucht, mit Go einen exklusiven Kontrollmechanismus zu erstellen
Ich habe versucht, die Sprecheridentifikation mithilfe der Sprechererkennungs-API von Azure Cognitive Services mit Python zu überprüfen. # 1
Ich habe versucht, die Sprecheridentifikation mithilfe der Sprechererkennungs-API von Azure Cognitive Services in Python zu überprüfen. # 2
Ich habe eine multiple Regressionsanalyse mit Polypoly-Regression versucht
Ich habe versucht, eine SMS mit Twilio zu senden
Ich habe versucht, Amazon SQS mit Django-Sellerie zu verwenden
Ich habe den asynchronen Server von Django 3.0 ausprobiert
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe Linebot mit Flasche (Anaconda) + Heroku ausprobiert