[PYTHON] Da es Doppelgenger gab, habe ich versucht, es mit künstlicher Intelligenz zu unterscheiden (lacht) (Teil 1)

Freut mich, dich kennenzulernen. Mein Name ist @eve_yk und ich bin Ingenieurpraktikant bei einem Startup namens Liaro. Dieses Mal werden wir unser Verständnis für die Technologie, die Liaro jeden Tag einsetzt, vertiefen, aktiv Wissen ausgeben und teilen und hoffentlich eine professionelle Person auf der Straße einen scharfen Masakari werfen lassen. Zu diesem Zweck habe ich beschlossen, einen Blog zu schreiben! Es gibt nicht viel Inhalt, der geschrieben werden kann, aber ich möchte so viel schreiben, wie ich kann. Vielen Dank ~!

Dieses Mal werde ich einen Gesichtsbildklassifikator unter Verwendung des Convelutional Neural Network (CNN) erstellen.

Zweck

Die Aufgabe der Gesichtsklassifizierung ist Facebooks DeepFace und Googles FaceNet. /1503.03832) usw. haben eine menschenähnliche (oder höhere?) Genauigkeit erreicht.

Warum herausfordern, Gesichtsbilder zu identifizieren? Um dies zu erklären, möchte ich, dass Sie sich das folgende Bild ansehen.

Zuerst das Symbol, das ich auf Facebook registriert habe.

537059_256924114444730_821185260_n.jpg

Es wird ein schönes Lächeln sein. Als nächstes ist dies Herr Kazuhiko Tanaka von "Super Maradona", dem Finalisten des M-1 Grand Prix 2015.

tanaka.jpg

!?!?!?

Super wie! !! !! Es war eine sehr schockierende Erfahrung für mich, der nie gesagt worden war, er solle wie jemand aussehen. Ich glaube, ich habe keine andere Wahl, als einen Klassifikator zu erstellen, der mich von Mr. Tanaka unterscheidet. Das ist ein dummer Grund.

0. Erstellen Sie eine Entwicklungsumgebung

Dieses Mal habe ich es in der folgenden Umgebung getestet.

Wenn Sie pyenv verwenden, um die Umgebung zu erstellen, wird es einfach sein. Ich denke, Sie sollten auf die unten stehenden Links verweisen.

Erstellen einer Entwicklungsumgebung für maschinelles Lernen mit Python

numpy und opencv können mit anaconda installiert werden, und chainer und ProgressBar2 können mit pip installiert werden.

1. Sammeln Sie Bilder zum Lernen.

Sammeln Sie als Nächstes die für das Training verwendeten Bilder. Es ist keine Übertreibung zu sagen, dass das Sammeln der zu verwendenden Daten die schwierigste Aufgabe beim maschinellen Lernen ist. In diesem Fall ** ist es besonders schwierig, weil zu wenig Bedarf für diesen Zweck besteht. Ich werde mein Bestes tun, um es manuell zu sammeln.

Vorerst wurden 80 Bilder von mir und 68 Bilder von Herrn Tanaka gesammelt. (Ich war überrascht, dass nur dies gesammelt wurde, selbst wenn ich mein Smartphone, meinen PC oder Facebook erwischte) Vermeiden Sie 5 davon als Testbilder. Wir werden einen Datensatz mit den verbleibenden 75,63 Bildern als Trainingsbilder erstellen. Die Anzahl ist zu klein, aber diesmal ist es ein Stück, also lass uns das machen.

2. Verarbeiten Sie das Bild vor

Um das Gesicht zu klassifizieren, werden wir das Bild ein wenig verarbeiten. Die nächsten 4 Schritte.

  1. Schneiden Sie den Gesichtsteil des Bildes aus
  2. Ändern Sie die Größe
  3. Datenerweiterung (Inversion, Rotation)
  4. In das Format np.ndarray konvertieren

Schneiden Sie zuerst den Bereich des Gesichtsteils im Bild aus. Dazu verwenden wir einen Kaskadenklassifikator, der die von OpenCV bereitgestellten Haar-Like-Funktionen verwendet. Ich werde den Klassifikator diesmal nicht lernen. Ändern Sie dann die Größe des Bildes auf 64 * 64px. Der Chainer kann Features jeder Größe mit fester Länge unabhängig von der Größe des Eingabebilds Spatial Pyramid Pooling berechnen .spatial_pyramid_pooling_2d) ist ebenfalls implementiert, aber ich habe es diesmal nicht verwendet. Danach werden die Daten erweitert. Bei der Klassifizierung von Bildern wird das Originalbild durch Inversion, parallele Bewegung, Drehung, Farbänderung, Glättung usw. verarbeitet und die Datenmenge wird aufgeblasen. Dieses Mal wird das Originalbild invertiert und gedreht, um die Datenmenge zu erhöhen.

