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

Hallo! Ich bin @eve_yk, ein Liaro-Ingenieur. Den Anfang der Angelegenheit finden Sie in Teil 1 (Weinen). Beim letzten Mal haben wir Daten gesammelt und verarbeitet, um den Klassifikator zu trainieren. Dieses Mal werden wir das Modell des Klassifikators beschreiben und tatsächlich lernen und bewerten (Gesichtsidentifikation)!

3. Erstellen Sie ein Modell des Klassifikators

Beschreiben Sie als Nächstes das Modell des Gesichtsbildklassifikators, der in [Chainer] trainiert werden soll (http://chainer.org/). Ich habe auf den folgenden Code verwiesen (einschließlich der vorherigen Datensatzerstellung). https://github.com/mitmul/chainer-cifar10

YTNet


class YTNet(chainer.Chain):

    def __init__(self):
        """
Modelldefinition
        """
        super(YTNet, self).__init__(
            conv1=L.Convolution2D(3, 32, 5, stride=1, pad=2),
            bn1  =L.BatchNormalization(32),
            conv2=L.Convolution2D(32, 32, 5, stride=1, pad=2),
            bn2  =L.BatchNormalization(32),
            conv3=L.Convolution2D(32, 64, 5, stride=1, pad=2),
            fc4=F.Linear(16384, 4096),
            fc5=F.Linear(4096, 2),
        )
        self.train = True

    def __call__(self, x, t):
    	"""
Vorwärtsverarbeitung
	    """
        h = F.max_pooling_2d(F.relu(self.conv1(x)), 3, stride=2)
        h = F.max_pooling_2d(F.relu(self.conv2(h)), 3, stride=2)
        h = F.relu(self.conv3(h))
        h = F.dropout(F.relu(self.fc4(h)), ratio=0.5, train=self.train)
        h = self.fc5(h)

        self.loss = F.softmax_cross_entropy(h, t)
        self.accuracy = F.accuracy(h, t)

        if self.train:
            return self.loss
        else:
            self.pred = F.softmax(h)
            return self.pred

4. Lernen Sie das Modell

Schreiben Sie den Code basierend auf dem Code in 3., um das Modell zu trainieren. Dieses Mal ist das Training relativ schnell beendet, aber wenn Sie versuchen, mit einem größeren Datensatz zu arbeiten, ist es für die psychische Gesundheit gut, den Fortschritt des Trainings zu zeigen.

train.py


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

import argparse
import os
import six
import chainer
import chainer.functions as F
import chainer.links as L
import numpy as np
from chainer import optimizers
from chainer import cuda
from chainer import serializers
from chainer import Variable
from progressbar import ProgressBar


class YTNet(chainer.Chain):

    def __init__(self):
        """
Modelldefinition
        """
        super(YTNet, self).__init__(
            conv1=L.Convolution2D(3, 32, 5, stride=1, pad=2),
            bn1  =L.BatchNormalization(32),
            conv2=L.Convolution2D(32, 32, 5, stride=1, pad=2),
            bn2  =L.BatchNormalization(32),
            conv3=L.Convolution2D(32, 64, 5, stride=1, pad=2),
            fc4=F.Linear(16384, 4096),
            fc5=F.Linear(4096, 2),
        )
        self.train = True

    def __call__(self, x, t):
        """
Vorwärtsverarbeitung
        """
        h = F.max_pooling_2d(F.relu(self.conv1(x)), 3, stride=2)
        h = F.max_pooling_2d(F.relu(self.conv2(h)), 3, stride=2)
        h = F.relu(self.conv3(h))
        h = F.dropout(F.relu(self.fc4(h)), ratio=0.5, train=self.train)
        h = self.fc5(h)

        self.loss = F.softmax_cross_entropy(h, t)
        self.accuracy = F.accuracy(h, t)

        if self.train:
            return self.loss
        else:
            self.pred = F.softmax(h)
            return self.pred

def one_epoch(args, model, optimizer, data, label, epoch, train):
    """
1epoch Training oder Evaluierungsverarbeitung
    """
    model.train = train
    xp = cuda.cupy if args.gpu >= 0 else np

    sum_accuracy = 0
    sum_loss = 0

    p = ProgressBar(min_value=0, max_value=data.shape[0]) #Zur Überprüfung des Fortschritts
    perm = np.random.permutation(data.shape[0])
    for i in xrange(0, data.shape[0], args.batchsize):
        p.update(i)
        
        #Erstellen Sie eine Mini-Charge
        target = perm[i:i + args.batchsize]
        x = xp.array(data[target], dtype=xp.float32)
        t = xp.array(label[target], dtype=xp.int32)

        #Variable erstellen
        volatile = 'off' if train else 'on'
        x = Variable(x, volatile=volatile)
        t = Variable(t, volatile=volatile)

        #Parameteraktualisierung oder Etikettenvorhersage
        if train:
            optimizer.update(model, x, t)
        else:
            pred = model(x, t).data
        
        sum_loss += float(model.loss.data) * t.data.shape[0]
        sum_accuracy += float(model.accuracy.data) * t.data.shape[0]

        del x, t

    print "" #Für Zeilenumbrüche
    if train:
        print "train epoch " + str(epoch)
        print "   train loss : " + str(sum_loss / data.shape[0])
        print "   train acc  : " + str(sum_accuracy / data.shape[0])
    else:
        print "test epoch " + str(epoch)
        print "   test loss : " + str(sum_loss / data.shape[0])
        print "   test acc  : " + str(sum_accuracy / data.shape[0])

def load_dataset(datadir):
    """
Laden Sie den Datensatz
    """
    train_data = np.load('%s/train_data.npy' % datadir)
    train_labels = np.load('%s/train_label.npy' % datadir)
    test_data = np.load('%s/test_data.npy' % datadir)
    test_labels = np.load('%s/test_label.npy' % datadir)

    return train_data, train_labels, test_data, test_labels

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--gpu", type=int, default=-1)
    parser.add_argument("--batchsize", type=int, default=10)
    parser.add_argument('--data_dir', type=str, default='dataset')
    parser.add_argument('--output_dir', type=str, default='result')
    args = parser.parse_args()

    # model,Optimierer erstellen
    model = YTNet()
    optimizer = optimizers.Adam(alpha=0.00005)
    optimizer.setup(model)

    #Datensatz laden
    dataset = load_dataset(args.data_dir)
    tr_data, tr_labels, te_data, te_labels = dataset

    #Hauptschleife
    for epoch in range(1, 20):
        #Ausbildung
        one_epoch(args, model, optimizer, tr_data, tr_labels, epoch, True)
        #Auswertung
        one_epoch(args, model, optimizer, te_data, te_labels, epoch, False)

    #Modell speichern
    if not os.path.exists(args.output_dir):
        os.makedirs(args.output_dir)
    serializers.save_npz(args.output_dir + "YTNet.chainermodel", model)
    serializers.save_npz(args.output_dir + "YTNet.state", optimizer)

Nach dem Training in etwa 20 Epochen lag die Genauigkeit der Trainingsdaten über 99%.

5. Bewerten Sie die Leistung

Schließlich werden wir die Leistung bewerten. Testen Sie mit den folgenden 10 Bildern. Fünf von ihnen sind @eve_yk und fünf sind Super Maradona Tanaka. Ein Beispiel für das Gesicht finden Sie im Vorherigen Artikel. Versuchen Sie also zu erraten, ob Sie es erraten können.

test.JPG

Ich bin ein wenig besorgt, aber Sie können es mit dem menschlichen Auge sehen. Es unterscheidet sich von der Farbe der Brille. Die richtige Antwort lautet eve_yk für 1,2,4,7,10 und Mr. Tanaka für 3,5,6,8,9.

Was ist nun mit dem CNN, das Sie dieses Mal gelernt haben? Testen Sie mit dem folgenden Code.

test.py


# coding:utf-8

import os
import sys
import argparse
import glob
import cv2
import numpy as np
from chainer import Variable
from chainer import serializers
from train import YTNet

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)

