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.
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.
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.
!?!?!?
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.
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.
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.
Um das Gesicht zu klassifizieren, werden wir das Bild ein wenig verarbeiten. Die nächsten 4 Schritte.
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.
…。 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!
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