Wenn Sie den obigen Prozess codieren, sieht er folgendermaßen aus.

face_data_augmentation.py


# coding:utf-8

"""
Extrahieren Sie den im Bild vorhandenen Gesichtsbereich im angegebenen Ordner
Invertieren und drehen Sie das Bild, um es zu vergrößern
"""

import os
import glob
import argparse
import cv2
import numpy as np

CASCADE_PATH = "/path/to/haarcascade/haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(CASCADE_PATH)

def detectFace(image):
	"""
Extrahieren Sie den Gesichtsbildteil
	"""
	image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
	facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=3, minSize=(50, 50))
 
	return facerect

def resize(image):
	"""
Bildgröße ändern
	"""
	return cv2.resize(image, (64,64))

def rotate(image, r):
	"""
Drehen Sie r Grad um die Bildmitte
	"""
	h, w, ch = image.shape #Bildarraygröße
	M = cv2.getRotationMatrix2D((w/2, h/2), r, 1) #Rotationsmatrix zum Drehen um das Bild
	rotated = cv2.warpAffine(image, M, (w, h))

	return rotated

if __name__ == "__main__":
	parser = argparse.ArgumentParser(description='clip face-image from imagefile and do data argumentation.')
	parser.add_argument('-p', required=True, help='set files path.', metavar='imagefile_path')
	args = parser.parse_args()

	#Erstellen, wenn kein Ausgabeverzeichnis vorhanden ist
	result_dir = args.p + "_result"
	if not os.path.exists(result_dir):
		os.makedirs(result_dir)

	face_cnt = 0

	#Holen Sie sich JPG-Datei
	files = glob.glob(args.p+"\*.jpg ")
	print args.p+"\*.jpg "

	for file_name in files:
		#Bild laden
		image = cv2.imread(file_name)
		if image is None:
			#Lesefehler
			continue

		# -12~Drehen Sie 3 Grad in einem Bereich von 12 Grad
		for r in xrange(-12,13,4):
			image = rotate(image, r)

			#Gesichtsbildextraktion
			facerect_list = detectFace(image)
			if len(facerect_list) == 0: continue

			for facerect in facerect_list:
				#Ausschnitt des Gesichtsbildteils
				croped = image[facerect[1]:facerect[1]+facerect[3],facerect[0]:facerect[0]+facerect[2]]

				#Ausgabe
				cv2.imwrite(result_dir+"/"+str(face_cnt)+".jpg ", resize(croped))
				face_cnt += 1

				#Das invertierte Bild wird ebenfalls ausgegeben
				fliped = np.fliplr(croped)
				cv2.imwrite(result_dir+"/"+str(face_cnt)+".jpg ", resize(fliped))
				face_cnt += 1

Die von diesem Code ausgegebenen Bilder enthalten Gesichtsbilder anderer Personen und falsch erkannte Bilder auf dem Foto, sodass unnötige Bilder nacheinander manuell entfernt werden. Hier ist der fertige Datensatz.

dataset.JPG

…。 Es ist ein Gefühl. Als Trainingsbilder habe ich 393 Bilder von mir und 187 Bilder von Herrn Tanaka gemacht.

Erstellen Sie abschließend die Daten, die für die Verarbeitung durch Chainer in das Format np.ndarray konvertiert wurden. Da davon ausgegangen wird, dass Daten vom Typ np.ndarray in die von chainer verwendete Variablenklasse eingegeben werden, konvertieren Sie sie im Voraus in dieses Format. Beachten Sie zu diesem Zeitpunkt, dass das von Pythons OpenCV und das von Chainers CNN behandelte Bildformat unterschiedlich sind.

OpenCV => (height, width, channel) chainer => (channel, height, width)

Konvertieren Sie mit dem folgenden Code.

make_dataset.py


# coding:utf-8

import os
import sys
import argparse
import glob
import cv2
import numpy as np

"""
Erstellen Sie einen Datensatz zur Verwendung mit CNN
Bild in CNN-Eingabeformat konvertieren

Das Format des Datensatzes ist wie folgt
	- dataset
		- train
			- [class_name_1]
				- hogehoge.jpg
				- foofoo.jpg
				- ...
			- [class_name_2]
				- hogehoge.jpg
				- ...
			- ...
		- test
			- [class_name_1]
				- hogehoge.jpg
				- ...
			- ...

"""

