[PYTHON] Klassifizieren Sie Anime-Gesichter durch Fortsetzung / Deep Learning mit Keras

Einführung

Vor ungefähr einem Jahr geschrieben in Chainer Dies ist ein Programm zum Klassifizieren von Anime-Gesichtern, aber dieses Mal habe ich es in Keras geschrieben. Das Programm ist auf GitHub aufgeführt.

Datensatz

Der Datensatz kann aus Animeface-Character-Dataset bezogen werden. Referenz: Ich habe versucht, die Funktionen des animierten Gesichts mit Denoising AutoEncoder zu extrahieren

Datensatzvorverarbeitung

Ich habe es etwas mehr als zuvor verbessert. Ändern Sie die Größe auf 32 x 32 RGB-Daten (Form = (3, 32, 32)). Der Unterschied zum letzten Mal besteht darin, dass es wahrscheinlich auch dann funktioniert, wenn Sie den leeren Ordner, der keine Daten enthält, nicht löschen. Bedarf

Es ist.

#! -*- coding: utf-8 -*-

import os
import six.moves.cPickle as pickle
import numpy as np
try:
	import cv2 as cv
except:
	pass
from progressbar import ProgressBar

class AnimeFaceDataset:
	def __init__(self):
		self.data_dir_path = u"./animeface-character-dataset/thumb/"
		self.data = None
		self.target = None
		self.n_types_target = -1
		self.dump_name = u'animedata'
		self.image_size = 32

	def get_dir_list(self):
		tmp = os.listdir(self.data_dir_path)
		if tmp is None:
			return None
		ret = []
		for x in tmp:
			if os.path.isdir(self.data_dir_path+x):
				if len(os.listdir(self.data_dir_path+x)) >= 2:
					ret.append(x)
		return sorted(ret)

	def get_class_id(self, fname):
		dir_list = self.get_dir_list()
		dir_name = filter(lambda x: x in fname, dir_list)
		return dir_list.index(dir_name[0])

	def get_class_name(self, id):
		dir_list = self.get_dir_list()
		return dir_list[id]

	def load_data_target(self):
		if os.path.exists(self.dump_name+".pkl"):
			print "load from pickle"
			self.load_dataset()
			print "done"
		else:
			dir_list = self.get_dir_list()
			ret = {}
			self.target = []
			self.data = []
			print("now loading...")
			pb = ProgressBar(min_value=0, max_value=len(dir_list)).start()
			for i, dir_name in enumerate(dir_list):
				pb.update(i)
				file_list = os.listdir(self.data_dir_path+dir_name)
				for file_name in file_list:
					root, ext = os.path.splitext(file_name)
					if ext == u'.png':
						abs_name = self.data_dir_path+dir_name+'/'+file_name
						# read class id i.e., target
						class_id = self.get_class_id(abs_name)
						self.target.append(class_id)
						# read image i.e., data
						image = cv.imread(abs_name)
						image = cv.resize(image, (self.image_size, self.image_size))
						image = image.transpose(2,0,1)
						image = image/255.
						self.data.append(image)
			pb.finish()
			print("done.")
			self.data = np.array(self.data, np.float32)
			self.target = np.array(self.target, np.int32)

			self.dump_dataset()

	def dump_dataset(self):
		pickle.dump((self.data,self.target), open(self.dump_name+".pkl", 'wb'), -1)

	def load_dataset(self):
		self.data, self.target = pickle.load(open(self.dump_name+".pkl", 'rb'))


if __name__ == '__main__':
	dataset = AnimeFaceDataset()
	dataset.load_data_target()

Wenn ich es tatsächlich lese

In [1]: from animeface import AnimeFaceDataset

In [2]: dataset = AnimeFaceDataset()

In [3]: dataset.load_data_target()
load from pickle
done

In [4]: x = dataset.data

In [5]: y = dataset.target

In [6]: print x.shape, y.shape
(14490, 3, 32, 32) (14490,)

Daher beträgt die Anzahl der Daten 14490 und die Anzahl der Klassen (Anzahl der Zeichen) 176. (Bis zu diesem Punkt ist es fast das gleiche wie beim letzten Mal.)

Implementierung von Faltungs-Neuronalen Netzen durch Keras

Ein Modell bauen

from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Dense
from keras.layers.core import Dropout
from keras.layers.core import Flatten
from keras.models import Sequential

def build_deep_cnn(num_classes=3):
	model = Sequential()

	model.add(Convolution2D(96, 3, 3, border_mode='same', input_shape=(3, 32, 32)))
	model.add(Activation('relu'))

	model.add(Convolution2D(128, 3, 3))
	model.add(Activation('relu'))
	model.add(MaxPooling2D(pool_size=(2, 2)))
	model.add(Dropout(0.5))

	model.add(Convolution2D(256, 3, 3, border_mode='same'))
	model.add(Activation('relu'))

	model.add(Convolution2D(256, 3, 3))
	model.add(Activation('relu'))
	model.add(MaxPooling2D(pool_size=(2, 2)))
	model.add(Dropout(0.5))

	model.add(Flatten())
	model.add(Dense(1024))
	model.add(Activation('relu'))
	model.add(Dropout(0.5))

	model.add(Dense(num_classes))
	model.add(Activation('softmax'))
	
	return model

