{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input/\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"from __future__ import print_function, division\n\nfrom keras.datasets import mnist\nfrom keras.layers import Input, Dense, Reshape, Flatten, Dropout\nfrom keras.layers import BatchNormalization, Activation, ZeroPadding2D\nfrom keras.layers.advanced_activations import LeakyReLU\nfrom keras.layers.convolutional import UpSampling2D, Conv2D, Conv2DTranspose\nfrom keras.models import Sequential, Model\nfrom keras.optimizers import Adam\n\nimport matplotlib.pyplot as plt\n\nimport sys\n\nimport numpy as np\n\nfrom tqdm import tqdm_notebook as tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import xml.etree.ElementTree as ET # xml parser used during pre-processing stage\nimport xml.dom.minidom # for printing the annotation xml nicely\n\n# Demo: Show how the Annotation files XML is structured\ndom = xml.dom.minidom.parse('../input/annotation/Annotation/n02097658-silky_terrier/n02097658_98') # or xml.dom.minidom.parseString(xml_string)\npretty_xml_as_string = dom.toprettyxml()\n#print(pretty_xml_as_string)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image # Python Image Library\n# Code slightly modified from user: cdeotte | https://www.kaggle.com/cdeotte/supervised-generative-dog-net\n\nROOT = '../input/'\n# list of all image file names in all-dogs\nIMAGES = os.listdir(ROOT + 'all-dogs/all-dogs')\n# list of all the annotation directories, each directory is a dog breed\nbreeds = os.listdir(ROOT + 'annotation/Annotation/') \n\nidxIn = 0; namesIn = []\nimagesIn = np.zeros((25000,64,64,3))\n\n# CROP WITH BOUNDING BOXES TO GET DOGS ONLY\n# iterate through each directory in annotation\nfor breed in breeds:\n    # iterate through each file in the directory\n    for dog in os.listdir(ROOT+'annotation/Annotation/'+breed):\n        try: img = Image.open(ROOT+'all-dogs/all-dogs/'+dog+'.jpg') \n        except: continue           \n        # Element Tree library allows for parsing xml and getting specific tag values    \n        tree = ET.parse(ROOT+'annotation/Annotation/'+breed+'/'+dog)\n        # take a look at the print out of an xml previously to get what is going on\n        root = tree.getroot() # <annotation>\n        objects = root.findall('object') # <object>\n        for o in objects:\n            bndbox = o.find('bndbox') # <bndbox>\n            xmin = int(bndbox.find('xmin').text) # <xmin>\n            ymin = int(bndbox.find('ymin').text) # <ymin>\n            xmax = int(bndbox.find('xmax').text) # <xmax>\n            ymax = int(bndbox.find('ymax').text) # <ymax>\n            w = np.min((xmax - xmin, ymax - ymin))\n            img2 = img.crop((xmin, ymin, xmin+w, ymin+w))\n            img2 = img2.resize((64,64), Image.ANTIALIAS)\n            imagesIn[idxIn,:,:,:] = np.asarray(img2)\n            namesIn.append(breed)\n            idxIn += 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_rows = 64\nimg_cols = 64\nchannels = 3\nimg_shape = (img_rows, img_cols, channels)\nlatent_dim = 100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_generator():\n\n    model = Sequential()\n    model.add(Dense(32 * 8 * 8, activation = \"relu\", input_dim = latent_dim))\n    \n    model.add(Dense(64 * 8 * 8, activation = \"relu\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Reshape((8, 8, 64)))\n    \n    model.add(UpSampling2D())\n    model.add(Conv2D(128, kernel_size = 3, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Activation(\"relu\"))\n    \n    model.add(UpSampling2D())\n    model.add(Conv2D(256, kernel_size = 3, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Activation(\"relu\"))\n\n    model.add(UpSampling2D())\n    model.add(Conv2D(512, kernel_size = 3, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Activation(\"relu\"))\n    \n    model.add(Conv2D(256, kernel_size = 5, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Activation(\"relu\"))\n    \n    model.add(Conv2D(128, kernel_size = 5, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Activation(\"relu\"))\n    \n    model.add(Conv2D(64, kernel_size = 3, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(Activation(\"relu\"))\n    \n    model.add(Conv2D(channels, kernel_size = 3, padding = \"same\"))\n    model.add(Activation(\"tanh\"))\n    \n    return model\n\ngenerator = build_generator()\ngenerator.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_discriminator():\n\n    model = Sequential()\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\n    model.add(Conv2D(64, kernel_size = 3, strides = 2, padding = \"same\"))\n    model.add(ZeroPadding2D(padding = ((0, 1), (0, 1))))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(LeakyReLU(alpha = 0.2))\n    model.add(Dropout(0.25))\n    \n    model.add(Conv2D(128, kernel_size = 3, strides = 2, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\n    model.add(LeakyReLU(alpha = 0.2))\n    model.add(Dropout(0.25))\n    \n    model.add(Conv2D(256, kernel_size = 3, strides = 2, padding = \"same\"))\n    model.add(BatchNormalization(momentum = 0.8))\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    return model\n\ndiscriminator = build_discriminator()\ndiscriminator.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = Adam(0.0002, 0.5)\n\n# Build and compile the discriminator\ndiscriminator = build_discriminator()\ndiscriminator.compile(loss='binary_crossentropy',\n                      optimizer=optimizer,\n                      metrics=['accuracy'])\n\n# Build the generator\ngenerator = build_generator()\n\n# The generator takes noise as input and generates imgs\nz = Input(shape=(latent_dim,))\nimg = generator(z)\n\n# For the combined model we will only train the generator\ndiscriminator.trainable = False\n\n# The discriminator takes generated images as input and determines validity\nvalid = discriminator(img)\n\n# The combined model  (stacked generator and discriminator)\n# Trains the generator to fool the discriminator\ncombined = Model(z, valid)\ncombined.compile(loss='binary_crossentropy', optimizer=optimizer)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def save_imgs(epoch):\n    r = 1\n    c = 5\n    noise = np.random.normal(0.0, 1.0, (batch_size, latent_dim))\n    gen_imgs = generator.predict(noise)\n    \n    # Rescale images 0 - 1\n    gen_imgs = 0.5 * gen_imgs + 0.5\n    \n    cnt = 0\n    for k in range(r):\n        plt.figure(figsize=(15,3))\n        for j in range(c):\n            plt.subplot(1,5,j+1)\n            plt.axis('off')\n            plt.imshow(gen_imgs[cnt, :,:,:])\n            cnt +=1\n        #plt.savefig('gen_images_{}.png'.format(epoch))\n        plt.show()\n        plt.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 100000\nbatch_size=32\nsave_interval=1000\nComputeLB = True\n\n# Load the dataset\nX_train = imagesIn\n\n# Rescale -1 to 1\nX_train = X_train / 127.5 - 1.\n\n# Adversarial ground truths\nvalid = np.ones((batch_size, 1))\nfake = np.zeros((batch_size, 1))\n\ng_loss_list = []\nd_loss_list = []\n\nfor epoch in tqdm(range(epochs)):\n    \n    # ---------------------\n    #  Train Discriminator\n    # ---------------------\n\n    # Select a random half of images\n    idx = np.random.randint(0, X_train.shape[0], batch_size)\n    imgs = X_train[idx]\n\n    # Sample noise and generate a batch of new images\n    noise = np.random.normal(0, 1, (batch_size, latent_dim))\n    gen_imgs = generator.predict(noise)\n\n    # Train the discriminator (real classified as ones and generated as zeros)\n    d_loss_real = discriminator.train_on_batch(imgs, valid)\n    d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)\n    d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)\n\n    # ---------------------\n    #  Train Generator\n    # ---------------------\n\n    # Train the generator (wants discriminator to mistake images as real)\n    g_loss = combined.train_on_batch(noise, valid)\n\n    # Plot the progress\n    g_loss_list.append(g_loss)\n    d_loss_list.append(d_loss[0])\n    # If at save interval => save generated image samples\n    if epoch % save_interval == 0:\n        print (\"%d [D loss: %f, acc.: %.2f%%] [G loss: %f]\" % (epoch, d_loss[0], 100*d_loss[1], g_loss))\n        save_imgs(epoch)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"save_imgs(epochs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_loss (gen_loss_list, dis_loss_list):\n    plt.figure(figsize=(10,5))\n    plt.title(\"Generator and Discriminator Loss\")\n    plt.plot(gen_loss_list,label=\"G\")\n    plt.plot(dis_loss_list,label=\"D\")\n    plt.xlabel(\"Epochs\")\n    plt.ylabel(\"Loss\")\n    plt.legend()\n    plt.show()\n    \nplot_loss(g_loss_list,d_loss_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists('../output_images'):\n    os.mkdir('../output_images')\nim_batch_size = 50\nn_images=10000\nfor i_batch in range(0, n_images, im_batch_size):\n    noise= np.random.normal(0,1, [im_batch_size, 100])\n    gen_images = generator.predict(noise)\n    images = gen_images[:im_batch_size,:,:,:]\n    for i_image in range(len(images)):\n        img = gen_images[i_image,:,:,:]*127.5+127.5\n        img = Image.fromarray(img.astype('uint8'))\n        img.save(os.path.join('../output_images', f'image_{i_batch+i_image:05d}.png'))\n\nimport shutil\nshutil.make_archive('images', 'zip', '../output_images')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}