def transpose_opencv2chainer(x):
	"""
Konvertieren Sie vom opencv npy-Format in das chainer npy-Format
		opencv  => (height, width, channel)
		chainer => (channel, height, width)
	"""
	return x.transpose(2,0,1)

if __name__ == "__main__":
	parser = argparse.ArgumentParser(description='Erstellen Sie einen Datensatz für CNN')
	parser.add_argument('--input_path',   required=True, type=str)
	parser.add_argument('--output_path',  required=True, type=str)
	args = parser.parse_args()

	#Holen Sie sich die JPG-Dateiliste
	train_files = glob.glob(args.input_path+"/train/*/*.jpg ")
	test_files  = glob.glob(args.input_path+"/test/*/*.jpg ")

	#Erstellen, wenn kein Ausgabeverzeichnis vorhanden ist
	if not os.path.exists(args.output_path):
		os.makedirs(args.output_path)

	train_data  = []
	train_label = []
	test_data   = []
	test_label  = []
	label_dict  = {}

	#Erstellung von Trainingsdaten
	for file_name in train_files:
		image = cv2.imread(file_name)
		if image is None:
			#Lesefehler
			continue

		#Ruft den Klassennamen aus der Verzeichnisstruktur ab
		class_name = file_name.replace("\\", "/").split("/")[-2]
		
		#In Chainer-Format konvertieren
		image = transpose_opencv2chainer(image)
		train_data.append(image)
		train_label.append(label_dict.setdefault(class_name, len(label_dict.keys())))

	#Datenerstellung / -speicherung
	train_data  = np.array(train_data)
	train_label = np.array(train_label)
	np.save(args.output_path+"/train_data.npy" , train_data)
	np.save(args.output_path+"/train_label.npy", train_label)

	for file_name in test_files:
		image = cv2.imread(file_name)
		if image is None:
			#Lesefehler
			continue

		#Ruft den Klassennamen aus der Verzeichnisstruktur ab
		class_name = file_name.replace("\\", "/").split("/")[-2]
		
		#In Chainer-Format konvertieren
		image = transpose_opencv2chainer(image)
		test_data.append(image)
		test_label.append(label_dict.setdefault(class_name, len(label_dict.keys())))

	#Datenerstellung / -speicherung
	test_data   = np.array(test_data)
	test_label  = np.array(test_label)
	np.save(args.output_path+"/test_data.npy"  , test_data)
	np.save(args.output_path+"/test_label.npy" , test_label)

Es ist ein bisschen kurz, aber diesmal ist es bis hierher. Das nächste Mal möchte ich ein Modell des Klassifikators beschreiben und tatsächlich Gesichtsdiskriminierung lernen und bewerten. freue mich auf!

Referenz

Erstellen einer Anwendungsentwicklungsumgebung für maschinelles Lernen mit Python --qiita

https://github.com/mitmul/chainer-cifar10

Versuchen Sie, CIFAR-10 mit dem Chainer-A-Tagebuch eines entspannten Ingenieurs zu klassifizieren

Yoshimoto Kogyo Co., Ltd. Entertainer-Profil | Super Maradona

Recommended Posts