file2labels = {"01.jpg ":"eve_yk", "02.jpg ":"eve_yk", "03.jpg ":"tanaka",
			   "04.jpg ":"eve_yk", "05.jpg ":"tanaka", "06.jpg ":"tanaka",
			   "07.jpg ":"eve_yk", "08.jpg ":"tanaka", "09.jpg ":"tanaka",
			   "10.jpg ":"eve_yk"}


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('--model_path',  required=True, type=str)
	args = parser.parse_args()

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

	#Modell laden
	model = YTNet()
	model = serializers.load_npz(args.model_path, , model)

	#Bewerten Sie eins nach dem anderen
	collect_count = 0.0
        test_count = 0.0
	for file_path in test_files:
		image = cv2.imread(file_path)
		if image is None:
			#Lesefehler
			continue
                test_count += 1.0

		#Holen Sie sich den Dateinamen aus der Verzeichnisstruktur
		file_name = file_path.split("/")[-1]
                print file_name+"("+file2labels[file_name]+") :",

		#In Chainer-Format konvertieren
		image = transpose_opencv2chainer(image)
		x = Variable(np.asarray([image], dtype=np.float32), volatile="on")
		t = Variable(np.asarray([[0]], dtype=np.int32), volatile="on")

		#Auswertung
		pred = model(x, t).data
		if int(pred) == 0: # tanaka
			print u"Identifikationsergebnis "tanaka""
			if file2labels[file_name] == u"tanaka":
				collect_count += 1.0
		else: # eve_yk
			print u"Identifikationsergebnis "Vorabend_yk」"
			if file2labels[file_name] == u"eve_yk":
				collect_count += 1.0	

	print u"total:{}%".format(collect_count/test_count*100)