Sie können ein Netzwerk einfach aufbauen, indem Sie zuerst ein sequentielles Modell mit model = Sequential () generieren und dann Convolutional2D und Dense hinzufügen. Es fühlt sich an, als ob "Convolutional2D" der Faltungsschicht entspricht und "Dense" der vollständig verbundenen Schicht entspricht. Der aller erste,

Convolution2D(96, 3, 3, border_mode='same', input_shape=(3, 32, 32))

Es muss nur "input_shape" angegeben werden. Um "Convolutional2D" kurz zu erklären, gibt das erste Argument die Anzahl der Faltungskerne an, und das zweite und dritte Argument geben die Größe des Faltungskerns an. Es gibt zwei Arten von "border_mode", "same" und "valid", aber in "same" ist das Auffüllen halb so groß wie der Kernel, dh die vertikale und horizontale Größe der Ausgabe ändert nichts an der vertikalen und horizontalen Größe der Eingabe. .. "gültig" bedeutet, dass keine Auffüllung vorhanden ist, dh die vertikalen und horizontalen Abmessungen der Ausgabe sind kleiner als die vertikalen und horizontalen Abmessungen der Eingabe. In Bezug auf die Polsterung ist hier leicht zu verstehen. Dieses Mal ist die "Form" des Faltungskerns "(96, 3, 3)" und die "Form" der Eingabe ist "(3, 32, 32)", also ist die "Form" der Ausgabe dieser Schicht " Es wird (96, 32, 32) `. Im Fall von "gültig" ist die Ausgabeform "(96, 32- (3-1), 32- (3-1)) = (96, 30, 30)". Sie können auch "Schritt" usw. einstellen.

Modelllernen

from keras.callbacks import EarlyStopping
from keras.callbacks import LearningRateScheduler
from keras.optimizers import Adam
from keras.optimizers import SGD
from animeface import AnimeFaceDataset

class Schedule(object):
	def __init__(self, init=0.01):
		self.init = init
	def __call__(self, epoch):
		lr = self.init
		for i in xrange(1, epoch+1):
			if i%5==0:
				lr *= 0.5
		return lr

def get_schedule_func(init):
	return Schedule(init)

dataset = AnimeFaceDataset()
dataset.load_data_target()
x = dataset.data
y = dataset.target
n_class = len(set(y))
perm = np.random.permutation(len(y))
x = x[perm]
y = y[perm]

model = build_deep_cnn(n_class)
model.summary()
init_learning_rate = 1e-2
opt = SGD(lr=init_learning_rate, decay=0.0, momentum=0.9, nesterov=False)
model.compile(loss='sparse_categorical_crossentropy', optimizer=opt, metrics=["acc"])
early_stopping = EarlyStopping(monitor='val_loss', patience=3, verbose=0, mode='auto')
lrs = LearningRateScheduler(get_schedule_func(init_learning_rate))

hist = model.fit(x, y, 
				batch_size=128, 
				nb_epoch=50, 
				validation_split=0.1, 
				verbose=1, 
				callbacks=[early_stopping, lrs])

Geben Sie für die "Rückrufe" der "Fit" -Funktion "EarlyStopping" an, das das Lernen automatisch beendet, wenn die Konvergenz bestimmt wird, oder "LearningRateScheduler", mit dem die Lernrate für jede "Epoche" angepasst werden kann. Es ist bequem und kann getan werden.

Um "LearningRateScheduler" kurz zu erklären, wird "eine Funktion verwendet, die die Lernrate zurückgibt, wenn dem Argument die aktuelle" Epochennummer "(beginnend mit 0) gegeben wird". Zum Beispiel

class Schedule(object):
    def __init__(self, init=0.01):
        self.init = init
    def __call__(self, epoch):
        lr = self.init
        for i in xrange(1, epoch+1):
            if i%5==0:
                lr *= 0.5
        return lr

def get_schedule_func(init):
    return Schedule(init)

lrs = LearningRateScheduler(get_schedule_fun(0.01))

Wenn Sie dies mögen, beträgt die anfängliche Lernrate 0,01 und die Lernrate wird alle 5 Epochen halbiert.

Zusätzlich wird die Fehlerfunktion für jede Epoche in der ".history" des Rückgabewertobjekts "fit" in einem Wörterbuchtyp gespeichert. Pandas und Matplotlib können zur bequemen Visualisierung verwendet werden.

