Chapter 8.5 - Introduction to generative adversarial networks


In [1]:
import numpy as np
from keras.layers import Dense, LeakyReLU, Input, Conv2DTranspose, Reshape, Conv2D
from keras.models import Model


C:\ProgramData\Anaconda3\lib\site-packages\h5py\__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
Using TensorFlow backend.

In [2]:
latent_dim = 32
height = 32
width = 32
channels = 3

The generator


In [3]:
generator_input = Input(shape=(latent_dim,))

# First, transform the input into a 16x16 128-channels feature map
x = Dense(units = 128 * 16 * 16)(generator_input)
x = LeakyReLU()(x)
x = Reshape(target_shape = (16, 16, 128))(x)

# Then, add a convolution layer
x = Conv2D(filters = 256, 
           kernel_size = (5, 5), 
           padding = 'same')(x)
x = LeakyReLU()(x)

# Upsample to 32x32
x = Conv2DTranspose(filters = 256, 
                    kernel_size = (4, 4), 
                    strides = (2, 2), 
                    padding = 'same')(x)
x = LeakyReLU()(x)

# Few more conv layers
x = Conv2D(filters = 256, 
           kernel_size = (5, 5),  
           padding = 'same')(x)
x = LeakyReLU()(x)
x = Conv2D(filters = 256, 
           kernel_size = (5, 5), 
           padding = 'same')(x)
x = LeakyReLU()(x)

# Produce a 32x32 1-channel feature map
x = Conv2D(filters = channels, 
           kernel_size = (7, 7),
           activation = 'tanh', 
           padding = 'same')(x)
generator = Model(generator_input, x)
generator.summary()


_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 32)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 32768)             1081344   
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU)    (None, 32768)             0         
_________________________________________________________________
reshape_1 (Reshape)          (None, 16, 16, 128)       0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 16, 16, 256)       819456    
_________________________________________________________________
leaky_re_lu_2 (LeakyReLU)    (None, 16, 16, 256)       0         
_________________________________________________________________
conv2d_transpose_1 (Conv2DTr (None, 32, 32, 256)       1048832   
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU)    (None, 32, 32, 256)       0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 32, 32, 256)       1638656   
_________________________________________________________________
leaky_re_lu_4 (LeakyReLU)    (None, 32, 32, 256)       0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 32, 32, 256)       1638656   
_________________________________________________________________
leaky_re_lu_5 (LeakyReLU)    (None, 32, 32, 256)       0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 32, 32, 3)         37635     
=================================================================
Total params: 6,264,579
Trainable params: 6,264,579
Non-trainable params: 0
_________________________________________________________________

The discriminator


In [4]:
from keras.layers import Flatten, Dropout

In [5]:
discriminator_input = Input(shape = (height, width, channels))
x = Conv2D(filters = 128,  
           kernel_size = (3, 3))(discriminator_input)
x = LeakyReLU()(x)
x = Conv2D(filters = 128,  
           kernel_size = (4, 4), 
           strides = (2, 2))(x)
x = LeakyReLU()(x)
x = Conv2D(filters = 128,  
           kernel_size = (4, 4), 
           strides = (2, 2))(x)
x = LeakyReLU()(x)
x = Conv2D(filters = 128,  
           kernel_size = (4, 4), 
           strides = (2, 2))(x)
x = LeakyReLU()(x)
x = Flatten()(x)

# One dropout layer - important trick!
x = Dropout(rate = 0.4)(x)

# Classification layer
x = Dense(units = 1, 
          activation = 'sigmoid')(x)

discriminator = Model(discriminator_input, x)
discriminator.summary()


_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer)         (None, 32, 32, 3)         0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 30, 30, 128)       3584      
_________________________________________________________________
leaky_re_lu_6 (LeakyReLU)    (None, 30, 30, 128)       0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 14, 14, 128)       262272    
_________________________________________________________________
leaky_re_lu_7 (LeakyReLU)    (None, 14, 14, 128)       0         
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 6, 6, 128)         262272    
_________________________________________________________________
leaky_re_lu_8 (LeakyReLU)    (None, 6, 6, 128)         0         
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 2, 2, 128)         262272    
_________________________________________________________________
leaky_re_lu_9 (LeakyReLU)    (None, 2, 2, 128)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 512)               0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 513       
=================================================================
Total params: 790,913
Trainable params: 790,913
Non-trainable params: 0
_________________________________________________________________

