[PYTHON] DCGAN

DCGAN (Deep Convolutional GAN)

Was ist DCGAN?

Vorheriger Artikel Sowohl für den einfachen GAN-Generator als auch für den Klassifikator wird anstelle eines einfachen zweischichtigen Feed-Forward ein Faltungs-Neuron verwendet GAN, das ein Netzwerk verwendet, wird als DCGAN bezeichnet.

Chargennormalisierung

Dieses Mal verwendet DCGAN die Chargennormalisierung. Für eine detaillierte Erklärung ist der [Artikel] dieser Person (https://qiita.com/t-tkd3a/items/14950dbf55f7a3095600) sehr einfach zu verstehen.

Um nur kurz die Vorteile der Einführung der Chargennormalisierung vorzustellen

  1. Es ist möglich, das Lernen schnell voranzutreiben
  2. Weniger abhängig vom Anfangswert
  3. Überlernen kann unterdrückt werden

Und so weiter. In dieser Implementierung kann die Funktion keras.layers.BatchNormalization den Mini-Batch hinter den Kulissen gut berechnen und aktualisieren. Lassen Sie uns DCGAN tatsächlich implementieren! Der allgemeine Ablauf ist fast der gleiche wie im vorherigen Artikel.

Es ist Zeit zu implementieren! !! !!

1. Verschiedene Importe

#Zunächst importieren

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np

from keras.datasets import mnist
from keras.layers import Activation, BatchNormalization, Dense, Dropout, Flatten, Reshape
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.models import Sequential
from keras.optimizers import Adam

2. Einstellen der Eingabedimension des Modells

#Festlegen der Eingabedimension des Modells

img_rows = 28
img_cols = 28
channels = 1

img_shape = (img_rows, img_cols, channels)

#Die Dimension des Rauschvektors, der als Eingabe für den Generator verwendet wird
z_dim = 100

3. Generatorimplementierung

Da der Generator aus dem Rauschvektor z ein Bild erzeugt, verwenden wir die Translokationsfaltung. Mit anderen Worten, in der folgenden Abbildung wird das Bild ganz links aus dem Z-Vektor ganz rechts erzeugt.

スクリーンショット 2020-06-13 15.16.22.png

Die spezifischen Schritte sind unten zusammengefasst.

  1. Konvertieren Sie in einen 7x7x256-Tensor, indem Sie einen Rauschvektor erstellen und ihn durch die vollständig verbundene Schicht leiten
  2. Konvertieren Sie 7x7x256 in 14x14x128 durch Translokationsfaltungsschicht
  3. Führen Sie eine Chargennormalisierung durch und wenden Sie Leaky ReLU an
  4. Konvertieren Sie 14x14x128 in 14x14x64 mit der Translokationsfaltungsschicht. Höhe und Breite ändern sich in diesem Schritt nicht
  5. Führen Sie eine Chargennormalisierung durch und wenden Sie Leaky ReLU an
  6. Konvertieren Sie 14x14x64 in die Ausgabebildgröße 28x28x1 mit Translokationsfaltungsschicht
  7. Wenden Sie die Tanh-Funktion an

In Bezug auf die Parameter von Conv2D Transpose habe ich auf [diesen Artikel] verwiesen (https://qiita.com/takurooo/items/9a9f387390f5fcf5a516).

#Generator

def build_generator(z_dim):
  model = Sequential()

  model.add(Dense(256*7*7, input_dim = z_dim))
  model.add(Reshape((7, 7, 256)))

  model.add(Conv2DTranspose(128, kernel_size=3, strides=2,padding='same'))
  model.add(BatchNormalization())
  model.add(LeakyReLU(alpha=0.01))

  model.add(Conv2DTranspose(1, kernel_size=3, strides=2, padding="same"))
  model.add(Activation('tanh'))

  return model

4. Implementierung des Klassifikators

Der Klassifikator übernimmt die bekannte Netzwerkstruktur von CNN. Um kurz zu erklären, was Sie tun, indem Sie Bilddaten eingeben und eine Faltung durchführen, wird schließlich die Wahrscheinlichkeit berechnet, dass das Bild echt ist. Bitte überprüfen Sie den Code unten für Details.

Identifikator

def build_discriminator(img_shape):

  model = Sequential()

  model.add(Conv2D(32, kernel_size=3, strides=2, input_shape=img_shape, padding='same'))
  model.add(LeakyReLU(alpha=0.01))

  model.add(Conv2D(64, kernel_size=3, strides=2, padding="same"))
  model.add(BatchNormalization())
  model.add(LeakyReLU(alpha=0.01))

  model.add(Conv2D(128, kernel_size=3, strides=2, padding="same"))
  model.add(BatchNormalization())
  model.add(BatchNormalization())
  model.add(LeakyReLU(alpha=0.01))

  model.add(Flatten())
  model.add(Dense(1, activation="sigmoid"))

  return model

5. DCGAN kompilieren

#DCGAN-Zusammenstellung
def build_gan(generator, discriminator):

  model = Sequential()

  model.add(generator)
  model.add(discriminator)

  return model

discriminator = build_discriminator(img_shape)
discriminator.compile(loss="binary_crossentropy", optimizer=Adam(), metrics=["accuracy"])

generator = build_generator(z_dim)
discriminator.trainable = False

gan = build_gan(generator, discriminator)
gan.compile(loss="binary_crossentropy", optimizer=Adam())

6. Lerneinstellungen

#Training

losses = []
accuracies = []
iteration_checkpoints = []

def train(iterations, batch_size, sample_interval):
  (X_train, _),(_, _) = mnist.load_data()

  X_train = X_train / 127.5 -1.0
  X_train = np.expand_dims(X_train, 3)

  real = np.ones((batch_size, 1))
  fake = np.zeros((batch_size, 1))

  for iteration in range(iterations):

    idx = np.random.randint(0, X_train.shape[0], batch_size)
    imgs = X_train[idx]

    z = np.random.normal(0, 1, (batch_size, 100))
    gen_imgs = generator.predict(z)

    d_loss_real = discriminator.train_on_batch(imgs, real)
    d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)
    d_loss,  accuracy = 0.5 * np.add(d_loss_real, d_loss_fake)

    z = np.random.normal(0, 1, (batch_size, 100))
    gen_imgs = generator.predict(z)

    g_loss = gan.train_on_batch(z, real)
    if iteration == 0:
      sample_images(generator)

    if ((iteration + 1) % sample_interval == 0):

      losses.append((d_loss, g_loss))
      accuracies.append(100 * accuracy)
      iteration_checkpoints.append(iteration+1)

      print("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" %
                  (iteration + 1, d_loss, 100.0 * accuracy, g_loss))
      sample_images(generator)

7. Bildanzeige

def sample_images(generator, image_grid_rows=4, image_grid_columns=4):

  z = np.random.normal(0, 1, (image_grid_rows * image_grid_columns, z_dim))
  gen_imgs = generator.predict(z)
  gen_imgs = 0.5 * gen_imgs + 0.5

  fig, axs = plt.subplots(image_grid_rows,
                           image_grid_columns,
                           figsize=(4,4),
                           sharey=True,
                           sharex=True
                           )
  cnt = 0
  for i in range(image_grid_rows):
    for j in range(image_grid_columns):
      axs[i, j].imshow(gen_imgs[cnt, :, :, 0], cmap='gray')
      axs[i, j].axis('off')
      cnt += 1

8. Lass uns lernen!

iterations = 20000
batch_size = 128
sample_interval = 1000
train(iterations, batch_size, sample_interval)

Ergebnis

↓ Anfangsgeräusch スクリーンショット 2020-06-13 19.26.47.png ↓1000iterations スクリーンショット 2020-06-13 19.26.57.png ↓10000iterations スクリーンショット 2020-06-13 19.27.29.png ↓20000iterations スクリーンショット 2020-06-13 19.27.43.png

Wie wäre es, wenn ich ein Bild auf einer Ebene erzeugen könnte, die nicht von dem echten handgeschriebenen Text aus dem Mnist des Datensatzes zu unterscheiden ist. Auch in der einfachen GAN von Vorheriger war Rauschen in Pixeleinheiten im Bild enthalten, diesmal jedoch bei Verwendung von DCGAN zwischen Pixeln. Beziehungen können eingebettet werden und ein schönes Bild ohne Rauschen wird erzeugt.

Recommended Posts

DCGAN
Schreiben Sie DCGAN mit Keras
GAN: DCGAN Part2-Training DCGAN-Modell
DCGAN mit TF Learn