Das Ergebnis ist diese Straße

python test.py --input_path test/ --model_path result/YTNet.chainermodel
08.jpg(tanaka) :Identifikationsergebnis "tanaka"
09.jpg(tanaka) :Identifikationsergebnis "Vorabend_yk」
07.jpg(eve_yk) :Identifikationsergebnis "Vorabend_yk」
01.jpg(eve_yk) :Identifikationsergebnis "Vorabend_yk」
03.jpg(tanaka) :Identifikationsergebnis "tanaka"
06.jpg(tanaka) :Identifikationsergebnis "Vorabend_yk」
02.jpg(eve_yk) :Identifikationsergebnis "Vorabend_yk」
05.jpg(tanaka) :Identifikationsergebnis "tanaka"
04.jpg(eve_yk) :Identifikationsergebnis "Vorabend_yk」
10.jpg(eve_yk) :Identifikationsergebnis "Vorabend_yk」
total:8.0/10

Ich habe Mr. Tanaka von 6 und 9 mit eve_yk verwechselt. Handelt es sich um eine voreingenommene Vorhersage aufgrund der unterschiedlichen Menge an Trainingsdaten? Ich habe jedoch das Gefühl, dass das für das menschliche Auge störende Bild falsch ist. Schließlich scheint es schwierig zu sein, Doppelgenger von einem halbfertigen System zu unterscheiden.

abschließend

Ich habe einen Gesichtsklassifikator erstellt, der mein Aussehen identifiziert. Die Genauigkeit ist in Ordnung. Ich finde es gut, dass es viele Kompromisse wie Datenanzahl und Vorverarbeitung gab. Es wäre interessant, hart zu arbeiten, um Daten zu sammeln und eine größere Anzahl von Personen zu klassifizieren, oder hart an der Vorverarbeitung zu arbeiten, um die Genauigkeit zu verbessern!

Liaro und eve_yk machen sich für Super Maradona stark!

Referenz

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

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 2)
Da es Doppelgenger gab, habe ich versucht, es mit künstlicher Intelligenz zu unterscheiden (lacht) (Teil 1)
Ein Anfänger versuchte, eine Strichzeichnung mit einem Kettenmesser zu färben. Ich konnte es schaffen.
Ein Memorandum beim automatischen Erwerb mit Selen
Da es keine Beschreibung zum Erstellen einer Umgebung für nnabla mit Docker einschließlich GPU gibt, habe ich es selbst versucht, Teil 1
Als ich versuchte, eine VPC mit AWS CDK zu erstellen, konnte ich es aber nicht schaffen
Als ich in IPython versuchte, den Wert zu sehen, war es ein Generator, also kam ich auf ihn, als ich frustriert war.
Ich wollte die Google-Tabelle mit AWS Lambda betreiben, also habe ich es versucht [Teil 2]
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
Ich habe versucht, eine zufällige FizzBuzz-Spalte mit Blasensortierung zu sortieren.
Ich habe versucht, in einem tief erlernten Sprachmodell zu schreiben
[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
[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
[Python] Als ich versuchte, ein Dekomprimierungswerkzeug mit einer Zip-Datei zu erstellen, die ich gerade kannte, war ich süchtig nach sys.exit ()
Da es der 20. Jahrestag der Gründung ist, habe ich versucht, die Texte von Parfüm mit Word Cloud zu visualisieren
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
Ich habe ein Systemkonfigurationsdiagramm mit Diagrams on Docker geschrieben
Verwenden Sie Python aus Java mit Jython. Ich war auch süchtig danach.
Ich habe versucht, mit Raspeye 4 (Python Edition) ein signalähnliches Signal zu erzeugen.
Ich habe versucht, ein Plug-In mit HULFT IoT Edge Streaming [Ausführung] (3/3) zu erstellen.
Ich habe versucht, mit django eine E-Mail zum Abschluss der Registrierung von Google Mail zu senden.
[Outlook] Ich habe versucht, mit Python automatisch eine tägliche Berichtsmail zu erstellen
Ich habe versucht, ein Plug-In mit HULFT IoT Edge Streaming [Setup] (1/3) zu erstellen.
Ich habe versucht, eine Mac Python-Entwicklungsumgebung mit pythonz + direnv zu erstellen
[Zaif] Ich habe versucht, den Handel mit virtuellen Währungen mit Python zu vereinfachen
Ich habe versucht, einen URL-Verkürzungsdienst mit AWS CDK serverlos zu machen
Ich war süchtig danach, Cython mit PyCharm auszuprobieren, also machen Sie sich eine Notiz
Ich habe versucht, einen Linebot zu erstellen (Implementierung)
Ich habe versucht zu simulieren, wie viel es kosten würde, mit Soshages Gacha einen sehr seltenen Charakter zu komponieren