In [6]:
from keras.optimizers import RMSprop

In [7]:
# To stabilize training, we use learning rate decay
# and gradient clipping (by value) in the optimizer.
discriminator_optimizer = RMSprop(lr = 0.0008, 
                                  clipvalue = 1.0, 
                                  decay = 1e-8)
discriminator.compile(optimizer = discriminator_optimizer, 
                      loss = 'binary_crossentropy')

The adversarial network


In [8]:
# Set discriminator weights to non-trainable
# (will only apply to the `gan` model)
discriminator.trainable = False

gan_input = Input(shape = (latent_dim,))
gan_output = discriminator(generator(gan_input))
gan = Model(gan_input, gan_output)

gan_optimizer = RMSprop(lr = 0.0004, 
                        clipvalue = 1.0, 
                        decay = 1e-8)
gan.compile(optimizer = gan_optimizer, 
            loss = 'binary_crossentropy')

Training a DCGAN


In [9]:
import os
from keras.preprocessing import image
from keras.datasets import cifar10

In [10]:
# Load CIFAR10 data
(x_train, y_train), (_, _) = cifar10.load_data()

# Select images (class 5)
x_train = x_train[y_train.flatten() == 5]

In [11]:
x_train.shape


Out[11]:
(5000, 32, 32, 3)

In [12]:
# Normalize data
x_train = x_train.reshape((x_train.shape[0],) + (height, width, channels)).astype('float32') / 255.

iterations = 10000
batch_size = 20

In [13]:
x_train.shape


Out[13]:
(5000, 32, 32, 3)

In [14]:
save_dir = './data/Chapter 8.5 - Introduction to generative adversarial networks/'

In [15]:
# Start training loop
start = 0
for step in range(iterations):
    # Sample random points in the latent space
    random_latent_vectors = np.random.normal(size = (batch_size, latent_dim))

    # Decode them to fake images
    generated_images = generator.predict(random_latent_vectors)

    # Combine them with real images
    stop = start + batch_size
    real_images = x_train[start: stop]
    combined_images = np.concatenate([generated_images, real_images])

    # Assemble labels discriminating real from fake images
    labels = np.concatenate([np.ones((batch_size, 1)),
                             np.zeros((batch_size, 1))])
    # Add random noise to the labels - important trick!
    labels = labels + 0.05 * np.random.random(labels.shape)

    # Train the discriminator
    d_loss = discriminator.train_on_batch(combined_images, labels)

    # Sample random points in the latent space
    random_latent_vectors = np.random.normal(size = (batch_size, latent_dim))

    # Assemble labels that say "all real images"
    misleading_targets = np.zeros((batch_size, 1))

    # Train the generator (via the gan model,
    # where the discriminator weights are frozen)
    a_loss = gan.train_on_batch(random_latent_vectors, misleading_targets)
    
    start = start + batch_size
    if start > len(x_train) - batch_size:
        start = 0

    # Occasionally save / plot
    if step % 100 == 0:
        # Save model weights
        gan.save_weights('./saved_checkpoints/Chapter 8.5 - Introduction to generative adversarial networks/gan.h5')

        # Print metrics
        print('-' * 50)
        print('Step: %s' % step )
        print('Discriminator loss: %s' % d_loss)
        print('Adversarial loss: %s' % a_loss)

        # Save one generated image
        img = image.array_to_img(generated_images[0] * 255., 
                                 scale = False)
        img.save(os.path.join(save_dir, 'generated_dog' + str(step) + '.png'))

        # Save one real image, for comparison
        img = image.array_to_img(real_images[0] * 255., 
                                 scale = False)
        img.save(os.path.join(save_dir, 'real_dog' + str(step) + '.png'))


