[PYTHON] Klassifizieren Sie Anime-Gesichter mit tiefem Lernen mit Chainer

** Klicken Sie hier für die Fortsetzung von Keras (http://qiita.com/hogefugabar/items/afb4f6c9a93a4bbda51a). ** ** **

Einführung

Dies ist mein erster Beitrag. Die heißen Tage gehen weiter, aber ich möchte die animierten Gesichtsbilddaten mithilfe von Deep Learning klassifizieren. Ich bin nicht sehr vertraut mit Anime. Sie können erkennen, ob es Hatsune Miku ist. Wer um alles in der Welt ist wer?

Datensatz

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

Code

Dieses Mal werden wir Chainer verwenden, um ein Faltungsnetzwerk zu implementieren. Definieren Sie zunächst das Modell. Es ist wie Faltung → Max Pooling → Faltung → Max Pooling → Voll verbunden → Softmax. Bitte verzeihen Sie, dass der Code schmutzig ist.

Referenz: https://github.com/mitmul/chainer-cifar10/blob/master/models/Cifar10.py

CNN.py


import time
import six.moves.cPickle as pickle
import numpy as np
from sklearn.datasets import fetch_mldata
from sklearn.cross_validation import train_test_split
from chainer import cuda, Variable, FunctionSet, optimizers
import chainer.functions as F

class ImageNet(FunctionSet):
	def __init__(self, n_outputs):
		super(ImageNet, self).__init__(
			conv1=	F.Convolution2D(3, 32, 5),
			conv2=	F.Convolution2D(32, 32, 5),
			l3=		F.Linear(512, 512),
			l4=		F.Linear(512, n_outputs)
		)

	def forward(self, x_data, y_data, train=True, gpu=-1):

		if gpu >= 0:
			x_data = cuda.to_gpu(x_data)
			y_data = cuda.to_gpu(y_data)

		x, t = Variable(x_data), Variable(y_data)
		h = F.max_pooling_2d(F.relu(self.conv1(x)), ksize=2, stride=2)
		h = F.max_pooling_2d(F.relu(self.conv2(h)), ksize=3, stride=3)
		h = F.dropout(F.relu(self.l3(h)), train=train)
		y = self.l4(h)
		return F.softmax_cross_entropy(y, t), F.accuracy(y,t)

Wir werden es vorerst ermöglichen, anhand des definierten Modells zu lernen und zu bewerten.

CNN.py


class CNN:
	def __init__(self, data, target, n_outputs, gpu=-1):

		self.model = ImageNet(n_outputs)
		self.model_name = 'cnn_model'

		if gpu >= 0:
			self.model.to_gpu()

		self.gpu = gpu

		self.x_train,\
		self.x_test,\
		self.y_train,\
		self.y_test = train_test_split(data, target, test_size=0.1)

		self.n_train = len(self.y_train)
		self.n_test = len(self.y_test)

		self.optimizer = optimizers.Adam()
		self.optimizer.setup(self.model.collect_parameters())

	def predict(self, x_data, gpu=-1):
		return self.model.predict(x_data, gpu)


	def train_and_test(self, n_epoch=100, batchsize=100):

		epoch = 1
		best_accuracy = 0
		while epoch <= n_epoch:
			print 'epoch', epoch

			perm = np.random.permutation(self.n_train)
			sum_train_accuracy = 0
			sum_train_loss = 0
			for i in xrange(0, self.n_train, batchsize):
				x_batch = self.x_train[perm[i:i+batchsize]]
				y_batch = self.y_train[perm[i:i+batchsize]]

				real_batchsize = len(x_batch)

				self.optimizer.zero_grads()
				loss, acc = self.model.forward(x_batch, y_batch, train=True, gpu=self.gpu)
				loss.backward()
				self.optimizer.update()

				sum_train_loss += float(cuda.to_cpu(loss.data)) * real_batchsize
				sum_train_accuracy += float(cuda.to_cpu(acc.data)) * real_batchsize

			print 'train mean loss={}, accuracy={}'.format(sum_train_loss/self.n_train, sum_train_accuracy/self.n_train)

			# evaluation
			sum_test_accuracy = 0
			sum_test_loss = 0
			for i in xrange(0, self.n_test, batchsize):
				x_batch = self.x_test[i:i+batchsize]
				y_batch = self.y_test[i:i+batchsize]

				real_batchsize = len(x_batch)

				loss, acc = self.model.forward(x_batch, y_batch, train=False, gpu=self.gpu)

				sum_test_loss += float(cuda.to_cpu(loss.data)) * real_batchsize
				sum_test_accuracy += float(cuda.to_cpu(acc.data)) * real_batchsize

			print 'test mean loss={}, accuracy={}'.format(sum_test_loss/self.n_test, sum_test_accuracy/self.n_test)			

			epoch += 1

	def dump_model(self):
		self.model.to_cpu()
		pickle.dump(self.model, open(self.model_name, 'wb'), -1)

	def load_model(self):
		self.model = pickle.load(open(self.model_name,'rb'))
		if self.gpu >= 0:
			self.model.to_gpu()
		self.optimizer.setup(self.model.collect_parameters())

Datensatzvorverarbeitung

Alle Bildgrößen sind auf 32 * 32 eingestellt, um die Verarbeitung zu reduzieren. Löschen Sie außerdem ** das Verzeichnis, das keine Bilder enthält ** im Voraus.

animeface.py


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

import os
import six.moves.cPickle as pickle
import numpy as np
import cv2 as cv

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'dataset'
		self.image_size = 32

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

	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 load_data_target(self):
		if os.path.exists(self.dump_name):
			self.load_dataset()
		if self.target is None:
			dir_list = self.get_dir_list()
			ret = {}
			self.target = []
			target_name = []
			self.data = []
			for dir_name in dir_list:
				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)
						target_name.append(str(dir_name))
						# 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)

			self.index2name = {}
			for i in xrange(len(self.target)):
				self.index2name[self.target[i]] = target_name[i]
				
		self.data = np.array(self.data, np.float32)
		self.target = np.array(self.target, np.int32)

		self.dump_dataset()

	def get_n_types_target(self):
		if self.target is None:
			self.load_data_target()

		if self.n_types_target is not -1:
			return self.n_types_target

		tmp = {}
		for target in self.target:
			tmp[target] = 0
		return len(tmp)

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

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

