[PYTHON] Implementierungsbeispiel für das Hostile Generation Network (GAN) von Keras [Für Anfänger]

Was ich in diesem Artikel gemacht habe

** - Minimale Bilderzeugung durch GAN

Einführung

Hostile Generation Network oder GAN. Ich höre oft, dass es sehr beliebt ist, aber wenn Sie tatsächlich versuchen, es selbst zu implementieren, ist es eine ziemliche Schwelle.

Es ist eine Technologie, die für mich wichtig zu sein scheint, also habe ich sie in Ruhe gelassen, indem ich sie nur von außen betrachtet habe. Überraschenderweise gibt es so viele Leute.

** Dieses Mal werde ich ein Beispiel für die Implementierung eines solchen GAN unter Verwendung von Mnist-Daten vorstellen. ** ** ** Daten und Code ["Unüberwachtes Lernen mit Python"](URL https://www.amazon.co.jp/Python%E3%81%A7%E3%81%AF%E3%81%98%E3%82 % 81% E3% 82% 8B% E6% 95% 99% E5% B8% AB% E3% 81% AA% E3% 81% 97% E5% AD% A6% E7% BF% 92-% E2% 80% 95% E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92% E3% 81% AE% E5% 8F% AF% E8% 83% BD% E6% 80% A7% E3% 82% 92% E5% BA% 83% E3% 81% 92% E3% 82% 8B% E3% 83% A9% E3% 83% 99% E3% 83% AB% E3% 81% AA% E3% 81% 97% E3% 83% 87% E3% 83% BC% E3% 82% BF% E3% 81% AE% E5% 88% A9% E7% 94% A8-Ankur-Patel / dp / 4873119103) Ich darf.

Das Buch, auf das ich mich bezog, wurde in Objektorientierung geschrieben, es war also ein wenig hoch, aber es war eine großartige Lernerfahrung.

Ebenso hoffe ich, dass es für Anfänger hilfreich sein wird.

Hier sind die Ergebnisse, die ich zuerst erhalten habe. Weil es das Aussehen beeinflusst.

** Echt ** image.png

** Generieren ** mnist_14000.png

** Ich finde, dass die erzeugten Bilder ekelhaft ähnlich sind ... ** Wenn Sie länger lernen, können Sie möglicherweise bessere Dinge tun.

Was ist ein Hostile Generation Network (GAN)?

Hier ist eine kurze Übersicht. Weitere Informationen finden Sie in diesem Artikel. GAN: Was ist ein feindliches Generationsnetzwerk? - Bilderzeugung durch "Lernen ohne Lehrer" https://www.imagazine.co.jp/gan%EF%BC%9A%E6%95%B5%E5%AF%BE%E7%9A%84%E7%94%9F%E6%88%90%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B%E3%80%80%EF%BD%9E%E3%80%8C%E6%95%99%E5%B8%AB/

** Mit GAN können Sie einen Datensatz trainieren, um dieselben und ähnliche Daten zu erstellen. ** ** ** Im Beispiel des Referenzartikels wird GAN verwendet, um ein Bild eines Schlafzimmers zu generieren, das tatsächlich nicht vorhanden ist. Es ist schwer zu sagen, maschinelles Lernen ist beängstigend.

Da dieser Artikel mnist verwendet, werden handgeschriebene Zeichen generiert. Wie erzeugt man diese handschriftliche Figur?

** Bei GAN gibt es zwei Modelle, eines, das Daten generiert, und das andere, das Daten identifiziert. In dem Modell, das Daten generiert, werden Daten erstellt, die wie handgeschriebene Zeichen aussehen. Anschließend werden die erstellten Daten als Identifikationsmodell verwendet, um festzustellen, ob sie gefälscht oder echt sind. Basierend auf dem Ergebnis werden wir dann das generierte Modell trainieren und dann ein Bild erstellen, das näher an der Realität liegt. ** ** **

Einfach gesagt, es ist nur dieses Modell. Die Frage bleibt nur, wie man die Daten trainiert und wie man die Daten trainiert. Ich denke.

Daten lernen

In diesem Modell wird das Datentraining wie folgt durchgeführt.

** - Generieren Sie ein Bild (1 * 28 * 28) aus Rauschen (100 * 1 * 1) mit dem Generierungsmodell

Wir werden dieses Modell tatsächlich implementieren.

Bibliothek importieren

Es ist nur ein Nachschlagewerk, aber ich habe es ein wenig verbessert, damit es in Google Colab verwendet werden kann.

python



'''Main'''
import numpy as np
import pandas as pd
import os, time, re
import pickle, gzip, datetime

'''Data Viz'''
import matplotlib.pyplot as plt
import seaborn as sns
color = sns.color_palette()
import matplotlib as mpl
from mpl_toolkits.axes_grid1 import Grid

%matplotlib inline

'''Data Prep and Model Evaluation'''
from sklearn import preprocessing as pp
from sklearn.model_selection import train_test_split 
from sklearn.model_selection import StratifiedKFold 
from sklearn.metrics import log_loss, accuracy_score
from sklearn.metrics import precision_recall_curve, average_precision_score
from sklearn.metrics import roc_curve, auc, roc_auc_score, mean_squared_error
from keras.utils import to_categorical

'''Algos'''
import lightgbm as lgb

'''TensorFlow and Keras'''
import tensorflow as tf
import keras
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Activation, Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras.layers import LeakyReLU, Reshape, UpSampling2D, Conv2DTranspose
from keras.layers import BatchNormalization, Input, Lambda
from keras.layers import Embedding, Flatten, dot
from keras import regularizers
from keras.losses import mse, binary_crossentropy
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.optimizers import Adam, RMSprop

from keras.datasets import mnist

sns.set("talk")

Daten gelesen

Es liest Daten. Verwenden Sie die wenigsten Daten. Es ist für den Einsatz in Laboratorien vorgesehen. Da wir nur x_train verwenden, normalisieren wir nur reshpae und Werte von 0 bis 1 auf x_train.

python



#Daten unterteilt in Trainingsdaten und Testdaten
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape((60000, 28, 28, 1))
#Setzen Sie den Pixelwert auf 0~Normalisieren Sie zwischen 1
x_train= x_train / 255.0

DCGAN-Klassendesign

Super wichtiger DCGAN-Code. Es wird in einer Klasse definiert, die das Generierungsmodell und das Identifikationsmodell zusammenfasst. Um die Funktion jeder Funktion kurz zu beschreiben generator

discriminator

discriminator_model --Kompilieren und modellieren Sie ein neuronales Netzwerk zur Identifizierung

adversarial?model

python


#DCGAN-Klasse
class DCGAN(object):
  #Initialisieren
    def __init__(self, img_rows=28, img_cols=28, channel=1):

        self.img_rows = img_rows
        self.img_cols = img_cols
        self.channel = channel
        self.D = None   # discriminator
        self.G = None   # generator
        self.AM = None  # adversarial model
        self.DM = None  # discriminator model
    
    #Generationsnetzwerk
    #100*1*Die Matrix von 1 entspricht dem Bild des Datensatzes 1*28*28
    def generator(self, depth=256, dim=7, dropout=0.3, momentum=0.8, \
                  window=5, input_dim=100, output_depth=1):
        if self.G:
            return self.G
        self.G = Sequential()

        #100*1*1 → 256*7*7
        self.G.add(Dense(dim*dim*depth, input_dim=input_dim))
        self.G.add(BatchNormalization(momentum=momentum))
        self.G.add(Activation('relu'))
        self.G.add(Reshape((dim, dim, depth)))
        self.G.add(Dropout(dropout))
        
        #256*7*7 → 128*14*14
        self.G.add(UpSampling2D())
        self.G.add(Conv2DTranspose(int(depth/2), window, padding='same'))
        self.G.add(BatchNormalization(momentum=momentum))
        self.G.add(Activation('relu'))

        #128*14*14 → 64*28*28
        self.G.add(UpSampling2D())
        self.G.add(Conv2DTranspose(int(depth/4), window, padding='same'))
        self.G.add(BatchNormalization(momentum=momentum))
        self.G.add(Activation('relu'))

        #64*28*28→32*28*28
        self.G.add(Conv2DTranspose(int(depth/8), window, padding='same'))
        self.G.add(BatchNormalization(momentum=momentum))
        self.G.add(Activation('relu'))

        #1*28*28
        self.G.add(Conv2DTranspose(output_depth, window, padding='same'))
        #Stellen Sie jedes Pixel auf einen Wert zwischen 0 und 1 ein
        self.G.add(Activation('sigmoid')) 
        self.G.summary()
        return self.G


    #Identifikationsnetzwerk
    #28*28*Unterscheiden Sie, ob das Bild von 1 echt ist
    def discriminator(self, depth=64, dropout=0.3, alpha=0.3):
        if self.D:
            return self.D

        self.D = Sequential()
        input_shape = (self.img_rows, self.img_cols, self.channel)

      #28*28*1 → 14*14*64
        self.D.add(Conv2D(depth*1, 5, strides=2, input_shape=input_shape,padding='same'))
        self.D.add(LeakyReLU(alpha=alpha))
        self.D.add(Dropout(dropout))

      #14*14*64 → 7*7*128
        self.D.add(Conv2D(depth*2, 5, strides=2, padding='same'))
        self.D.add(LeakyReLU(alpha=alpha))
        self.D.add(Dropout(dropout))

      #7*7*128 → 4*4*256
        self.D.add(Conv2D(depth*4, 5, strides=2, padding='same'))
        self.D.add(LeakyReLU(alpha=alpha))
        self.D.add(Dropout(dropout))

        #4*4*512 → 4*4*512 ####Überprüfen Sie jedoch, ob es übereinstimmt###
        self.D.add(Conv2D(depth*8, 5, strides=1, padding='same'))
        self.D.add(LeakyReLU(alpha=alpha))
        self.D.add(Dropout(dropout))

        #Abflachen und nach Sigmoid klassifizieren
        self.D.add(Flatten())
        self.D.add(Dense(1))
        self.D.add(Activation('sigmoid'))

        self.D.summary()
        return self.D

    #Diskriminierungsmodell
    def discriminator_model(self):
        if self.DM:
            return self.DM
        optimizer = RMSprop(lr=0.0002, decay=6e-8)
        self.DM = Sequential()
        self.DM.add(self.discriminator())
        self.DM.compile(loss='binary_crossentropy', \
                        optimizer=optimizer, metrics=['accuracy'])
        return self.DM

    #Generationsmodell
    def adversarial_model(self):
        if self.AM:
            return self.AM
        optimizer = RMSprop(lr=0.0001, decay=3e-8)
        self.AM = Sequential()
        self.AM.add(self.generator())
        self.AM.add(self.discriminator())
        self.AM.compile(loss='binary_crossentropy', \
                        optimizer=optimizer, metrics=['accuracy'])
        return self.AM

DCGAN-Klassendesign für Mnist

Als nächstes werden wir diese Funktionen verwenden, um die kleinsten Daten tatsächlich zu trainieren, um ein Bild zu erzeugen. Trainieren Sie das Bild mit der Zugfunktion und speichern Sie das Bild mit plot_images.

Die Zugfunktion wird im folgenden Ablauf ausgeführt.

** - Generieren Sie Trainingsdaten aus Lärm

python


#Klasse, die DCGAN auf MNIST-Daten anwendet
class MNIST_DCGAN(object):
    #Initialisieren
    def __init__(self, x_train):
        self.img_rows = 28
        self.img_cols = 28
        self.channel = 1

        self.x_train = x_train

        #Identifizierung von DCGAN, Definition des Modells der feindlichen Erzeugung
        self.DCGAN = DCGAN()
        self.discriminator =  self.DCGAN.discriminator_model()
        self.adversarial = self.DCGAN.adversarial_model()
        self.generator = self.DCGAN.generator()

    #Trainingsfunktion
    #train_on_Batch lernt für jeden Batch. Ausgabe ist Verlust und gem
    def train(self, train_steps=2000, batch_size=256, save_interval=0):
        noise_input = None

        if save_interval>0:
            noise_input = np.random.uniform(-1.0, 1.0, size=[16, 100])

        for i in range(train_steps):
            #Batch-Trainingsdaten_Nur Größe nach dem Zufallsprinzip extrahieren
            images_train = self.x_train[np.random.randint(0,self.x_train.shape[0], size=batch_size), :, :, :] 
            
            # 100*1*Erstellen Sie ein Rauschen von 1 nach Stapelgröße und machen Sie es zu einem gefälschten Bild
            noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100])
            
            #Trainiere das generierte Bild
            images_fake = self.generator.predict(noise)
            x = np.concatenate((images_train, images_fake))
            #Setzen Sie die Trainingsdaten auf 1 und die generierten Daten auf 0
            y = np.ones([2*batch_size, 1])
            y[batch_size:, :] = 0
            
            #Trainieren Sie das Diskriminanzmodell
            d_loss = self.discriminator.train_on_batch(x, y)

            y = np.ones([batch_size, 1])
            noise = np.random.uniform(-1.0, 1.0, size=[batch_size, 100])

            #Generieren&Trainieren Sie das Diskriminanzmodell
            #Das Training des Generationsmodells erfolgt nur hier
            a_loss = self.adversarial.train_on_batch(noise, y)

            #Verlust und Genauigkeit der Trainingsdaten und des generierten Modells
            #D Verlust ist der Verlust und die Übereinstimmung des erzeugten Bildes und des tatsächlichen Bildes
            #Ein Verlust ist Verlust und acc, wenn das von einem Gegner erzeugte Bild 1 ist.
            log_mesg = "%d: [D loss: %f, acc: %f]" % (i, d_loss[0], d_loss[1])
            log_mesg = "%s  [A loss: %f, acc: %f]" % (log_mesg, a_loss[0], a_loss[1])
            print(log_mesg)

            #save_Daten in Intervallen speichern
            if save_interval>0:
                if (i+1)%save_interval==0:
                    self.plot_images(save2file=True, \
                        samples=noise_input.shape[0],\
                        noise=noise_input, step=(i+1))

    #Plotten Sie die Trainingsergebnisse
    def plot_images(self, save2file=False, fake=True, samples=16, \
                    noise=None, step=0):
        current_path = os.getcwd()
        file = os.path.sep.join(["","data", 'images', 'chapter12', 'synthetic_mnist', ''])
        filename = 'mnist.png'
        if fake:
            if noise is None:
                noise = np.random.uniform(-1.0, 1.0, size=[samples, 100])
            else:
                filename = "mnist_%d.png " % step
            images = self.generator.predict(noise)
        else:
            i = np.random.randint(0, self.x_train.shape[0], samples)
            images = self.x_train[i, :, :, :]

        plt.figure(figsize=(10,10))
        for i in range(images.shape[0]):
            plt.subplot(4, 4, i+1)
            image = images[i, :, :, :]
            image = np.reshape(image, [self.img_rows, self.img_cols])
            plt.imshow(image, cmap='gray')
            plt.axis('off')
        plt.tight_layout()
        if save2file:
            plt.savefig(current_path+file+filename)
            plt.close('all')
        else:
            plt.show()

