DCGAN (Deep Convolutional GAN)
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.
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
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.
#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
#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
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.
Die spezifischen Schritte sind unten zusammengefasst.
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
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.
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
#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())
#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)
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
iterations = 20000
batch_size = 128
sample_interval = 1000
train(iterations, batch_size, sample_interval)
↓ Anfangsgeräusch ↓1000iterations ↓10000iterations ↓20000iterations
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.