Lassen Sie uns die Daten tatsächlich lesen.

In [1]: from animeface import AnimeFaceDataset

In [2]: dataset = AnimeFaceDataset()

In [3]: dataset.load_data_target()       

In [5]: dataset.get_n_types_target()
Out[5]: 176

In [6]: len(dataset.target)
Out[6]: 14490

Daher handelt es sich um ein Klassifizierungsproblem mit 14490 Daten und 176 Klassen (Anzahl der Zeichen). Ich frage mich, ob es 176 Leute gibt. Lassen Sie uns tatsächlich mit dem folgenden Code lernen.

from CNN import CNN
from animeface import AnimeFaceDataset
from chainer import cuda

#Ich werde GPU verwenden
cuda.init(0)

print 'load AnimeFace dataset'
dataset = AnimeFaceDataset()
dataset.read_data_target()
data = dataset.data
target = dataset.target
n_outputs = dataset.get_n_types_target()

cnn = CNN(data=data,
		  target=target,
		  gpu=0,
		  n_outputs=n_outputs)
		  
cnn.train_and_test(n_epoch=100)

Das Ausführungsergebnis ist wie folgt.

C:\Python27\lib\site-packages\skcuda\cublas.py:273: UserWarning: creating CUBLAS
 context to get version number
  warnings.warn('creating CUBLAS context to get version number')
load AnimeFace dataset
epoch 1
train mean loss=4.77383880182, accuracy=0.0361935423276
test mean loss=3.88453409868, accuracy=0.116632157313
epoch 2
train mean loss=3.52874370272, accuracy=0.158193386024
test mean loss=3.00467933286, accuracy=0.247066933423
epoch 3
train mean loss=2.95961939461, accuracy=0.254735058687
test mean loss=2.6362867278, accuracy=0.327122144303
epoch 4
train mean loss=2.634737659, accuracy=0.319607384265
test mean loss=2.38959699009, accuracy=0.395445127233

----
Unterlassung
----

epoch 96
train mean loss=0.227027994983, accuracy=0.925159092696
test mean loss=2.70711887911, accuracy=0.589371965415
epoch 97
train mean loss=0.216873285405, accuracy=0.927382851637
test mean loss=2.6218228118, accuracy=0.594893018034
epoch 98
train mean loss=0.209225204521, accuracy=0.930220058136
test mean loss=2.68379376295, accuracy=0.5935127585
epoch 99
train mean loss=0.209071503231, accuracy=0.928072985573
test mean loss=2.62009712151, accuracy=0.593512752658
epoch 100
train mean loss=0.210750763214, accuracy=0.92999001446
test mean loss=2.75891605618, accuracy=0.589371977427
Early Stopping was not executed.

