Skip to content

Commit

Permalink
add notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
drmerlot committed Mar 17, 2018
1 parent 6c59e40 commit 738d633
Show file tree
Hide file tree
Showing 5 changed files with 86,822 additions and 0 deletions.
330 changes: 330 additions & 0 deletions .ipynb_checkpoints/.ipynb_checkpoints/DCGAN-checkpoint.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Generating Faces With A Deep Convolutional Generative Adversarial Network\n",
"\n",
"Recently I found a great repo posted by Erik Lindernoren [https://github.com/eriklindernoren/Keras-GAN/blob/master/dcgan/dcgan.py] providing wire frame code for a whole bunch of different GANs. I've wanted to give GANs a try for a while so, I grabbed the DCGAN code from this repo, a celebrity faces data set posted by Mirantha Jayathilaka at [https://www.floydhub.com/mirantha/datasets/celeba]. Following methods and using code from the DCGAN and gan_rgb folders in Erik Lindernoren's repo, I set up the the DCGAN code to train on RGB images from the Celeba data set. \n",
"\n",
"On a hunch, I wanted to modify the generator network to accept random noise in the same size and shape as the image it is generating, rather than a random vector of lenght 100. My thought was, why 100? I couldn't not think of any theoretical reason to keep the length of the random vector to 100, or any guidence on the size. Without reseraching, I decided to make the random input the same size and dimentions as the output that is to be produced. Following Erik's code, I used his crop and resize pre-processing to generate and discriminate with 28x28 pixel images cropped close to the faces. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
}
],
"source": [
"# Imports \n",
"# code from https://github.com/eriklindernoren/Keras-GAN/blob/master/dcgan/dcgan.py\n",
"from __future__ import print_function, division\n",
"\n",
"from keras.datasets import mnist\n",
"from keras.layers import Input, Dense, Reshape, Flatten, Dropout\n",
"from keras.layers import BatchNormalization, Activation, ZeroPadding2D\n",
"from keras.layers.advanced_activations import LeakyReLU\n",
"from keras.layers.convolutional import UpSampling2D, Conv2D\n",
"from keras.models import Sequential, Model\n",
"from keras.optimizers import Adam\n",
"\n",
"import matplotlib.pyplot as plt\n",
"\n",
"import sys\n",
"\n",
"import numpy as np\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Code from https://github.com/eriklindernoren/Keras-GAN/blob/master/dcgan/dcgan.py\n",
"# with edits to generate from different noise input\n",
"# DC GAN covoutional \n",
"\n",
"# DCGAN class \n",
"class DCGAN():\n",
" def __init__(self):\n",
" self.img_rows = 28 \n",
" self.img_cols = 28\n",
" self.channels = 3\n",
" self.img_shape = (self.img_rows, self.img_cols, self.channels)\n",
"\n",
" optimizer = Adam(0.0002, 0.5)\n",
"\n",
" # Build and compile the discriminator\n",
" self.discriminator = self.build_discriminator()\n",
" self.discriminator.compile(loss='binary_crossentropy',\n",
" optimizer=optimizer,\n",
" metrics=['accuracy'])\n",
"\n",
" # Build and compile the generator\n",
" self.generator = self.build_generator()\n",
" self.generator.compile(loss='binary_crossentropy', optimizer=optimizer)\n",
"\n",
" # The generator takes noise as input and generated imgs\n",
" z = Input(shape=(100,))\n",
" img = self.generator(z)\n",
"\n",
" # For the combined model we will only train the generator\n",
" self.discriminator.trainable = False\n",
"\n",
" # The valid takes generated images as input and determines validity\n",
" valid = self.discriminator(img)\n",
"\n",
" # The combined model (stacked generator and discriminator) takes\n",
" # noise as input => generates images => determines validity\n",
" self.combined = Model(z, valid)\n",
" self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)\n",
"\n",
" def build_generator(self):\n",
"\n",
" noise_shape = (100,)\n",
"\n",
" model = Sequential()\n",
"\n",
" model.add(Dense(128 * 7 * 7, activation=\"relu\", input_shape=noise_shape))\n",
" model.add(Reshape((7, 7, 128)))\n",
" model.add(BatchNormalization(momentum=0.8))\n",
" model.add(UpSampling2D())\n",
" model.add(Conv2D(128, kernel_size=3, padding=\"same\"))\n",
" model.add(Activation(\"relu\"))\n",
" model.add(BatchNormalization(momentum=0.8))\n",
" model.add(UpSampling2D())\n",
" model.add(Conv2D(64, kernel_size=3, padding=\"same\"))\n",
" model.add(Activation(\"relu\"))\n",
" model.add(BatchNormalization(momentum=0.8))\n",
" model.add(Flatten())\n",
" model.add(Dense(np.prod(self.img_shape), activation='tanh'))\n",
" model.add(Reshape(self.img_shape))\n",
"\n",
" model.summary()\n",
"\n",
" noise = Input(shape=noise_shape)\n",
" img = model(noise)\n",
"\n",
" return Model(noise, img)\n",
"\n",
" def build_discriminator(self):\n",
"\n",
" img_shape = (self.img_rows, self.img_cols, self.channels)\n",
"\n",
" model = Sequential()\n",
"\n",
" model.add(Conv2D(32, kernel_size=3, strides=2, input_shape=img_shape, padding=\"same\"))\n",
" model.add(LeakyReLU(alpha=0.2))\n",
" model.add(Dropout(0.25))\n",
" model.add(Conv2D(64, kernel_size=3, strides=2, padding=\"same\"))\n",
" model.add(ZeroPadding2D(padding=((0, 1), (0, 1))))\n",
" model.add(LeakyReLU(alpha=0.2))\n",
" model.add(Dropout(0.25))\n",
" model.add(BatchNormalization(momentum=0.8))\n",
" model.add(Conv2D(128, kernel_size=3, strides=2, padding=\"same\"))\n",
" model.add(LeakyReLU(alpha=0.2))\n",
" model.add(Dropout(0.25))\n",
" model.add(BatchNormalization(momentum=0.8))\n",
" model.add(Conv2D(256, kernel_size=3, strides=1, padding=\"same\"))\n",
" model.add(LeakyReLU(alpha=0.2))\n",
" model.add(Dropout(0.25))\n",
"\n",
" model.add(Flatten())\n",
" model.add(Dense(1, activation='sigmoid'))\n",
"\n",
" model.summary()\n",
"\n",
" img = Input(shape=img_shape)\n",
" validity = model(img)\n",
"\n",
" return Model(img, validity)\n",
"\n",
" def train(self, epochs, batch_size=128, save_interval=50):\n",
"\n",
" # Load the dataset\n",
" #(X_train, _), (_, _) = mnist.load_data()\n",
"\n",
" # Rescale -1 to 1\n",
" X_train = (X_train.astype(np.float32) - 127.5) / 127.5\n",
" X_train = np.expand_dims(X_train, axis=3)\n",
"\n",
" half_batch = int(batch_size / 2)\n",
"\n",
" for epoch in range(epochs):\n",
"\n",
" # ---------------------\n",
" # Train Discriminator\n",
" # ---------------------\n",
"\n",
" # Select a random half batch of images\n",
" idx = np.random.randint(0, X_train.shape[0], half_batch)\n",
" imgs = X_train[idx]\n",
"\n",
" # Sample noise and generate a half batch of new images\n",
" noise = np.random.normal(0, 1, (half_batch, 100))\n",
" gen_imgs = self.generator.predict(noise)\n",
"\n",
" # Train the discriminator (real classified as ones and generated as zeros)\n",
" d_loss_real = self.discriminator.train_on_batch(imgs, np.ones((half_batch, 1)))\n",
" d_loss_fake = self.discriminator.train_on_batch(gen_imgs, np.zeros((half_batch, 1)))\n",
" d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)\n",
"\n",
" # ---------------------\n",
" # Train Generator\n",
" # ---------------------\n",
"\n",
" noise = np.random.normal(0, 1, (batch_size, 100))\n",
"\n",
" # Train the generator (wants discriminator to mistake images as real)\n",
" g_loss = self.combined.train_on_batch(noise, np.ones((batch_size, 1)))\n",
"\n",
" # Plot the progress\n",
" print(\"%d [D loss: %f, acc.: %.2f%%] [G loss: %f]\" % (epoch, d_loss[0], 100 * d_loss[1], g_loss))\n",
"\n",
" # If at save interval => save generated image samples\n",
" if epoch % save_interval == 0:\n",
" self.save_imgs(epoch)\n",
"\n",
" def save_imgs(self, epoch):\n",
" r, c = 5, 5\n",
" noise = np.random.normal(0, 1, (r * c, 100))\n",
" gen_imgs = self.generator.predict(noise)\n",
"\n",
" # Rescale images 0 - 1\n",
" gen_imgs = 0.5 * gen_imgs + 0.5\n",
"\n",
" fig, axs = plt.subplots(r, c)\n",
" # fig.suptitle(\"DCGAN: Generated digits\", fontsize=12)\n",
" cnt = 0\n",
" for i in range(r):\n",
" for j in range(c):\n",
" axs[i,j].imshow(gen_imgs[cnt, :,:,:])\n",
" axs[i, j].axis('off')\n",
" cnt += 1\n",
" fig.savefig(\"output/mnist_%d.png\" % epoch)\n",
" plt.close()\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"conv2d_1 (Conv2D) (None, 14, 14, 32) 896 \n",
"_________________________________________________________________\n",
"leaky_re_lu_1 (LeakyReLU) (None, 14, 14, 32) 0 \n",
"_________________________________________________________________\n",
"dropout_1 (Dropout) (None, 14, 14, 32) 0 \n",
"_________________________________________________________________\n",
"conv2d_2 (Conv2D) (None, 7, 7, 64) 18496 \n",
"_________________________________________________________________\n",
"zero_padding2d_1 (ZeroPaddin (None, 8, 8, 64) 0 \n",
"_________________________________________________________________\n",
"leaky_re_lu_2 (LeakyReLU) (None, 8, 8, 64) 0 \n",
"_________________________________________________________________\n",
"dropout_2 (Dropout) (None, 8, 8, 64) 0 \n",
"_________________________________________________________________\n",
"batch_normalization_1 (Batch (None, 8, 8, 64) 256 \n",
"_________________________________________________________________\n",
"conv2d_3 (Conv2D) (None, 4, 4, 128) 73856 \n",
"_________________________________________________________________\n",
"leaky_re_lu_3 (LeakyReLU) (None, 4, 4, 128) 0 \n",
"_________________________________________________________________\n",
"dropout_3 (Dropout) (None, 4, 4, 128) 0 \n",
"_________________________________________________________________\n",
"batch_normalization_2 (Batch (None, 4, 4, 128) 512 \n",
"_________________________________________________________________\n",
"conv2d_4 (Conv2D) (None, 4, 4, 256) 295168 \n",
"_________________________________________________________________\n",
"leaky_re_lu_4 (LeakyReLU) (None, 4, 4, 256) 0 \n",
"_________________________________________________________________\n",
"dropout_4 (Dropout) (None, 4, 4, 256) 0 \n",
"_________________________________________________________________\n",
"flatten_1 (Flatten) (None, 4096) 0 \n",
"_________________________________________________________________\n",
"dense_1 (Dense) (None, 1) 4097 \n",
"=================================================================\n",
"Total params: 393,281\n",
"Trainable params: 392,897\n",
"Non-trainable params: 384\n",
"_________________________________________________________________\n",
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"dense_2 (Dense) (None, 6272) 633472 \n",
"_________________________________________________________________\n",
"reshape_1 (Reshape) (None, 7, 7, 128) 0 \n",
"_________________________________________________________________\n",
"batch_normalization_3 (Batch (None, 7, 7, 128) 512 \n",
"_________________________________________________________________\n",
"up_sampling2d_1 (UpSampling2 (None, 14, 14, 128) 0 \n",
"_________________________________________________________________\n",
"conv2d_5 (Conv2D) (None, 14, 14, 128) 147584 \n",
"_________________________________________________________________\n",
"activation_1 (Activation) (None, 14, 14, 128) 0 \n",
"_________________________________________________________________\n",
"batch_normalization_4 (Batch (None, 14, 14, 128) 512 \n",
"_________________________________________________________________\n"
]
}
],
"source": [
"# Code from https://github.com/eriklindernoren/Keras-GAN/blob/master/dcgan/dcgan.py\n",
"# pulled out of the file context to run here in the notebook\n",
"dcgan = DCGAN()\n",
"dcgan.train(epochs=2, batch_size=32, save_interval=1)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
},
"widgets": {
"state": {},
"version": "1.1.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading

0 comments on commit 738d633

Please sign in to comment.