DCGANS for CIFAR-10 Dataset

Introduction

  1. Vanilla GANs: These are the simplest and most basic types of GANs. They consist of a generator and a discriminator, as described above.
  2. Conditional GANs: These GANs are able to generate synthetic data that is conditioned on some additional input. For example, a conditional GAN could be trained to generate images of a specific type of object (e.g. cats) when given a label indicating the desired object type as input.
  3. Deep Convolutional GANs (DCGANs): These GANs use deep convolutional neural networks as the generator and discriminator, which makes them well-suited for generating images.
  4. InfoGANs: These GANs are designed to disentangle the latent factors of variation in the training data and allow control over the generated data by manipulating these factors.
  5. Wasserstein GANs (WGANs): These GANs use the Wasserstein distance as a measure of the difference between the real data distribution and the synthetic data distribution, rather than the traditional GAN objective of minimizing the cross-entropy loss.
  6. CycleGANs: These GANs are used for image-to-image translation tasks, such as translating photos of horses into photos of zebras.
  7. StyleGANs: These GANs are able to generate highly realistic images, and are particularly well-suited for tasks such as generating synthetic faces

Dataset Introduction

  • Aeroplane
  • Automobile
  • Bird
  • Cat
  • Deer
  • Dog
  • Frog
  • Horse
  • Ship
  • Truck
# example of loading the cifar10 dataset
from keras.datasets.cifar10 import load_data
# load the images into memory
(trainX, trainy), (testX, testy) = load_data()

fig, ax = plt.subplots(ncols = 5,nrows = 5,figsize=(10,10))
for i in range(5):
for j in range(5):
ax[i][j].imshow(trainX[(i+1)*(j+1)-1])
CIFAR-10 Dataset

Preprocessing

  1. Feature Scaling: Feature Scaling is an important step of data preprocessing, If feature scaling is not performed, a machine learning algorithm would consider larger values to be higher and smaller values to be lower, regardless of the unit of measurement. The scaler used here is the Traditional MinMax Scaler. Minmax scaler Transform features by scaling each feature to a given range[-1, 1]
def load_real_samples():
X = trainX.astype('float32')
# Scale from [0, 255] to [-1, 1]
X = (X - 127.5)/127.5
return X

Preparing data for the Discriminator Model

  1. Generate Real Samples: Before building the discriminator model it is important to generate real & fake samples and label them accordingly. The Discriminator model would then be trained on this data so that it learns beforehand which is a real sample & which one is fake.
def generate_real_samples(dataset, n_samples):
ix = randint(0, dataset.shape[0], n_samples)
X = dataset[ix]
y = ones((n_samples, 1))
return X, y
def generate_fake_samples(n_samples):
# Generate uniform samples in [0, 1]
X = rand(32*32* 3 * n_samples)
# scale it to [-1, 1]
X = -1 + X + 2
# reshape into batch of color images
X= X.reshape((n_samples, 32,32,3))
y = zeros((n_samples, 1))
return X, y

Building & Training the Discriminator Model

def define_discriminator_model(in_shape = (32,32,3)):
model = Sequential()
model.add(Conv2D(64, (3,3),strides = (2,2),padding='same', input_shape =in_shape))
model.add(LeakyReLU(0.2))

model.add(Conv2D(128, (3,3),strides = (2,2),padding = 'same'))
model.add(LeakyReLU(0.2))

model.add(Conv2D(128, (3,3), strides = (2,2), padding = 'same'))
model.add(LeakyReLU(0.2))

# downsample
model.add(Conv2D(256, (3,3), strides=(2,2), padding='same'))
model.add(LeakyReLU(0.2))

# classifier
model.add(Flatten())
model.add(Dropout(0.4))
model.add(Dense(1, activation='sigmoid'))

opt = Adam(lr=0.0002, beta_1=0.5)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
return model

model = define_discriminator_model()
model.summary()
Discriminator Summary
def train_discriminator_model(model, dataset, n_iter = 20, n_batch = 128):
half_batch = int(n_batch/2)
for i in range(n_iter):
X_real, y_real = generate_real_samples(dataset, half_batch)
_,real_acc = model.train_on_batch(X_real, y_real)

X_fake, y_fake = generate_fake_samples(half_batch)
_,fake_acc = model.train_on_batch(X_fake, y_fake)

print("Real Accuracy ",(real_acc*100),"Fake Accuracy",(fake_acc*100))

# define the discriminator model
model = define_discriminator_model()
# load image data
dataset = load_real_samples()
# fit the model
train_discriminator_model(model, dataset)

Building & Testing Generator Model

