ml-finance-python

python scripts for finance machine learning

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

dcgan.py

(6384B)


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