Da es Doppelgenger gab, habe ich versucht, es mit künstlicher Intelligenz zu unterscheiden (lacht) (Teil 1)
Als ich in IPython versuchte, den Wert zu sehen, war es ein Generator, also kam ich auf ihn, als ich frustriert war.
Ein Anfänger versuchte, eine Strichzeichnung mit einem Kettenmesser zu färben. Ich konnte es schaffen.
Ich wollte die Google-Tabelle mit AWS Lambda betreiben, also habe ich es versucht [Teil 2]
Ein Memorandum beim automatischen Erwerb mit Selen
Ich war süchtig danach, Cython mit PyCharm auszuprobieren, also machen Sie sich eine Notiz
Als ich versuchte, eine VPC mit AWS CDK zu erstellen, konnte ich es aber nicht schaffen
Ich konnte AWS-Batch mit Python, Moto verspotten, also werde ich es verlassen
Beachten Sie, dass ich süchtig danach war, TensowFlow einzurichten
Ich wollte die Anzahl der Zeilen in mehreren Dateien wissen und versuchte, sie mit einem Befehl abzurufen
Python-Anfänger haben einen Chat-BOT erstellt, also habe ich versucht, zusammenzufassen, wie man es macht
Ich habe versucht, mit Quantx eine Linie mit gleitendem Durchschnitt des Volumens zu implementieren
[IOS] GIF-Animation mit Pythonista3. Ich war süchtig danach.
Ich habe versucht, automatisch einen Bericht mit der Markov-Kette zu erstellen
Als ich versuchte, PIL und matplotlib in einer virtuellen Umgebung zu installieren, war ich süchtig danach.
Ich habe versucht, das Problem der Kombinationsoptimierung mit Qiskit zu lösen
Ich habe einen Server mit Python-Socket und SSL erstellt und versucht, über den Browser darauf zuzugreifen
Ich habe versucht, mit Hy ・ Define a class zu beginnen
PyTorchs Buch war schwer zu verstehen, deshalb habe ich es ergänzt
Ich bin gestolpert, als ich versucht habe, Basemap zu installieren, also ein Memorandum
Ich habe versucht, eine zufällige FizzBuzz-Spalte mit Blasensortierung zu sortieren.
Ich habe versucht, in einem tief erlernten Sprachmodell zu schreiben
Ich habe kein Gefühl für "Quiz fragen nach Investitionssinn", also habe ich versucht, es mit roher Gewalt zu lösen (Python Monte Carlo Simulation)
Wovon ich in Kapitel 3 der kollektiven Intelligenz abhängig war. Es ist kein Tippfehler, daher denke ich, dass etwas mit meinem Code nicht stimmt.
Als ich versuchte, mithilfe von Anforderungen in Python zu kratzen, war ich süchtig nach SSLError, also einem Workaround-Memo
Ich habe versucht, es zu erweitern, damit die Datenbank mit der Analysesoftware von Wiire verwendet werden kann
Ich war frustriert von Kaggle und versuchte, durch Schaben und maschinelles Lernen ein gutes Mietobjekt zu finden
[5.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[2nd] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[Python] Ich habe versucht, eine stabile Sortierung zu implementieren
[3.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe versucht, mit Python eine Liste von Primzahlen zu erstellen
Ich habe versucht, mit Selenium und Python einen regelmäßigen Ausführungsprozess durchzuführen
Ich habe versucht zusammenzufassen, was mit Qiita mit Word Cloud ausgegeben wurde
Ein Hinweis, dem ich beim Erstellen einer Tabelle mit SQL Alchemy verfallen war
Ich habe versucht, mit Python eine 2-Kanal-Post-Benachrichtigungsanwendung zu erstellen
Ich habe versucht, Bulls and Cows mit einem Shell-Programm zu erstellen
Ich habe versucht, eine ToDo-App mit einer Flasche mit Python zu erstellen
[4.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
[1.] Ich habe versucht, mit Python ein bestimmtes Authenticator-ähnliches Tool zu erstellen
Ich habe versucht, Jojo mit LSTM ein seltsames Zitat zu machen
Ich habe versucht, mit Go einen exklusiven Kontrollmechanismus zu erstellen
Ich bin auf einen Bildfilter mit einem eindeutig japanischen Namen namens Kuwahara-Filter gestoßen, und als ich ihn ausprobierte, war er erstaunlich, also werde ich ihn vorstellen.
Der Cloud Shell Editor von GCP war mit der Python-Entwicklungsumgebung verstopft, sodass ich es geschafft habe, ihn auf einem freien Grundstück neu zu erstellen.
Da es keine Beschreibung zum Erstellen einer Umgebung für nnabla mit Docker einschließlich GPU gibt, habe ich es selbst versucht, Teil 1
[Python] Als ich versuchte, ein Dekomprimierungswerkzeug mit einer Zip-Datei zu erstellen, die ich gerade kannte, war ich süchtig nach sys.exit ()
Ich habe versucht, mit einem Remote-Server über Socket-Kommunikation mit Python zu kommunizieren.
Ich habe versucht, eine Blockchain zu implementieren, die tatsächlich mit ungefähr 170 Zeilen funktioniert
Als ich versuchte, Python auszuführen, wurde ich zum Microsoft Store übersprungen
Ich habe versucht, ein Programm zu erstellen, das Hexadezimalzahlen mit Python in Dezimalzahlen konvertiert
Ich war süchtig danach, eine Python-Venv-Umgebung mit VS Code zu erstellen
Eine Geschichte, die ich süchtig danach war, eine Video-URL mit Tweepy zu bekommen
Ich habe versucht, ein Plug-In mit HULFT IoT Edge Streaming [Entwicklung] (2/3) zu erstellen.
Ich habe versucht, "Sakurai-san" LINE BOT mit API Gateway + Lambda zu erstellen