def define_generator_model(latent_dim):
model = Sequential()
# foundation for 4x4 image
n_nodes = 256 * 4 * 4
model.add(Dense(n_nodes, input_dim=latent_dim))
model.add(LeakyReLU(alpha=0.2))
model.add(Reshape((4, 4, 256)))
# upsample to 8x8
model.add(Conv2DTranspose(128, (4,4), strides=(2,2), padding='same'))
model.add(LeakyReLU(alpha=0.2))
# upsample to 16x16
model.add(Conv2DTranspose(128, (4,4), strides=(2,2), padding='same'))
model.add(LeakyReLU(alpha=0.2))
# upsample to 32x32
model.add(Conv2DTranspose(128, (4,4), strides=(2,2), padding='same'))
model.add(LeakyReLU(alpha=0.2))
# output layer
model.add(Conv2D(3, (3,3), activation='tanh', padding='same'))
return model
# define the size of the latent space
latent_dim = 100
# define the generator model
model = define_generator(latent_dim)
# summarize the model
model.summary()
Generator Model
def generate_fake_samples(model, latent_dim, n_samples):
x_input = generate_latent_points(latent_dim, n_samples)
X = model.predict(x_input)
y = zeros((n_samples, 1))

return X, y

latent_dim = 100
n_samples = 50

model = define_generator_model(latent_dim)
X,_ = generate_fake_samples(model, latent_dim, n_samples)

# Rescale from [-1, 1] to [0, 1]
X = (X+1)/2.0

fig, ax = plt.subplots(ncols = 3, nrows = 3, figsize=(10,10))
for i in range(3):
for j in range(3):
ax[i][j].imshow(X[(i+1)*(j+1)-1])
Generated Images

Building & Training the GAN Model

def define_gan(g_model, d_model):
d_model.trainable = False
model = Sequential()
model.add(g_model)
model.add(d_model)
opt = Adam(lr=0.0002, beta_1=0.5)
model.compile(loss='binary_crossentropy', optimizer=opt)
return model
# size of the latent space
latent_dim = 100
# create the discriminator
d_model = define_discriminator_model()
# create the generator
g_model = define_generator_model(latent_dim)
# create the gan
gan_model = define_gan(g_model, d_model)
# summarize gan model
gan_model.summary()
def train(g_model, d_model, gan_model, dataset, latent_dim, n_epochs=200, n_batch=128):
bat_per_epo = int(dataset.shape[0] / n_batch)
half_batch = int(n_batch / 2)
# manually enumerate epochs
for i in range(n_epochs):
# enumerate batches over the training set
for j in range(bat_per_epo):
# get randomly selected ✬real✬ samples
X_real, y_real = generate_real_samples(dataset, half_batch)
# update discriminator model weights
d_loss1, _ = d_model.train_on_batch(X_real, y_real)
# generate ✬fake✬ examples
X_fake, y_fake = generate_fake_samples(g_model, latent_dim, half_batch)
# update discriminator model weights
d_loss2, _ = d_model.train_on_batch(X_fake, y_fake)
# prepare points in latent space as input for the generator
X_gan = generate_latent_points(latent_dim, n_batch)
# create inverted labels for the fake samples
y_gan = ones((n_batch, 1))
# update the generator via the discriminator✬s error
g_loss = gan_model.train_on_batch(X_gan, y_gan)
# summarize loss on this batch
print('>%d, %d/%d, d1=%.3f, d2=%.3f g=%.3f' %
(i+1, j+1, bat_per_epo, d_loss1, d_loss2, g_loss))
if (i+1) % 10 == 0:
summarize_performance(i, g_model, d_model, dataset, latent_dim)
# size of the latent space
latent_dim = 100
# create the discriminator
d_model = define_discriminator_model()
# create the generator
g_model = define_generator_model(latent_dim)
# create the gan
gan_model = define_gan(g_model, d_model)
# load image data
dataset = load_real_samples()
# train model
train(g_model, d_model, gan_model, dataset, latent_dim)
def generate_latent_points(latent_dim, n_samples):
# generate points in the latent space
x_input = randn(latent_dim * n_samples)
# reshape into a batch of inputs for the network
x_input = x_input.reshape(n_samples, latent_dim)
return x_input

# create and save a plot of generated images
def save_plot(examples, n):
# plot images
fig, ax = plt.subplots(ncols = 5, nrows = 5, figsize = (20,20))
for i in range(5):
for j in range(5):
ax[i][j].imshow(examples[(i+1)*(j+1)-1, :, :])
# plot raw pixel data
# load model
model = load_model('generator_model_200.h5')
# generate images
latent_points = generate_latent_points(100, 100)
# generate images
X = model.predict(latent_points)
# scale from [-1,1] to [0,1]
X = (X + 1) / 2.0
# plot the result
save_plot(X, 10)
Results generated by the Generator

Resources

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store