import pandas as pd
import matplotlib.pyplot as plt
plt.style.use("ggplot")

df = pd.DataFrame(hist.history)
df.index += 1
df.index.name = "epoch"
df[["acc", "val_acc"]].plot(linewidth=2)
plt.savefig("acc_history.pdf")
df[["loss", "val_loss"]].plot(linewidth=2)
plt.savefig("loss_history.pdf")

Versuchsergebnis

Die Ergebnisse sind wie folgt und die korrekte Antwortrate für die Überprüfung betrug weniger als 60%. Wenn Adam als Optimierungsmethode verwendet wird, liegt die korrekte Antwortrate für die Überprüfung tatsächlich über 70%. Versuchen Sie es also bitte.

Übergang der Fehlerfunktion

スクリーンショット 2016-06-12 14.40.39.png

Übergang der richtigen Antwortrate

スクリーンショット 2016-06-12 14.40.15.png

Recommended Posts

Klassifizieren Sie Anime-Gesichter durch Fortsetzung / Deep Learning mit Keras
Klassifizieren Sie Anime-Gesichter mit tiefem Lernen mit Chainer
Klassifizieren Sie Mnist-Zahlen nach Keras, ohne dass der Lehrer etwas lernt [Auto Encoder Edition]
Objekterkennung durch tiefes Lernen, Keras tief zu verstehen
[Einführung in StyleGAN2] Unabhängiges Lernen mit 10 Anime-Gesichtern ♬
99,78% Genauigkeit bei tiefem Lernen durch Erkennen von handgeschriebenem Hiragana
Paralleles Lernen von Deep Learning durch Keras und Kubernetes
Deep Learning Bildanalyse beginnend mit Kaggle und Keras
Klassifizieren Sie Artikel mit Tags, die von Qiita durch unbeaufsichtigtes Lernen angegeben wurden
Erstellen Sie durch tiefes Lernen einen "Bot, der Ihnen AV-Schauspielerinnen mit ähnlichen Gesichtern sagt"
Versuchen Sie es mit TensorFlow
Deep Kernel Learning mit Pyro
Generiere Pokemon mit Deep Learning
Probieren Sie Deep Learning mit FPGA-Select-Gurken aus
Identifikation der Katzenrasse mit Deep Learning
Machen Sie ASCII-Kunst mit tiefem Lernen
Ich habe versucht, Deep Learning mit Spark × Keras × Docker skalierbar zu machen
Maschinelles Lernen mit Docker (42) Programmieren von PyTorch für Deep Learning Von Ian Pointer
Deep Learning durch Implementierung 1 gelernt (Return Edition)
Überprüfen Sie die Kniebeugenform mit tiefem Lernen
Kategorisieren Sie Nachrichtenartikel mit Deep Learning
Snack-Umsatzprognose mit Deep Learning
Bringen Sie Menschen mit Deep Learning zum Lächeln
Sortieren Sie Anime-Gesichter, indem Sie Anime-Charakterseiten mit Beautiful Soup und Selenium abkratzen
Ich habe versucht, Oba Hanana und Otani Emiri durch tiefes Lernen zu klassifizieren
Deep Learning 2 durch Implementierung gelernt (Bildklassifizierung)
Versuchen Sie, Piktogramm-Schriftarten mit Keras zu klassifizieren
Probieren Sie die Bitcoin-Preisprognose mit Deep Learning aus
Versuchen Sie es mit Chainer Deep Q Learning - Launch
Gesichtserkennung von Anime-Charakteren mit Keras
Produzieren Sie wunderschöne Seekühe durch tiefes Lernen
Versuchen Sie mit Kipoi tiefes Erlernen der Genomik
Tiefes Lernen
Ich habe versucht, Hanana Oba und Emiri Otani durch tiefes Lernen zu klassifizieren (Teil 2)
Ich habe versucht, Deep Learning mit Spark × Keras × Docker 2 Multi-Host-Edition skalierbar zu machen
Chainer und Deep Learning durch Funktionsnäherung gelernt
Tiefes Lernen durch Implementierung gelernt ~ Erkennung von Abnormalitäten (Lernen ohne Lehrer) ~
Videorahmeninterpolation durch tiefes Lernen Teil 1 [Python]
Klassifizieren Sie Informationen zum maschinellen Lernen nach Themenmodellen
Tiefes Lernen durch Implementierung (Segmentierung) ~ Implementierung von SegNet ~
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 16) Ich habe versucht, SimpleConvNet mit Keras zu erstellen
Lernen Sie, indem Sie mit neuem Python laufen! Lehrbuch für maschinelles Lernen von Makoto Ito numpy / keras Achtung!
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 17) Ich habe versucht, DeepConvNet mit Keras zu erstellen
[Für Anfänger im Deep Learning] Implementierung einer einfachen binären Klassifizierung durch vollständige Kopplung mit Keras