C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py:953: UserWarning: Discrepancy between trainable weights and collected trainable weights, did you set `model.trainable` without calling `model.compile` after ?
  'Discrepancy between trainable weights and collected trainable'
WARNING:tensorflow:Variable *= will be deprecated. Use variable.assign_mul if you want assignment to the variable value or 'x = x * y' if you want a new python Tensor object.
--------------------------------------------------
Step: 0
Discriminator loss: 0.6911715
Adversarial loss: 0.6933484
--------------------------------------------------
Step: 100
Discriminator loss: 0.44683647
Adversarial loss: 2.628831
--------------------------------------------------
Step: 200
Discriminator loss: 0.70925105
Adversarial loss: 0.8020114
--------------------------------------------------
Step: 300
Discriminator loss: 0.7145446
Adversarial loss: 0.77895004
--------------------------------------------------
Step: 400
Discriminator loss: 0.7032187
Adversarial loss: 0.7404046
--------------------------------------------------
Step: 500
Discriminator loss: 0.69979143
Adversarial loss: 0.7711795
--------------------------------------------------
Step: 600
Discriminator loss: 0.6790079
Adversarial loss: 1.15787
--------------------------------------------------
Step: 700
Discriminator loss: 0.69431365
Adversarial loss: 0.7624009
--------------------------------------------------
Step: 800
Discriminator loss: 0.75251454
Adversarial loss: 0.90363896
--------------------------------------------------
Step: 900
Discriminator loss: 0.6952241
Adversarial loss: 0.8307866
--------------------------------------------------
Step: 1000
Discriminator loss: 0.7054943
Adversarial loss: 0.7260996
--------------------------------------------------
Step: 1100
Discriminator loss: 0.70006144
Adversarial loss: 0.7457956
--------------------------------------------------
Step: 1200
Discriminator loss: 0.6897727
Adversarial loss: 0.7516589
--------------------------------------------------
Step: 1300
Discriminator loss: 0.69468915
Adversarial loss: 0.7897028
--------------------------------------------------
Step: 1400
Discriminator loss: 0.69670707
Adversarial loss: 0.73326683
--------------------------------------------------
Step: 1500
Discriminator loss: 0.68500197
Adversarial loss: 0.68625075
--------------------------------------------------
Step: 1600
Discriminator loss: 0.67639923
Adversarial loss: 0.80879366
--------------------------------------------------
Step: 1700
Discriminator loss: 0.7212465
Adversarial loss: 0.7429582
--------------------------------------------------
Step: 1800
Discriminator loss: 0.6789199
Adversarial loss: 0.7903185
--------------------------------------------------
Step: 1900
Discriminator loss: 0.6723213
Adversarial loss: 0.8794702
--------------------------------------------------
Step: 2000
Discriminator loss: 0.6927999
Adversarial loss: 0.87353134
--------------------------------------------------
Step: 2100
Discriminator loss: 0.7029891
Adversarial loss: 0.7775944
--------------------------------------------------
Step: 2200
Discriminator loss: 0.68108535
Adversarial loss: 0.90648127
--------------------------------------------------
Step: 2300
Discriminator loss: 0.69884574
Adversarial loss: 0.77626145
--------------------------------------------------
Step: 2400
Discriminator loss: 0.6791872
Adversarial loss: 0.77388597
--------------------------------------------------
Step: 2500
Discriminator loss: 0.69965726
Adversarial loss: 0.67664176
--------------------------------------------------
Step: 2600
Discriminator loss: 0.66865647
Adversarial loss: 0.85385674
--------------------------------------------------
Step: 2700
Discriminator loss: 0.6744262
Adversarial loss: 0.97089624
--------------------------------------------------
Step: 2800
Discriminator loss: 0.68916875
Adversarial loss: 0.77362955
--------------------------------------------------
Step: 2900
Discriminator loss: 0.70223516
Adversarial loss: 0.7849681
--------------------------------------------------
Step: 3000
Discriminator loss: 0.6773055
Adversarial loss: 0.8516523
--------------------------------------------------
Step: 3100
Discriminator loss: 0.6643353
Adversarial loss: 0.86221564
--------------------------------------------------
Step: 3200
Discriminator loss: 0.6684871
Adversarial loss: 0.8877943
--------------------------------------------------
Step: 3300
Discriminator loss: 0.6550965
Adversarial loss: 0.86263144
--------------------------------------------------
Step: 3400
Discriminator loss: 0.70162416
Adversarial loss: 0.6676649
--------------------------------------------------
Step: 3500
Discriminator loss: 0.6952876
Adversarial loss: 0.99171543
--------------------------------------------------
Step: 3600
Discriminator loss: 0.6895224
Adversarial loss: 0.9264434
--------------------------------------------------
Step: 3700
Discriminator loss: 0.71681684
Adversarial loss: 0.8614456
--------------------------------------------------
Step: 3800
Discriminator loss: 0.6729911
Adversarial loss: 1.0582005
--------------------------------------------------
Step: 3900
Discriminator loss: 0.6995832
Adversarial loss: 0.81170386
--------------------------------------------------
Step: 4000
Discriminator loss: 0.69235384
Adversarial loss: 1.0145327
--------------------------------------------------
Step: 4100
Discriminator loss: 0.7924156
Adversarial loss: 2.4178765
--------------------------------------------------
Step: 4200
Discriminator loss: 0.7185844
Adversarial loss: 0.7813747
--------------------------------------------------
Step: 4300
Discriminator loss: 0.7019522
Adversarial loss: 0.7702726
--------------------------------------------------
Step: 4400
Discriminator loss: 0.68162084
Adversarial loss: 0.82279253
--------------------------------------------------
Step: 4500
Discriminator loss: 0.68529516
Adversarial loss: 0.7544757
--------------------------------------------------
Step: 4600
Discriminator loss: 0.7233573
Adversarial loss: 0.8187416
--------------------------------------------------
Step: 4700
Discriminator loss: 0.6822995
Adversarial loss: 0.7368448
--------------------------------------------------
Step: 4800
Discriminator loss: 0.68382776
Adversarial loss: 0.7693602
--------------------------------------------------
Step: 4900
Discriminator loss: 0.6784229
Adversarial loss: 0.76925075
--------------------------------------------------
Step: 5000
Discriminator loss: 0.6867162
Adversarial loss: 0.8713625
--------------------------------------------------
Step: 5100
Discriminator loss: 0.68624526
Adversarial loss: 0.8143288
--------------------------------------------------
Step: 5200
Discriminator loss: 0.68612945
Adversarial loss: 0.82269776
--------------------------------------------------
Step: 5300
Discriminator loss: 0.69660705
Adversarial loss: 0.7579215
--------------------------------------------------
Step: 5400
Discriminator loss: 0.6789893
Adversarial loss: 0.8200084
--------------------------------------------------
Step: 5500
Discriminator loss: 0.72082186
Adversarial loss: 0.9304228
--------------------------------------------------
Step: 5600
Discriminator loss: 0.7045619
Adversarial loss: 0.79948837
--------------------------------------------------
Step: 5700
Discriminator loss: 0.69796574
Adversarial loss: 0.79910123
--------------------------------------------------
Step: 5800
Discriminator loss: 0.68886065
Adversarial loss: 0.7728654
--------------------------------------------------
Step: 5900
Discriminator loss: 0.6807909
Adversarial loss: 0.7921885
--------------------------------------------------
Step: 6000
Discriminator loss: 0.68425834
Adversarial loss: 0.7994927
--------------------------------------------------
Step: 6100
Discriminator loss: 0.68168545
Adversarial loss: 0.8104867
--------------------------------------------------
Step: 6200
Discriminator loss: 0.69464415
Adversarial loss: 0.72118616
--------------------------------------------------
Step: 6300
Discriminator loss: 0.70137316
Adversarial loss: 0.7575309
--------------------------------------------------
Step: 6400
Discriminator loss: 0.6875243
Adversarial loss: 0.8361305
--------------------------------------------------
Step: 6500
Discriminator loss: 0.71526825
Adversarial loss: 0.82820815
--------------------------------------------------
Step: 6600
Discriminator loss: 0.68705666
Adversarial loss: 0.7904312
--------------------------------------------------
Step: 6700
Discriminator loss: 0.71096146
Adversarial loss: 0.7600935
--------------------------------------------------
Step: 6800
Discriminator loss: 0.6972765
Adversarial loss: 0.7767426
--------------------------------------------------
Step: 6900
Discriminator loss: 0.68509376
Adversarial loss: 0.8056838
--------------------------------------------------
Step: 7000
Discriminator loss: 0.7230104
Adversarial loss: 0.7839001
--------------------------------------------------
Step: 7100
Discriminator loss: 0.6922885
Adversarial loss: 0.75965863
--------------------------------------------------
Step: 7200
Discriminator loss: 0.6749347
Adversarial loss: 0.6775611
--------------------------------------------------
Step: 7300
Discriminator loss: 0.7141993
Adversarial loss: 0.7120148
--------------------------------------------------
Step: 7400
Discriminator loss: 0.68293697
Adversarial loss: 0.7780585
--------------------------------------------------
Step: 7500
Discriminator loss: 0.69306594
Adversarial loss: 0.7886464
--------------------------------------------------
Step: 7600
Discriminator loss: 0.7205754
Adversarial loss: 0.73802483
--------------------------------------------------
Step: 7700
Discriminator loss: 0.7114936
Adversarial loss: 0.5833697
--------------------------------------------------
Step: 7800
Discriminator loss: 0.7028869
Adversarial loss: 0.6880201
--------------------------------------------------
Step: 7900
Discriminator loss: 0.68306845
Adversarial loss: 0.76671004
--------------------------------------------------
Step: 8000
Discriminator loss: 0.686694
Adversarial loss: 0.82968616
--------------------------------------------------
Step: 8100
Discriminator loss: 0.6776139
Adversarial loss: 0.7630439
--------------------------------------------------
Step: 8200
Discriminator loss: 0.681163
Adversarial loss: 0.7413414
--------------------------------------------------
Step: 8300
Discriminator loss: 0.6898142
Adversarial loss: 0.8415512
--------------------------------------------------
Step: 8400
Discriminator loss: 0.6928853
Adversarial loss: 0.7913861
--------------------------------------------------
Step: 8500
Discriminator loss: 0.68659353
Adversarial loss: 0.7492336
--------------------------------------------------
Step: 8600
Discriminator loss: 0.68708456
Adversarial loss: 0.77956426
--------------------------------------------------
Step: 8700
Discriminator loss: 0.697896
Adversarial loss: 0.7403568
--------------------------------------------------
Step: 8800
Discriminator loss: 0.68905747
Adversarial loss: 0.7231371
--------------------------------------------------
Step: 8900
Discriminator loss: 0.70890033
Adversarial loss: 0.81286156
--------------------------------------------------
Step: 9000
Discriminator loss: 0.72729605
Adversarial loss: 0.81993073
--------------------------------------------------
Step: 9100
Discriminator loss: 0.6967311
Adversarial loss: 0.83500254
--------------------------------------------------
Step: 9200
Discriminator loss: 0.7148731
Adversarial loss: 0.6921493
--------------------------------------------------
Step: 9300
Discriminator loss: 0.6893544
Adversarial loss: 0.7566522
--------------------------------------------------
Step: 9400
Discriminator loss: 0.6894201
Adversarial loss: 0.82959604
--------------------------------------------------
Step: 9500
Discriminator loss: 0.69895107
Adversarial loss: 0.9418046
--------------------------------------------------
Step: 9600
Discriminator loss: 0.68523425
Adversarial loss: 0.70057625
--------------------------------------------------
Step: 9700
Discriminator loss: 0.68753856
Adversarial loss: 0.84994173
--------------------------------------------------
Step: 9800
Discriminator loss: 0.6732129
Adversarial loss: 0.7845704
--------------------------------------------------
Step: 9900
Discriminator loss: 0.7045146
Adversarial loss: 0.7784