Note from Instructor:
==============================================================
Dear All,
Take the TensorFlow code of GAN and implement it on the Fashion-MNIST dataset. Try to modify the architecture of the model (generator and discriminator) and hyperparameters to produce better (visually) outputs (images).
Note you can load the Fashion MNIST dataset using: tf.keras.datasets.fashion_mnist.load_data()
Your submission should contain some saved files of images generated by the GAN model.
Deadline: November 06, 2020 Submissions are to be made by replying to this email with files as attachments or as a GoogleDrive link.
Best wishes,
Dripta Mj
==============================================================
http://introtodeeplearning.com : LFL
https://www.tensorflow.org/tutorials/generative/dcgan : Code stolen from here
# import all required packages
import tensorflow as tf
import glob
import imageio
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
from tensorflow.keras import layers
import time
from IPython import display
(train_imgs, train_lab), (_, _) = tf.keras.datasets.fashion_mnist.load_data()
train_imgs = train_imgs.reshape(train_imgs.shape[0], 28, 28, 1).astype('float32')
train_imgs = (train_imgs - 127.5) / 127.5 # Normalize the images in between -1 and 1
BUFFER_SIZE = 60000
BATCH_SIZE = 8*8
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step
# Batch and Shuffle the data
train_set = tf.data.Dataset.from_tensor_slices(train_imgs).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
# Architecture for Generator
def generator_model():
model = tf.keras.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)))
assert model.output_shape == (None, 7, 7, 256) #None refers to the batch size
# Conv2DTranspose are used to upsample for generating an image from a seed which is random noise
model.add(layers.Conv2DTranspose(128, (5,5), strides=(1,1), padding='same', use_bias=False))
assert model.output_shape == (None, 7, 7, 128)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(64, (5,5), strides=(2,2), padding='same', use_bias=False))
assert model.output_shape == (None, 14, 14, 64)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(1, (5,5), strides=(2,2), padding='same', use_bias=False, activation='tanh'))
assert model.output_shape == (None, 28, 28, 1)
return model
generator = generator_model()
noise = tf.random.normal([1, 100])
generated_img = generator(noise, training=False)
plt.imshow(generated_img[0,:,:,0], cmap='gray')
<matplotlib.image.AxesImage at 0x7f1fe03654a8>
# Architecture for Discriminator Model
def discriminator_model():
model = tf.keras.Sequential()
model.add(layers.Conv2D(64, (5,5), strides=(2,2), padding='same', input_shape=[28,28,1]))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(128,(5,5), strides=(2,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 = discriminator_model()
decision_output = discriminator(generated_img)
print(decision_output)
tf.Tensor([[-0.00103022]], shape=(1, 1), dtype=float32)
# compute CrossEntropyLoss
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
# Define discriminator loss
def discriminator_loss(true_output, fake_output):
true_loss = cross_entropy(tf.ones_like(true_output), true_output)
fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
tot_loss = true_loss + fake_loss
return tot_loss
# Define Generator loss
def generator_loss(fake_output):
return cross_entropy(tf.ones_like(fake_output), fake_output)
# Defining separate optimizers for generator and discriminator
gen_optimizer = tf.keras.optimizers.Adam(1e-4)
dis_optimizer = tf.keras.optimizers.Adam(1e-4)
checkpoints_dir = './training_chpk'
checkpoint_prefix = os.path.join(checkpoints_dir, "ckpt")
checkpoint = tf.train.Checkpoint(gen_optimizer=gen_optimizer, dis_optimizer=dis_optimizer, generator=generator, discriminator=discriminator)
EPOCHS = 150
noise_dim = 100
num_ex_to_gen = 16*16
seed = tf.random.normal([num_ex_to_gen,noise_dim])
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, noise_dim])
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
generated_img = generator(noise, training=True)
true_output = discriminator(images, training=True)
fake_output = discriminator(generated_img, training=True)
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(true_output, fake_output)
grad_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
grad_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
gen_optimizer.apply_gradients(zip(grad_generator, generator.trainable_variables))
dis_optimizer.apply_gradients(zip(grad_discriminator, discriminator.trainable_variables))
def train(dataset, epochs):
for epoch in range(epochs):
start = time.time()
for img_batch in dataset:
train_step(img_batch)
#produce images for the GIF as we go
display.clear_output(wait=True)
generate_and_save_images(generator, epoch + 1, seed)
# Save the model every 12 EPOCHS
if (epoch + 1) % 12 == 0:
checkpoint.save(file_prefix = checkpoint_prefix)
print ('Time for epoch {} is {} sec'.format(epoch + 1, time.time()-start))
# Generator after final epoch
display.clear_output(wait=True)
generate_and_save_images(generator, epochs, seed)
def generate_and_save_images(model, epoch, test_input):
# Training set to false so that every layer runs in inferenc mode
predictions = model(test_input, training=False)
fig = plt.figure(figsize=(16,16))
print(predictions.shape)
for i in range(8*8):
plt.subplot(8, 8, i+1)
plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')
plt.axis('off')
plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
plt.show()
%%time
train(train_set, EPOCHS)
(256, 28, 28, 1)
CPU times: user 23min 58s, sys: 1min 18s, total: 25min 17s Wall time: 42min 46s
out_file = 'output.gif'
with imageio.get_writer(out_file, mode='I') as writer:
filenames = glob.glob('image*.png')
filenames = sorted(filenames)
last = -1
for i, filename in enumerate(filenames):
frame = 2*(i**0.5)
if round(frame) > round(last):
last = frame
else:
continue
image = imageio.imread(filename)
writer.append_data(image)
image = imageio.imread(filename)
writer.append_data(image)
import IPython
if IPython.version_info > (6,2,0,''):
display.Image(filename=out_file)
! mkdir files
! mv *.png files
! zip -r files.zip files
out_file = 'output_long_movie.gif'
with imageio.get_writer(out_file, mode='I') as writer:
filenames = glob.glob('image*.png')
filenames = sorted(filenames)
last = -1
for i, filename in enumerate(filenames):
frame = i
if round(frame) > round(last):
last = frame
else:
continue
image = imageio.imread(filename)
writer.append_data(image)
image = imageio.imread(filename)
writer.append_data(image)
import IPython
if IPython.version_info > (6,2,0,''):
display.Image(filename=out_file)