ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

generative_adversarial_network.py

(5842B)


      1 from __future__ import print_function, division
      2 from sklearn import datasets
      3 import math
      4 import matplotlib.pyplot as plt
      5 import numpy as np
      6 import progressbar
      7 
      8 from sklearn.datasets import fetch_mldata
      9 
     10 from mlfromscratch.deep_learning.optimizers import Adam
     11 from mlfromscratch.deep_learning.loss_functions import CrossEntropy
     12 from mlfromscratch.deep_learning.layers import Dense, Dropout, Flatten, Activation, Reshape, BatchNormalization
     13 from mlfromscratch.deep_learning import NeuralNetwork
     14 
     15 
     16 class GAN():
     17     """A Generative Adversarial Network with deep fully-connected neural nets as
     18     Generator and Discriminator.
     19 
     20     Training Data: MNIST Handwritten Digits (28x28 images)
     21     """
     22     def __init__(self):
     23         self.img_rows = 28 
     24         self.img_cols = 28
     25         self.img_dim = self.img_rows * self.img_cols
     26         self.latent_dim = 100
     27 
     28         optimizer = Adam(learning_rate=0.0002, b1=0.5)
     29         loss_function = CrossEntropy
     30 
     31         # Build the discriminator
     32         self.discriminator = self.build_discriminator(optimizer, loss_function)
     33 
     34         # Build the generator
     35         self.generator = self.build_generator(optimizer, loss_function)
     36 
     37         # Build the combined model
     38         self.combined = NeuralNetwork(optimizer=optimizer, loss=loss_function)
     39         self.combined.layers.extend(self.generator.layers)
     40         self.combined.layers.extend(self.discriminator.layers)
     41 
     42         print ()
     43         self.generator.summary(name="Generator")
     44         self.discriminator.summary(name="Discriminator")
     45 
     46     def build_generator(self, optimizer, loss_function):
     47         
     48         model = NeuralNetwork(optimizer=optimizer, loss=loss_function)
     49 
     50         model.add(Dense(256, input_shape=(self.latent_dim,)))
     51         model.add(Activation('leaky_relu'))
     52         model.add(BatchNormalization(momentum=0.8))
     53         model.add(Dense(512))
     54         model.add(Activation('leaky_relu'))
     55         model.add(BatchNormalization(momentum=0.8))
     56         model.add(Dense(1024))
     57         model.add(Activation('leaky_relu'))
     58         model.add(BatchNormalization(momentum=0.8))
     59         model.add(Dense(self.img_dim))
     60         model.add(Activation('tanh'))
     61 
     62         return model
     63 
     64     def build_discriminator(self, optimizer, loss_function):
     65         
     66         model = NeuralNetwork(optimizer=optimizer, loss=loss_function)
     67 
     68         model.add(Dense(512, input_shape=(self.img_dim,)))
     69         model.add(Activation('leaky_relu'))
     70         model.add(Dropout(0.5))
     71         model.add(Dense(256))
     72         model.add(Activation('leaky_relu'))
     73         model.add(Dropout(0.5))
     74         model.add(Dense(2))
     75         model.add(Activation('softmax'))
     76 
     77         return model
     78 
     79     def train(self, n_epochs, batch_size=128, save_interval=50):
     80 
     81         mnist = fetch_mldata('MNIST original')
     82 
     83         X = mnist.data
     84         y = mnist.target
     85 
     86         # Rescale [-1, 1]
     87         X = (X.astype(np.float32) - 127.5) / 127.5
     88 
     89         half_batch = int(batch_size / 2)
     90 
     91         for epoch in range(n_epochs):
     92 
     93             # ---------------------
     94             #  Train Discriminator
     95             # ---------------------
     96 
     97             self.discriminator.set_trainable(True)
     98 
     99             # Select a random half batch of images
    100             idx = np.random.randint(0, X.shape[0], half_batch)
    101             imgs = X[idx]
    102 
    103             # Sample noise to use as generator input
    104             noise = np.random.normal(0, 1, (half_batch, self.latent_dim))
    105 
    106             # Generate a half batch of images
    107             gen_imgs = self.generator.predict(noise)
    108 
    109             # Valid = [1, 0], Fake = [0, 1]
    110             valid = np.concatenate((np.ones((half_batch, 1)), np.zeros((half_batch, 1))), axis=1)
    111             fake = np.concatenate((np.zeros((half_batch, 1)), np.ones((half_batch, 1))), axis=1)
    112 
    113             # Train the discriminator
    114             d_loss_real, d_acc_real = self.discriminator.train_on_batch(imgs, valid)
    115             d_loss_fake, d_acc_fake = self.discriminator.train_on_batch(gen_imgs, fake)
    116             d_loss = 0.5 * (d_loss_real + d_loss_fake)
    117             d_acc = 0.5 * (d_acc_real + d_acc_fake)
    118 
    119 
    120             # ---------------------
    121             #  Train Generator
    122             # ---------------------
    123 
    124             # We only want to train the generator for the combined model
    125             self.discriminator.set_trainable(False)
    126 
    127             # Sample noise and use as generator input
    128             noise = np.random.normal(0, 1, (batch_size, self.latent_dim))
    129 
    130             # The generator wants the discriminator to label the generated samples as valid
    131             valid = np.concatenate((np.ones((batch_size, 1)), np.zeros((batch_size, 1))), axis=1)
    132 
    133             # Train the generator
    134             g_loss, g_acc = self.combined.train_on_batch(noise, valid)
    135 
    136             # Display the progress
    137             print ("%d [D loss: %f, acc: %.2f%%] [G loss: %f, acc: %.2f%%]" % (epoch, d_loss, 100*d_acc, g_loss, 100*g_acc))
    138 
    139             # If at save interval => save generated image samples
    140             if epoch % save_interval == 0:
    141                 self.save_imgs(epoch)
    142 
    143     def save_imgs(self, epoch):
    144         r, c = 5, 5 # Grid size
    145         noise = np.random.normal(0, 1, (r * c, self.latent_dim))
    146         # Generate images and reshape to image shape
    147         gen_imgs = self.generator.predict(noise).reshape((-1, self.img_rows, self.img_cols))
    148 
    149         # Rescale images 0 - 1
    150         gen_imgs = 0.5 * gen_imgs + 0.5
    151 
    152         fig, axs = plt.subplots(r, c)
    153         plt.suptitle("Generative Adversarial Network")
    154         cnt = 0
    155         for i in range(r):
    156             for j in range(c):
    157                 axs[i,j].imshow(gen_imgs[cnt,:,:], cmap='gray')
    158                 axs[i,j].axis('off')
    159                 cnt += 1
    160         fig.savefig("mnist_%d.png" % epoch)
    161         plt.close()
    162 
    163 
    164 if __name__ == '__main__':
    165     gan = GAN()
    166     gan.train(n_epochs=200000, batch_size=64, save_interval=400)
    167 
    168