7. Explore generative adversal networks and its features
on simple dataset.
import tensorflow as tf
from tensorflow.keras import layers, Sequential
import numpy as np
import matplotlib.pyplot as plt
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = x_train.astype('float32') / 127.5 - 1 # Normalize
to [-1,1]
x_train = np.expand_dims(x_train, axis=-1)
BUFFER_SIZE = 60000
BATCH_SIZE = 256
train_dataset =
tf.data.Dataset.from_tensor_slices(x_train).shuffle(BUFFE
R_SIZE).batch(BATCH_SIZE)
def build_generator():
model = Sequential()
model.add(layers.Dense(7*7*256, use_bias=False,
input_shape=(100,)))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Reshape((7, 7, 256)))
model.add(layers.Conv2DTranspose(128, 5, strides=1,
padding='same', use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(64, 5, strides=2,
padding='same', use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(1, 5, strides=2,
padding='same', activation='tanh'))
return model
generator = build_generator()
def build_discriminator():
model = Sequential()
model.add(layers.Conv2D(64, 5, strides=2,
padding='same', input_shape=[28,28,1]))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(128, 5, strides=2,
padding='same'))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Flatten())
model.add(layers.Dense(1))
return model
discriminator = build_discriminator()
cross_entropy =
tf.keras.losses.BinaryCrossentropy(from_logits=True)
generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, 100])
with tf.GradientTape() as gen_tape, tf.GradientTape() as
disc_tape:
generated_images = generator(noise, training=True)
real_output = discriminator(images, training=True)
fake_output = discriminator(generated_images,
training=True)
gen_loss = cross_entropy(tf.ones_like(fake_output),
fake_output)
disc_loss = cross_entropy(tf.ones_like(real_output),
real_output) + \
cross_entropy(tf.zeros_like(fake_output),
fake_output)
gradients_of_generator = gen_tape.gradient(gen_loss,
generator.trainable_variables)
gradients_of_discriminator =
disc_tape.gradient(disc_loss,
discriminator.trainable_variables)
generator_optimizer.apply_gradients(zip(gradients_of_gen
erator, generator.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_
discriminator, discriminator.trainable_variables))
return gen_loss, disc_loss
EPOCHS = 5
for epoch in range(EPOCHS):
for batch in train_dataset:
g_loss, d_loss = train_step(batch)
print(f"Epoch {epoch+1}, Gen Loss: {g_loss:.4f}, Disc
Loss: {d_loss:.4f}")
noise = tf.random.normal([16, 100])
generated_images = generator(noise, training=False)
plt.figure(figsize=(4,4))
for i in range(16):
plt.subplot(4,4,i+1)
plt.imshow((generated_images[i, :, :, 0] + 1)/2,
cmap='gray')
plt.axis('off')
plt.show()