Am Ende

GAN ist unglaublich. Ich fühle mich sogar unwohl, wenn so etwas wie handgeschriebene Zeichen erzeugt werden.

Es scheint, dass es zur Erkennung von Anomalien usw. am tatsächlichen Standort verwendet werden kann.

In der Zusammenfassung der Nachschlagewerke stand jedoch die Aussage ** "Bitte seien Sie bereit, sich bei der Verwendung von GAN viel Mühe zu geben" **. Es gab keinen detaillierten Grund dafür ...

Wie schwer hast du, GAN.

Bis zum Ende Danke fürs Lesen.

Recommended Posts

Implementierungsbeispiel für das Hostile Generation Network (GAN) von Keras [Für Anfänger]
Abnormalitätserkennung durch Auto-Encoder mit Keras [Implementierungsbeispiel für Anfänger]
Implementierungsbeispiel des LINE BOT-Servers für den tatsächlichen Betrieb
[Linux] Grundlagen der Berechtigungseinstellung von chmod für Anfänger
Speichern Sie die Ausgabe der bedingten GAN für jede Klasse ~ Mit der cGAN-Implementierung von PyTorch ~
[Für Anfänger] Grundlagen von Python erklärt durch Java Gold Teil 2
Speichern Sie die Ausgabe von GAN nacheinander ~ Mit der Implementierung von GAN durch PyTorch ~
■ Kaggle-Übung für Anfänger - Einführung von Python - von Google Colaboratory
[Für Anfänger] Grundlagen von Python erklärt durch Java Gold Teil 1
Übersicht über Docker (für Anfänger)
Implementierung von Scale-Space für SIFT
Zusammenfassung der grundlegenden Implementierung von PyTorch
Implementierung eines zweischichtigen neuronalen Netzwerks 2
[Muss für Anfänger] Grundlagen von Linux
Beispiel für das Umschreiben von Code durch ast.NodeTransformer
Ableitung der multivariaten t-Verteilung und Implementierung der Zufallszahlengenerierung durch Python
[Beispiel für eine Python-Verbesserung] Was ist die empfohlene Lernseite für Python-Anfänger?
Implementieren Sie ein Modell mit Status und Verhalten (3) - Beispiel für die Implementierung durch den Dekorateur