GANTF

artificial-intelligence10-GANsrnnganmicrosoft-for-beginnerslessonsAImicrosoft-AI-For-Beginnersmachine-learningdeep-learning4-ComputerVisioncomputer-visioncnnNLP

Genereative Adversarial Networks

The main goal of Generative Adversarial Network (GAN) is to generate images that are similar (but not identical) to training dataset.

GAN consists of two neural networks that are trained against each other:

  • Generator takes a random vector, and should generate an image from it
  • Discriminator is a networks that should distinguish between original image (from training dataset), and the one generated by the generator.
[13]

Generator

The role of a generator is to take a random vector of some size (it is similar to latent vector in autoencoders) and generate the target image. It is very similar to the generative side of autoencoder.

In our example, we will use dense neural networks and MNIST dataset.

[14]

A few tricks used in generator:

  • Instead of ReLU, we use Leaky ReLU, i.e. a ReLU which is not exactly 0 for negative xx, but rather another linear function with very small slope. This is important, because it helps gradient descent to propagate values even if we are on the negative side of ReLU (where values are 0)
  • We use Batch Normalization in order to stabilize training
  • The activation function on last layer is tanh, so the output is in the range [-1,1]

Discriminator

Discriminator is a classical image classification network. In our first example, we will also use dense classifier.

[15]

We will also define an adversarial network, which is generator followed by discriminator. This network starts with a noise vector, and returns a binary result.

[4]

Loading dataset

We will use MNIST dataset, built into Keras:

[17]

Network training

On each step of the training, we have two phases:

  • Training discriminator:
    • We generate some random vectors noise. Training happens in minibatches, so we use batch//2 vectors to produce batch//2 generated images
    • Sample batch//2 random images from the dataset
    • Train discriminator on 50% real and 50% generated images, providing corresponding labels (0 or 1)
  • Train the generator by using combined adversarial model, passing random vectors as input, and expecting 1's as output (which corresponds to real images)
[18]
[7]
epoch: 0, [Discriminator :: d_loss: 0.601463], [ Generator :: loss: 0.640677]
Output
epoch: 500, [Discriminator :: d_loss: 0.192001], [ Generator :: loss: 12.124918]
Output
epoch: 1000, [Discriminator :: d_loss: 0.141956], [ Generator :: loss: 1.900380]
Output
epoch: 1500, [Discriminator :: d_loss: 0.293635], [ Generator :: loss: 2.443017]
Output
epoch: 2000, [Discriminator :: d_loss: 0.547135], [ Generator :: loss: 2.680543]
Output
epoch: 2500, [Discriminator :: d_loss: 0.491767], [ Generator :: loss: 2.633016]
Output

Task: You can train this GAN on the whole MNIST dataset and see how good can it get

DCGAN

In the previous example, we have used dense networks for both generator and discriminator, but we know that CNNs provide better performance when dealing with images. Deep Convolutional GAN is similar to the architecture above, but it uses convolutional layers for generator and discriminator.

The main difficulty here is to build an architecture for denerator, because it has to do an inverse task compared to traditional CNN - it has to generate image from feature vector. In a way, this is similar to decoder part of autoencoders.That's why we will be using Conv2DTranspose layers in the generator.

[19]
-1.0 1.0
[9]
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_7 (Dense)              (None, 6272)              633472    
_________________________________________________________________
reshape_1 (Reshape)          (None, 7, 7, 128)         0         
_________________________________________________________________
up_sampling2d (UpSampling2D) (None, 14, 14, 128)       0         
_________________________________________________________________
conv2d_transpose (Conv2DTran (None, 14, 14, 128)       147584    
_________________________________________________________________
batch_normalization_3 (Batch (None, 14, 14, 128)       512       
_________________________________________________________________
activation (Activation)      (None, 14, 14, 128)       0         
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 28, 28, 128)       0         
_________________________________________________________________
conv2d_transpose_1 (Conv2DTr (None, 28, 28, 64)        73792     
_________________________________________________________________
batch_normalization_4 (Batch (None, 28, 28, 64)        256       
_________________________________________________________________
activation_1 (Activation)    (None, 28, 28, 64)        0         
_________________________________________________________________
conv2d_transpose_2 (Conv2DTr (None, 28, 28, 1)         577       
_________________________________________________________________
activation_2 (Activation)    (None, 28, 28, 1)         0         
=================================================================
Total params: 856,193
Trainable params: 855,809
Non-trainable params: 384
_________________________________________________________________
[10]
[11]
[12]
epoch: 0, [Discriminator :: d_loss: 0.957905], [ Generator :: loss: 0.695994]
Output
epoch: 100, [Discriminator :: d_loss: 0.826593], [ Generator :: loss: 1.488088]
Output
epoch: 200, [Discriminator :: d_loss: 0.602254], [ Generator :: loss: 1.362499]
Output
epoch: 300, [Discriminator :: d_loss: 0.711605], [ Generator :: loss: 1.224355]
Output
epoch: 400, [Discriminator :: d_loss: 0.650690], [ Generator :: loss: 0.899742]
Output
epoch: 500, [Discriminator :: d_loss: 0.413256], [ Generator :: loss: 1.106550]
Output
epoch: 600, [Discriminator :: d_loss: 0.574668], [ Generator :: loss: 1.045400]
Output
epoch: 700, [Discriminator :: d_loss: 0.522089], [ Generator :: loss: 1.068755]
Output
epoch: 800, [Discriminator :: d_loss: 0.300957], [ Generator :: loss: 1.292961]
Output
epoch: 900, [Discriminator :: d_loss: 0.389556], [ Generator :: loss: 0.942707]
Output

Task: Try generating more complex color images with DCGAN - for example, take one class from CIFAR-10 dataset.

Training on Paintings

One of the good candidates for GAN training are paintings created by human artists. Below is a sample image produced by DCGAN trained on a dataset from WikiArt. KeraGAN library was used to produce this image using Azure Machine Learning

(Photo from Art of Artificial collection)