abschließend

Das Ergebnis war eine korrekte Rücklaufquote von ca. 60%. Vielleicht denke ich, ich kann gehen, wenn ich die Architektur von CNN ändere, und ich denke, es war zu klein, um das Bild 32 * 32 zu machen. .. .. Wann Ich werde GitHub beim nächsten Mal den Code, den Variablennamen, den Funktionsnamen usw. geben. Ich würde es begrüßen, wenn Sie auf merkwürdige Punkte hinweisen könnten.

Recommended Posts

Klassifizieren Sie Anime-Gesichter mit tiefem Lernen mit Chainer
Klassifizieren Sie Anime-Gesichter durch Fortsetzung / Deep Learning mit Keras
Versuchen Sie es mit Chainer Deep Q Learning - Launch
[Einführung in StyleGAN2] Unabhängiges Lernen mit 10 Anime-Gesichtern ♬
Versuchen Sie es mit TensorFlow
Deep Kernel Learning mit Pyro
Versuchen Sie Deep Learning mit FPGA
Deep Embedded Clustering mit Chainer 2.0
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
Versuchen Sie es mit TensorFlow Part 2
[Chainer] Lernen von XOR mit mehrschichtigem Perzeptron
Erste Anime-Gesichtserkennung mit Chainer
Überprüfen Sie die Kniebeugenform mit tiefem Lernen
Kategorisieren Sie Nachrichtenartikel mit Deep Learning
Snack-Umsatzprognose mit Deep Learning
Versuchen Sie Common Representation Learning mit Chainer
Bringen Sie Menschen mit Deep Learning zum Lächeln
(Python) Deep Learning Library Chainer-Grundlagen Grundlagen
Einführung in Deep Learning (2) - Versuchen Sie Ihre eigene nichtlineare Regression mit Chainer-
Tiefes Lernen
Probieren Sie die Bitcoin-Preisprognose mit Deep Learning aus
Versuchen Sie mit Kipoi tiefes Erlernen der Genomik
Emotionale Analyse von Tweets mit Deep Learning
Die Geschichte des tiefen Lernens mit TPU
Chainer und Deep Learning durch Funktionsnäherung gelernt
Laden Sie das Kaffeemodell mit Chainer und klassifizieren Sie die Bilder
Kategorisieren Sie Gesichtsbilder von Anime-Charakteren mit Chainer
Deep Learning Memorandum
Starten Sie Deep Learning
99,78% Genauigkeit bei tiefem Lernen durch Erkennen von handgeschriebenem Hiragana
Python Deep Learning
Deep Learning × Python
Seq2Seq (1) mit Chainer
Ich habe den Deep Learning Framework Chainer installiert
Erstellen Sie durch tiefes Lernen einen "Bot, der Ihnen AV-Schauspielerinnen mit ähnlichen Gesichtern sagt"
Eine Geschichte über die Vorhersage des Wechselkurses mit Deep Learning
Klassifizieren Sie Mnist-Zahlen nach Keras, ohne dass der Lehrer etwas lernt [Auto Encoder Edition]
Deep Learning Bildanalyse beginnend mit Kaggle und Keras
Klassifizieren Sie Artikel mit Tags, die von Qiita durch unbeaufsichtigtes Lernen angegeben wurden
Verwenden Sie den Scikit-Learn-Trainingsdatensatz mit Chainer (für Training / Vorhersage).
Vorhersagen von Tags durch Extrahieren von Musikfunktionen mit Deep Learning
DNN (Deep Learning) Library: Vergleich von Chainer und TensorFlow (1)
Versuchen wir nun die Gesichtserkennung mit Chainer (Lernphase)
"Objektorientiert" mit Python gelernt
Python: Deep Learning-Praxis
Deep Learning / Aktivierungsfunktionen
Deep Learning von Grund auf neu
Deep Learning 1 Übung des Deep Learning
Verwenden Sie Tensorboard mit Chainer
Deep Learning / Cross Entropy
Erstes tiefes Lernen ~ Vorbereitung ~
Erstes tiefes Lernen ~ Lösung ~
[AI] Deep Metric Learning
Python lernen mit ChemTHEATER 02
Ich habe versucht, tief zu lernen
Python lernen mit ChemTHEATER 01
Ich habe versucht, Othello AI zu machen, dass ich 7,2 Millionen Hände durch tiefes Lernen mit Chainer gelernt habe