[PYTHON] Versuchen wir nun die Gesichtserkennung mit Chainer (Lernphase)

Überblick

Das Ende der Entwicklung von Chainer wurde angekündigt und die Gesichtserkennung ist voller Gefühle. Ich werde es hier als Memorandum buchstabieren.

Diese Serie wird in zwei Teilen verschickt. Dieses Mal werde ich erklären, wie die Lernphase (Lernen von Gesichtsbildern) implementiert wird. Nächstes Mal werde ich die Implementierung von Vorhersagephase (Gesichtserkennung mit einer Kamera) erläutern.

Da ich zu dieser Zeit ein Anfänger in ML und ein Schüler war, kann es außerdem zu Fehlern in den Informationen oder zu einem Fehler im Programm kommen. Wenn es so etwas gibt, wäre ich dankbar, wenn Sie in den Kommentaren darauf hinweisen könnten. (Erstellungsdatum des Artikels: 2020/2/9)

Umgebung

-Software- Windows 10 Home Anaconda3 64-bit(Python3.7) Spyder -Library- Chainer 7.0.0 -Hardware- CPU: Intel core i9 9900K GPU: NVIDIA GeForce GTX1080ti RAM: 16GB 3200MHz

Referenz

** Bücher ** CQ Publishing Deep Learning Beginnend mit Arithmetik und Himbeere ([Amazon-Seite](https://www.amazon.co.jp/%E7%AE%97%E6%95%B0-%E3%83%A9%E3%82%BA%E3%83%91% E3% 82% A4% E3% 81% 8B% E3% 82% 89% E5% A7% 8B% E3% 82% 81% E3% 82% 8B-% E3% 83% 87% E3% 82% A3% E3 % 83% BC% E3% 83% 97% E3% 83% BB% E3% 83% A9% E3% 83% BC% E3% 83% 8B% E3% 83% B3% E3% 82% B0-% E3% 83% 9C% E3% 83% BC% E3% 83% 89% E3% 83% BB% E3% 82% B3% E3% 83% B3% E3% 83% 94% E3% 83% A5% E3% 83% BC% E3% 82% BF% E3% 83% BB% E3% 82% B7% E3% 83% AA% E3% 83% BC% E3% 82% BA-% E7% 89% A7% E9% 87% 8E / dp / 4789847063))) Seite? ˅ Chainer-API-Referenz

Programm

Vorerst werde ich es auf Github veröffentlichen. https://github.com/himazin331/Face-Recognition-Chainer- Das Repository enthält eine Lernphase, eine Vorhersagephase, ein Datenverarbeitungsprogramm und Haar-Cascade.

Annahme

** Anaconda3 muss installiert sein ** für den Programmbetrieb. Im Folgenden erfahren Sie, wie Sie Anaconda3 herunterladen und installieren. Anaconda3-Download-Site Anaconda3-Installationsmethode (Windows)

Wenn Ihnen das hier von meinem Freund gefällt, lesen Sie es bitte.

Nach der Installation von Anaconda3 an der Eingabeaufforderung von Anaconda3 pip install chainer Bitte geben Sie Chainer ein und installieren Sie es.

Über Trainingsdaten

In diesem Programm ** sind die Trainingsdaten ein Graustufenbild und eine 32x32px JPEG-Datei ** Es wird vor Ort implementiert. Bitte verwenden Sie hier für die Datenverarbeitung.

Quellcode

** Bitte beachten Sie, dass der Code verschmutzt ist ... **

face_recog_train_CH.py



import argparse as arg
import os
import sys

import chainer
import chainer.functions as F
import chainer.links as L 
from chainer import training
from chainer.training import extensions

#Definition von CNN
class CNN(chainer.Chain):
    
    #Definition jeder Schicht
    def __init__(self, n_out):
        super(CNN, self).__init__(
            #Definition der Faltungsschicht
            conv1 = L.Convolution2D(1, 16, 5, 1, 0),  # 1st
            conv2 = L.Convolution2D(16, 32, 5, 1, 0), # 2nd
            conv3 = L.Convolution2D(32, 64, 5, 1, 0), # 3rd

            #Lineare Verbindung aller Neuronen
            link = L.Linear(None, 1024), #Vollständig verbundene Schicht
            link_class = L.Linear(None, n_out), #Vollständig verbundene Schicht zur Klassifizierung(n_out:Anzahl der Klassen)
        )
        
    #Vorwärtsausbreitung
    def __call__(self, x):
        
        #Faltschicht->ReLU-Funktion->Maximale Pooling-Schicht
        h1 = F.max_pooling_2d(F.relu(self.conv1(x)), ksize=2)   # 1st
        h2 = F.max_pooling_2d(F.relu(self.conv2(h1)), ksize=2)  # 2nd
        h3 = F.relu(self.conv3(h2))  # 3rd
        
        #Vollständig verbundene Schicht->ReLU-Funktion
        h4 = F.relu(self.link(h3))
        
        #Voraussichtliche Wertrendite
        return self.link_class(h4) #Vollständig verbundene Schicht zur Klassifizierung
 
# Trainer
class trainer(object):
    
    #Modellbau,Setup der Optimierungsmethode
    def __init__(self):
        
        #Modellbau
        self.model = L.Classifier(CNN(2))
        
        #Methodeneinstellung optimieren
        self.optimizer = chainer.optimizers.Adam() #Adam-Algorithmus
        self.optimizer.setup(self.model) #Stellen Sie das Modell im Optimierer ein
        
    #Lernen
    def train(self, train_set, batch_size, epoch, gpu, out_path):

        #Entspricht der GPU-Verarbeitung
        if gpu >= 0:
            chainer.cuda.get_device(gpu).use() #Geräteobjekt abrufen
            self.model.to_gpu()  #Kopieren Sie den Inhalt der Instanz auf die GPU
        
        #Erstellen eines Dataset-Iterators(Definition der iterativen Verarbeitung von Trainingsdaten,Mische jede Schleife)
        train_iter = chainer.iterators.SerialIterator(train_set, batch_size)

        #Updater erstellen
        updater = training.StandardUpdater(train_iter, self.optimizer, device=gpu)
        #Erstellen Sie einen Trainer
        trainer = training.Trainer(updater, (epoch, 'epoch'), out=out_path)

        #Erweiterungseinstellungen
        #Schematisierung des Verarbeitungsflusses
        trainer.extend(extensions.dump_graph('main/loss'))
        #Schreiben Sie für jedes Lernen einen Schnappschuss
        trainer.extend(extensions.snapshot(), trigger=(epoch, 'epoch'))
        # log(JSON-Format)Schreiben
        trainer.extend(extensions.LogReport())
        #Zeichnen Sie den Verlustwert in das Diagramm ein
        trainer.extend(
                extensions.PlotReport('main/loss', 'epoch', file_name='loss.png'))
        #Zeichnen Sie die Vorhersagegenauigkeit in einem Diagramm
        trainer.extend(
                extensions.PlotReport('main/accuracy', 'epoch', file_name='accuracy.png'))
        #"Anzahl der Lernvorgänge" für jedes Lernvorgang,Verlustwert,Vorhersagegenauigkeit,Ausgabe "verstrichene Zeit"
        trainer.extend(extensions.PrintReport(
                ['epoch', 'main/loss', 'main/accuracy', 'elapsed_time']))
        #Fortschrittsbalkenanzeige
        trainer.extend(extensions.ProgressBar())

        #Fang an zu lernen
        trainer.run()

        print("___Training finished\n\n")
        
        #Machen Sie die Modell-CPU kompatibel
        self.model.to_cpu()
    
        #Parameter speichern
        print("___Saving parameter...")
        param_name = os.path.join(out_path, "face_recog.model") #Gelernte Parameter speichern Ziel
        chainer.serializers.save_npz(param_name, self.model) #Schreiben Sie trainierte Parameter im NPZ-Format
        print("___Successfully completed\n\n")
    
#Datensatzerstellung
def create_dataset(data_dir):
    
    print("\n___Creating a dataset...")
    
    cnt = 0
    prc = ['/', '-', '\\', '|']
    
    #Anzahl der Bildsätze
    print("Number of Rough-Dataset: {}".format(len(os.listdir(data_dir))))
    #Anzahl der Bilddaten
    for c in os.listdir(data_dir):
        d = os.path.join(data_dir, c)
        print("Number of image in a directory \"{}\": {}".format(c, len(os.listdir(d))))
    
    train = []  #Temporärer Datensatz
    label = 0
    
    #Temporäre Datensatzerstellung
    for c in os.listdir(data_dir):
        
        print('\nclass: {}, class id: {}'.format(c, label))   #Ausgabe von Klassenname und Klassen-ID
       
        d = os.path.join(data_dir, c)    #Kombinieren Sie Ordnernamen und Klassenordnernamen
        imgs = os.listdir(d)    #Holen Sie sich alle Bilddateien
        
        #Lesen Sie nur Bilddateien im JPEG-Format
        for i in [f for f in imgs if ('jpg'or'JPG' in f)]:        
            
            #Durch Cache-Datei
            if i == 'Thumbs.db':
                continue
            
            train.append([os.path.join(d, i), label])   #Speichern Sie nach dem Kombinieren des Klassenordnerpfads und des Bilddateinamens in der Liste

            cnt += 1
            
            print("\r   Loading a images and labels...{}    ({} / {})".format(prc[cnt%4], cnt, len(os.listdir(d))), end='')
            
        print("\r   Loading a images and labels...Done    ({} / {})".format(cnt, len(os.listdir(d))), end='')
        
        label += 1
        cnt = 0

    train_set = chainer.datasets.LabeledImageDataset(train, '.')    #Datensatz
    
    print("\n___Successfully completed\n")
    
    return train_set
    
def main():

    #Befehlszeilenoptionen
    parser = arg.ArgumentParser(description='Face Recognition train Program(Chainer)')
    parser.add_argument('--data_dir', '-d', type=str, default=None,
                        help='Angeben des Ordnerpfads(Fehler, wenn nicht angegeben)')
    parser.add_argument('--out', '-o', type=str, 
                        default=os.path.dirname(os.path.abspath(__file__))+'/result'.replace('/', os.sep),
                        help='Geben Sie das Speicherziel der Parameter an(Standardwert./result)')
    parser.add_argument('--batch_size', '-b', type=int, default=32,
                        help='Angeben der Mini-Stapelgröße(Standardwert 32)')
    parser.add_argument('--epoch', '-e', type=int, default=15,
                        help='Angabe der Anzahl der Lernvorgänge(Standardwert 15)')
    parser.add_argument('--gpu', '-g', type=int, default=-1,
                        help='Angeben der GPU-ID(Negative Werte zeigen die CPU-Verarbeitung an,Standardwert-1)')
    args = parser.parse_args()

    #Ordner nicht angegeben->Ausnahme
    if args.data_dir == None:
        print("\nException: Folder not specified.\n")
        sys.exit()
    #Wenn Sie einen Ordner angeben, der nicht vorhanden ist->Ausnahme
    if os.path.exists(args.data_dir) != True:
        print("\nException: Folder {} is not found.\n".format(args.data_dir))
        sys.exit()

    #Informationsausgabe einstellen
    print("=== Setting information ===")
    print("# Images folder: {}".format(os.path.abspath(args.data_dir)))
    print("# Output folder: {}".format(args.out))
    print("# Minibatch-size: {}".format(args.batch_size))
    print("# Epoch: {}".format(args.epoch))
    print("===========================")

    #Datensatzerstellung
    train_set = create_dataset(args.data_dir)

    #Fang an zu lernen
    print("___Start training...")
    Trainer = trainer()
    Trainer.train(train_set, args.batch_size, args.epoch, args.gpu, args.out)
   
if __name__ == '__main__':
    main()

Ausführungsergebnis

image.png

image.png Nach der Ausführung wird die obige Datei im Speicherziel generiert.

Befehl python face_recog_train_CH.py -d <Ordner> -e <Anzahl der Lernvorgänge> -b <Batchgröße> (-o <Speichern> -g <GPU ID>) Die Datei wird standardmäßig in ". / Result" gespeichert.

Erläuterung

Ich werde den Code erklären. Leider ist die Erklärungsfähigkeit schlecht.

Netzwerkmodell

Das Netzwerkmodell ist diesmal ein Faltungs-Neuronales Netzwerk (CNN). Das Netzwerkmodell ist in der CNN-Klasse definiert.

CNN-Klasse


#Definition von CNN
class CNN(chainer.Chain):
    
    #Definition jeder Schicht
    def __init__(self, n_out):
        super(CNN, self).__init__(
            #Definition der Faltungsschicht
            conv1 = L.Convolution2D(1, 16, 5, 1, 0),  # 1st
            conv2 = L.Convolution2D(16, 32, 5, 1, 0), # 2nd
            conv3 = L.Convolution2D(32, 64, 5, 1, 0), # 3rd

            #Lineare Verbindung aller Neuronen
            link = L.Linear(None, 1024), #Vollständig verbundene Schicht
            link_class = L.Linear(None, n_out), #Vollständig verbundene Schicht zur Klassifizierung(n_out:Anzahl der Klassen)
        )
        
    #Vorwärtsausbreitung
    def __call__(self, x):
        
        #Faltschicht->ReLU-Funktion->Maximale Pooling-Schicht
        h1 = F.max_pooling_2d(F.relu(self.conv1(x)), ksize=2)   # 1st
        h2 = F.max_pooling_2d(F.relu(self.conv2(h1)), ksize=2)  # 2nd
        h3 = F.relu(self.conv3(h2))  # 3rd
        
        #Vollständig verbundene Schicht->ReLU-Funktion
        h4 = F.relu(self.link(h3))
        
        #Voraussichtliche Wertrendite
        return self.link_class(h4) #Vollständig verbundene Schicht zur Klassifizierung

Wir übergeben chainer.Chain als Argument an die CNN-Klasse. chainer.Chain ist eine Chainer-spezifische Klasse und bildet den Kern des Netzwerks. Rufen Sie beim Erstellen einer Instanz die Instanzmethode __init __ auf und rufen Sie die Instanzmethode der Oberklasse chainer.Chain auf, um die Faltungsschicht und die vollständig verbundene Schicht zu definieren.

Die Hyperparameter der Faltungsschicht in diesem Programm sind in der folgenden Tabelle aufgeführt.

Eingangskanal Ausgangskanal Filtergröße Schrittweite Polsterbreite
1st 1 16 5 1 0
2nd 16 32 5 1 0
3rd 32 64 5 1 0

Da angenommen wird, dass die Trainingsdaten ein Graustufenbild sind, wird die Anzahl der Eingangskanäle der ersten Faltungsschicht auf 1 gesetzt. Wenn es sich um ein RGB-Bild handelt, ist es 3. "Auffüllbreite 0" bedeutet, dass kein Auffüllvorgang ausgeführt wird.

Die Hyperparameter für die vollständig verbundene Schicht sind in der folgenden Tabelle aufgeführt.

Anzahl der Eingangsdimensionen Anzahl der Ausgangsabmessungen
Vollständig verbundene Schicht None 1024
Zur Klassifizierung None 2

Wenn Sie für die Anzahl der Eingabedimensionen "Keine" angeben, wird die Anzahl der Dimensionen der Eingabedaten automatisch angewendet.

Dieses Mal mache ich eine ** 2-Klassenklassifizierung **, also setze ich die Anzahl der Ausgabedimensionen der vollständig verbundenen Schicht für die ** Klassenklassifizierung auf 2 **. Wenn Sie eine Instanz der Klasse CNN erstellen, indem Sie einen numerischen Wert in das Argument eingeben, entspricht die Klassenklassifizierung diesem numerischen Wert. (Im Code bedeutet "n_out", welche Klasse klassifiziert werden soll.)

Die andere Methode, __call__, wird für die Vorwärtsausbreitung verwendet. Die Gesamtstruktur ist in der folgenden Abbildung dargestellt. image.png Die Pooling-Schicht ist das maximale Pooling ** mit dem Pooling-Bereich ** 2 x 2.


Datensatzerstellung

Zunächst sind einige Punkte zum Datensatz zu beachten, daher werde ich zunächst die Funktion erläutern, mit der der Datensatz erstellt wird. Das Dataset wird mit der Funktion crate_dataset erstellt.

create_Datensatzfunktion


#Datensatzerstellung
def create_dataset(data_dir):
    
    print("\n___Creating a dataset...")
    
    cnt = 0
    prc = ['/', '-', '\\', '|']
    
    #Anzahl der Bildsätze
    print("Number of Rough-Dataset: {}".format(len(os.listdir(data_dir))))
    #Anzahl der Bilddaten
    for c in os.listdir(data_dir):
        d = os.path.join(data_dir, c)
        print("Number of image in a directory \"{}\": {}".format(c, len(os.listdir(d))))
    
    train = []  #Temporärer Datensatz
    label = 0
    
    #Temporäre Datensatzerstellung
    for c in os.listdir(data_dir):
        
        print('\nclass: {}, class id: {}'.format(c, label))   #Ausgabe von Klassenname und Klassen-ID
       
        d = os.path.join(data_dir, c)    #Kombinieren Sie Ordnernamen und Klassenordnernamen
        imgs = os.listdir(d)    #Holen Sie sich alle Bilddateien
        
        #Lesen Sie nur Bilddateien im JPEG-Format
        for i in [f for f in imgs if ('jpg'or'JPG' in f)]:        
            
            #Durch Cache-Datei
            if i == 'Thumbs.db':
                continue
            
            train.append([os.path.join(d, i), label])   #Speichern Sie nach dem Kombinieren des Klassenordnerpfads und des Bilddateinamens in der Liste

            cnt += 1
            
            print("\r   Loading a images and labels...{}    ({} / {})".format(prc[cnt%4], cnt, len(os.listdir(d))), end='')
            
        print("\r   Loading a images and labels...Done    ({} / {})".format(cnt, len(os.listdir(d))), end='')
        
        label += 1
        cnt = 0

    train_set = chainer.datasets.LabeledImageDataset(train, '.')    #Datensatz
    
    print("\n___Successfully completed\n")
    
    return train_set

Der Datensatz im Klassifizierungsproblem erfordert Trainingsdaten und korrekte Beschriftungen.

In diesem Fall ** sind die Trainingsdaten ein Gesichtsbild, und das richtige Antwortetikett ist der numerische Wert, der diesem Gesicht entspricht **. Zum Beispiel, wenn es falsche und korrekte Klassen gibt "0" für alle Bezeichnungen der Trainingsdaten in der falschen Antwortklasse Die Beschriftungen der Trainingsdaten in der richtigen Antwortklasse werden gemeinsam auf "1" gesetzt. Aufgrund seiner Natur müssen Sie auf die Struktur des Ordners achten.

** ** dataset.png

Wie oben in einem Ordner (train_data), Erstellen Sie für jede Klasse einen Ordner (false, true) und legen Sie die Bilddaten darin ab. Auf diese Weise wird das richtige Antwortetikett der in false enthaltenen Trainingsdaten zu 0 und das in true enthaltene richtige Antwortetikett zu 1. In diesem Beispiel gibt die Befehlsoption -d train_data an.

Nachdem Sie so etwas wie die Notizen im Code gemacht haben Schließlich im folgenden Code eine Liste der Trainingsdaten und -etiketten, Erstellen Sie es formal als Datensatz.

    train_set = chainer.datasets.LabeledImageDataset(train, '.')    #Datensatz

Lernen

Richten Sie ein und lernen Sie, bevor Sie in der Trainerklasse maschinell lernen.

Trainerklasse(Instanzmethode)


# Trainer
class trainer(object):
    
    #Modellbau,Setup der Optimierungsmethode
    def __init__(self):
        
        #Modellbau
        self.model = L.Classifier(CNN(2))
        
        #Methodeneinstellung optimieren
        self.optimizer = chainer.optimizers.Adam() #Adam-Algorithmus
        self.optimizer.setup(self.model) #Stellen Sie das Modell im Optimierer ein

Rufen Sie beim Erstellen einer Instanz die Instanzmethode __init__ auf, um den Algorithmus zur Erstellung und Optimierung des Netzwerkmodells zu bestimmen. Mit "self.model = L.Classifier (CNN (2))" kann ** in eine beliebige Anzahl von Klassen klassifiziert werden, indem ein beliebiger Wert in die Klammern von ** CNN (2) ** gesetzt wird.

Nach der Erstellung gibt die Chainer.links-Methode "L.Classifier ()" die Aktivierungs- und Verlustfunktionen an. Die Aktivierungsfunktion ist hier eine Aktivierungsfunktion, die zum Zeitpunkt der Ausgabe verwendet wird, wie beispielsweise die Softmax-Funktion. Die Aktivierungsfunktion ist auf die Softmax-Funktion und die Verlustfunktion standardmäßig auf den Kreuzentropiefehler ** eingestellt. Bei einem Klassifizierungsproblem gibt es also kein Problem, nur das Netzwerkmodell zu verpacken.

Nachdem Sie eine Instanz des Optimierungsalgorithmus ** Adam ** mit self.optimizer = chainer.optimizers.Adam () erstellt haben, Wenden Sie das Netzwerkmodell mit "self.optimizer.setup (self.model)" an.


In der "Zug" -Methode in der "Trainer" -Klasse, Wir werden Dataset-Iteratoren, Updater und Trainer erstellen und trainieren.

Trainerklasse(Zugmethode)


    #Lernen
    def train(self, train_set, batch_size, epoch, gpu, out_path):

        #Entspricht der GPU-Verarbeitung
        if gpu >= 0:
            chainer.cuda.get_device(gpu).use() #Geräteobjekt abrufen
            self.model.to_gpu()   #Kopieren Sie den Inhalt der Instanz auf die GPU

        #Erstellen eines Dataset-Iterators(Definition der iterativen Verarbeitung von Trainingsdaten,Mische jede Schleife)
        train_iter = chainer.iterators.SerialIterator(train_set, batch_size)

        #Updater erstellen
        updater = training.StandardUpdater(train_iter, self.optimizer, device=gpu)
        #Erstellen Sie einen Trainer
        trainer = training.Trainer(updater, (epoch, 'epoch'), out=out_path)

        #Erweiterungseinstellungen
        #Schematisierung des Verarbeitungsflusses
        trainer.extend(extensions.dump_graph('main/loss'))
        #Schreiben Sie für jedes Lernen einen Schnappschuss
        trainer.extend(extensions.snapshot(), trigger=(epoch, 'epoch'))
        # log(JSON-Format)Schreiben
        trainer.extend(extensions.LogReport())
        #Zeichnen Sie den Verlustwert in das Diagramm ein
        trainer.extend(
                extensions.PlotReport('main/loss', 'epoch', file_name='loss.png'))
        #Zeichnen Sie die Vorhersagegenauigkeit in einem Diagramm
        trainer.extend(
                extensions.PlotReport('main/accuracy', 'epoch', file_name='accuracy.png'))
        #"Anzahl der Lernvorgänge" für jedes Lernvorgang,Verlustwert,Vorhersagegenauigkeit,Ausgabe "verstrichene Zeit"
        trainer.extend(extensions.PrintReport(
                ['epoch', 'main/loss', 'main/accuracy', 'elapsed_time']))
        #Fortschrittsbalkenanzeige
        trainer.extend(extensions.ProgressBar())

        #Fang an zu lernen
        trainer.run()

        print("___Training finished\n\n")

        #Machen Sie die Modell-CPU kompatibel
        self.model.to_cpu()

        #Parameter speichern
        print("___Saving parameter...")
        param_name = os.path.join(out_path, "face_recog.model") #Gelernte Parameter speichern Ziel
        chainer.serializers.save_npz(param_name, self.model) #Schreiben Sie trainierte Parameter im NPZ-Format
        print("___Successfully completed\n\n")

Der folgende Code ist ** Erstellen eines Dataset-Iterators **.

        #Erstellen eines Dataset-Iterators(Definition der iterativen Verarbeitung von Trainingsdaten,Mische jede Schleife)
        train_iter = chainer.iterators.SerialIterator(train_set, batch_size)

Es ** erstellt Shuffles und Mini-Batch der Datenreihenfolge **. Geben Sie den Zieldatensatz (train_set) und die Mini-Batch-Größe ( batch_size) als Argumente an.


Als nächstes ** erstelle einen Updater **.

        #Updater erstellen
        updater = training.StandardUpdater(train_iter, self.optimizer, device=gpu)

updater ** aktualisiert die Parameter **. Geben Sie als Argumente den Dataset-Iterator (train_iter), den Optimierungsalgorithmus ( self.optimizer) und ggf. die GPU-ID an. Der Optimierungsalgorithmus ist "self.optimizer.setup ()", der den Optimierungsalgorithmus auf das Netzwerkmodell anwendet. Selbst wenn Sie chainer.optimizers.Adam () direkt angeben, funktioniert dies nicht.


Erstellen Sie als Nächstes einen ** Trainer **.

        #Erstellen Sie einen Trainer
        trainer = training.Trainer(updater, (epoch, 'epoch'), out=out_path)

Trainer ** implementiert eine Lernschleife **. Wir werden definieren, welche Auslöser (Bedingungen) das Lernen beenden. Wird normalerweise durch die Anzahl der Lernepochen oder -iterationen ausgelöst.

In diesem Fall wird ** die Anzahl der Lernepochen als Auslöser ** gesetzt. Als Argumente Updater (updater) und Stop Trigger ((Epoche, 'Epoche')) Geben Sie außerdem das Speicherziel der von der Erweiterung erstellten Datei an.


Als nächstes wird endlich gelernt! Fügen wir vorher eine praktische Erweiterung hinzu. Der Chainer hat eine Erweiterung namens ** Trainer Extension **.

        #Erweiterungseinstellungen
        #Schematisierung des Verarbeitungsflusses
        trainer.extend(extensions.dump_graph('main/loss'))
        #Schreiben Sie für jedes Lernen einen Schnappschuss
        trainer.extend(extensions.snapshot(), trigger=(epoch, 'epoch'))
        # log(JSON-Format)Schreiben
        trainer.extend(extensions.LogReport())
        #Zeichnen Sie den Verlustwert in das Diagramm ein
        trainer.extend(
                extensions.PlotReport('main/loss', 'epoch', file_name='loss.png'))
        #Zeichnen Sie die Vorhersagegenauigkeit in einem Diagramm
        trainer.extend(
                extensions.PlotReport('main/accuracy', 'epoch', file_name='accuracy.png'))
        #"Anzahl der Lernvorgänge" für jedes Lernvorgang,Verlustwert,Vorhersagegenauigkeit,Ausgabe "verstrichene Zeit"
        trainer.extend(extensions.PrintReport(
                ['epoch', 'main/loss', 'main/accuracy', 'elapsed_time']))
        #Fortschrittsbalkenanzeige
        trainer.extend(extensions.ProgressBar())

Hier, -Eine Funktion, die Eingabedaten und Parameterfluss in die folgende DOT-Datei schreibt ・ Eine Funktion, die Informationen wie Parameter am Ende des Lernens aufzeichnet (Sie können das Lernen von der Mitte aus mithilfe eines Schnappschusses neu starten.)


Nach dem Hinzufügen der Erweiterungsfunktion wird das Lernen endlich gestartet.

        #Fang an zu lernen
        trainer.run()

Mit dieser einen Zeile beginnt alles (?) Warten wir, bis das Lernen beendet ist.

Speichern Sie nach dem Lernen die Parameter.

        #Parameter speichern
        print("___Saving parameter...")
        param_name = os.path.join(out_path, "face_recog.model") #Gelernte Parameter speichern Ziel
        chainer.serializers.save_npz(param_name, self.model) #Schreiben Sie trainierte Parameter im NPZ-Format
        print("___Successfully completed\n\n")

Legen Sie in "chainer.serializers.save_npz ()" den Parameter Sicherungsziel (param_name) und das Netzwerkmodell ( self.model) fest. Wenn angegeben, werden die Parameter im NPZ-Format gespeichert. Dieser Parameter wird verwendet, um das Gesicht tatsächlich zu erkennen.

Hauptfunktion

Die Hauptfunktion entfällt, da es keinen Platz gibt, um sie zu erklären.

Hauptfunktion


def main():

    #Befehlszeilenoptionen
    parser = arg.ArgumentParser(description='Face Recognition train Program(Chainer)')
    parser.add_argument('--data_dir', '-d', type=str, default=None,
                        help='Angeben des Ordnerpfads(Fehler, wenn nicht angegeben)')
    parser.add_argument('--out', '-o', type=str, 
                        default=os.path.dirname(os.path.abspath(__file__))+'/result'.replace('/', os.sep),
                        help='Geben Sie das Speicherziel der Parameter an(Standardwert./result)')
    parser.add_argument('--batch_size', '-b', type=int, default=32,
                        help='Angeben der Mini-Stapelgröße(Standardwert 32)')
    parser.add_argument('--epoch', '-e', type=int, default=15,
                        help='Angabe der Anzahl der Lernvorgänge(Standardwert 15)')
    parser.add_argument('--gpu', '-g', type=int, default=-1,
                        help='Angeben der GPU-ID(Negative Werte zeigen die CPU-Verarbeitung an,Standardwert-1)')
    args = parser.parse_args()

    #Ordner nicht angegeben->Ausnahme
    if args.data_dir == None:
        print("\nException: Folder not specified.\n")
        sys.exit()
    #Wenn Sie einen Ordner angeben, der nicht vorhanden ist->Ausnahme
    if os.path.exists(args.data_dir) != True:
        print("\nException: Folder {} is not found.\n".format(args.data_dir))
        sys.exit()

    #Informationsausgabe einstellen
    print("=== Setting information ===")
    print("# Images folder: {}".format(os.path.abspath(args.data_dir)))
    print("# Output folder: {}".format(args.out))
    print("# Minibatch-size: {}".format(args.batch_size))
    print("# Epoch: {}".format(args.epoch))
    print("===========================")

    #Datensatzerstellung
    train_set = create_dataset(args.data_dir)

    #Fang an zu lernen
    print("___Start training...")
    Trainer = trainer()
    Trainer.train(train_set, args.batch_size, args.epoch, args.gpu, args.out)
   
if __name__ == '__main__':
    main()

** Informationen zur GPU-Verarbeitung ** Ich habe die Umgebung so aufgebaut, dass sie von der GPU verarbeitet werden kann Die folgende Verarbeitung wird beschrieben. Es spielt keine Rolle, ob es da ist oder nicht, und es muss nicht von der GPU verarbeitet werden. Im Gegensatz zu Tensorflow hat Chainer jedoch eine lange Lernzeit. Wir empfehlen daher, wenn möglich mit GPU zu verarbeiten. .. (Abhängig von der Umgebung und dem zu lösenden Problem) Ich werde den Aufbau der GPU-Verarbeitungsumgebung weglassen.

        if gpu >= 0:
            chainer.cuda.get_device(gpu).use() #Geräteobjekt abrufen
            self.model.to_gpu()  #Kopieren Sie die Eingabedaten auf das angegebene Gerät

Hinweis

Im folgenden Prozess werden wir zählen, wie viele Trainingsdaten vorhanden sind. ** Ein weiteres Blatt kann hinzugefügt werden **. Dies liegt daran, dass es einen Miniaturbild-Cache namens Thumbs.db enthält. ~~ Es ist nervig, also ~~ Ich berücksichtige dies beim Zählen nicht. Es gibt jedoch kein Problem, da es so verarbeitet wird, dass es beim Erstellen des Datasets durchlaufen wird.

    for c in os.listdir(data_dir):
        d = os.path.join(data_dir, c)
        print("Number of image in a directory \"{}\": {}".format(c, len(os.listdir(d))))

abschließend

Ich habe dieses Mal zum ersten Mal bei Qiita gepostet, aber ich mache mir Sorgen, weil es viele unangenehme Punkte gibt ... Wie in der Übersicht erwähnt, kommentieren Sie bitte, wenn etwas damit nicht stimmt. korrigieren.

Das nächste Mal, weil es die Vorhersagephase ist, werde ich die Kamera verwenden, um das Gesicht zu erkennen ... Ich kann mein Gesicht nicht zeigen, daher plane ich, stattdessen das Gesichtsbild einer öffentlichen Person zu verwenden.

Zusätzlich zu Chainer können Sie mit Tensorflow (tf.keras) ein Gesichtserkennungsprogramm implementieren, versuchen, Filter und Feature-Maps zu visualisieren usw. Ich habe verschiedene Dinge ausprobiert, beispielsweise das Hyperparameter-Optimierungs-Framework "Optuna", also hoffe ich, dass ich in Zukunft etwas posten kann. (Obwohl es in Form eines Memorandums sein wird)

Recommended Posts

Versuchen wir nun die Gesichtserkennung mit Chainer (Lernphase)
Versuchen Sie die Gesichtserkennung mit Python
Versuchen Sie die Gesichtserkennung mit Python + OpenCV
Erste Anime-Gesichtserkennung mit Chainer
Versuchen Sie Common Representation Learning mit Chainer
Versuchen Sie es mit Chainer Deep Q Learning - Launch
[Python3] [Ubuntu16] [Docker] Versuchen Sie die Gesichtserkennung mit OpenFace
Gesichtserkennung mit Edison
Einfacher Gesichtserkennungsversuch mit Jetson Nano und Webkamera
Gesichtserkennung mit OpenCV von Python
Versuchen Sie, RBM mit Chainer zu implementieren.
Gesichtserkennung durch Amazon Rekognition
Versuchen Sie Deep Learning mit FPGA
Gesichtserkennung / Schneiden mit OpenCV
Versuchen Sie es mit Kaggle leicht maschinell
Lassen Sie uns word2vec mit Chainer verschieben und den Lernfortschritt sehen
Lernen stärken 13 Probieren Sie Mountain_car mit ChainerRL aus.
Versuchen Sie es mit TensorFlow Part 2
Versuchen Sie, Pferderennen mit Chainer vorherzusagen
[Chainer] Lernen von XOR mit mehrschichtigem Perzeptron
SVM versucht maschinelles Lernen mit Scikit-Learn
Stärkung des Lernens 8 Versuchen Sie, die Chainer-Benutzeroberfläche zu verwenden
Gesichtserkennung mit Kamera mit opencv3 + python2.7
Einführung in Deep Learning (2) - Versuchen Sie Ihre eigene nichtlineare Regression mit Chainer-
Ich habe versucht, das Gesicht mit OpenCV zu erkennen
Klassifizieren Sie Anime-Gesichter mit tiefem Lernen mit Chainer
Probieren Sie die Bitcoin-Preisprognose mit Deep Learning aus
Versuchen wir es mit gRPC mit Go und Docker
Gesichtserkennung von Anime-Charakteren mit Keras
Versuchen Sie mit Kipoi tiefes Erlernen der Genomik
[python, openCV] base64 Gesichtserkennung in Bildern
Serverlose Gesichtserkennungs-API mit Python
Stärkung des Lernens 11 Probieren Sie OpenAI Acrobot mit ChainerRL aus.
Kategorisieren Sie Gesichtsbilder von Anime-Charakteren mit Chainer
Versuchen Sie, Ihr Gesicht mit dem AB-Test zu montieren
Bilderkennung mit Caffe Model Chainer Yo!