{"cells":[{"metadata":{"_uuid":"02f22b39-a484-4c06-bf60-7dbfc60ffb4b","_cell_guid":"96bfb418-20d7-4dc9-9818-71611f185405","trusted":true},"cell_type":"code","source":"import shutil\nimport os\n\nfrom tensorflow.keras.preprocessing.image import img_to_array, array_to_img\nfrom tensorflow.keras.layers import Input, Dense, Reshape, Flatten, Dropout, LeakyReLU, Conv2D, \\\n    BatchNormalization, UpSampling2D, Reshape, Conv2DTranspose, ReLU\nfrom tensorflow.keras.models import Model,Sequential\nfrom tensorflow.keras.optimizers import Adam\nfrom PIL import Image\nfrom tqdm import tqdm\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport xml.etree.ElementTree as et\n\n\nINPUT_SIZE = 100\nPLOT_FRECUENCY = 50","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Image Loading and Processing"},{"metadata":{"_uuid":"49fc1b17-bedb-426f-9507-10b04e6b1091","_cell_guid":"83fda285-90da-4643-b24e-aa97e995fcd8","trusted":true},"cell_type":"code","source":"def read_image(file, bounds):\n    image = open_image(file, bounds)\n    image = normalize_image(image)\n    return image\n\n\ndef open_image(file, bounds):\n    image = Image.open(file)\n    image = image.crop(bounds)\n    image = image.resize((64, 64))\n    return np.array(image)\n\n\n# Normalization, [-1,1] Range\ndef normalize_image(image):\n    image = np.asarray(image, np.float32)\n    image = image / 127.5 - 1\n    return img_to_array(image)\n\n\n# Restore, [0,255] Range\ndef denormalize_image(image):\n    return ((image+1)*127.5).astype(np.uint8)\n\n\ndef load_images():\n    images = []\n\n    for breed in os.listdir('../input/annotation/Annotation/'):\n        for dog in os.listdir('../input/annotation/Annotation/' + breed):\n            tree = et.parse('../input/annotation/Annotation/' + breed + '/' + dog)\n            root = tree.getroot()\n            objects = root.findall('object')\n            for o in objects:\n                box = o.find('bndbox')\n                xmin = int(box.find('xmin').text)\n                ymin = int(box.find('ymin').text)\n                xmax = int(box.find('xmax').text)\n                ymax = int(box.find('ymax').text)\n\n            bounds = (xmin, ymin, xmax, ymax)\n            try:\n                image = read_image('../input/all-dogs/all-dogs/' + dog + '.jpg', bounds)\n                images.append(image)\n            except:\n                print('No image', dog)\n\n    return np.array(images)\n\n\nx_train = load_images()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Adversarial Networks"},{"metadata":{},"cell_type":"markdown","source":"## Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_generator():\n    generator = Sequential()\n    generator.add(Dense(units=256*4*4,input_dim=INPUT_SIZE))\n    generator.add(Reshape((4,4,256)))\n\n    generator.add(Conv2DTranspose(1024, 4, strides=1, padding='same'))\n    generator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    generator.add(ReLU())\n    \n    generator.add(Conv2DTranspose(512, 4, strides=2, padding='same'))\n    generator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    generator.add(ReLU())\n    \n    generator.add(Conv2DTranspose(256, 4, strides=2, padding='same'))\n    generator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    generator.add(ReLU())\n\n    generator.add(Conv2DTranspose(128, 4, strides=2, padding='same'))\n    generator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    generator.add(ReLU())\n    \n    generator.add(Conv2DTranspose(64, 4, strides=2, padding='same'))\n    generator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    generator.add(ReLU())\n    \n    generator.add(Conv2DTranspose(3, 3, strides=1, activation='tanh', padding='same'))\n    \n    generator.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0005, beta_1=0.5))\n\n    return generator\n\n\ngenerator = create_generator()\ngenerator.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Discriminator"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_discriminator():\n    discriminator = Sequential()\n\n    discriminator.add(Conv2D(32, kernel_size=4, strides=2, padding='same', input_shape=(64,64,3)))\n    discriminator.add(LeakyReLU(0.2))\n    \n    discriminator.add(Conv2D(64, kernel_size=4, strides=2, padding='same'))\n    discriminator.add(LeakyReLU(0.2))\n    \n    discriminator.add(Conv2D(128, kernel_size=4, strides=2, padding='same'))\n    discriminator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    discriminator.add(LeakyReLU(0.2))\n    \n    discriminator.add(Conv2D(256, kernel_size=4, strides=2, padding='same'))\n    discriminator.add(BatchNormalization(momentum=0.1, epsilon=1e-05))\n    discriminator.add(LeakyReLU(0.2))\n    \n    discriminator.add(Conv2D(1, kernel_size=4, strides=1, padding='same'))\n\n    discriminator.add(Flatten())\n    discriminator.add(Dense(units=1, activation='sigmoid'))\n    \n    discriminator.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0005, beta_1=0.5))\n    return discriminator\n\n\ndiscriminator = create_discriminator()\ndiscriminator.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## GAN"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_gan(generator, discriminator):\n    discriminator.trainable = False\n\n    gan_input = Input(shape=(INPUT_SIZE,))\n    generator_output = generator(gan_input)\n    gan_output = discriminator(generator_output)\n\n    gan = Model(inputs=gan_input, outputs=gan_output)\n    gan.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0005, beta_1=0.5))\n\n    return gan\n\n\ngan = create_gan(generator, discriminator)\ngan.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plotting"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_images(generator, size=25, dim=(5,5), figsize=(10,10)):\n    noise= generate_noise(size)\n    generated_images = generator.predict(noise)\n\n    plt.figure(figsize=figsize)\n    for i in range(generated_images.shape[0]):\n        plt.subplot(dim[0], dim[1], i+1)\n        plt.imshow(denormalize_image(generated_images[i]), interpolation='nearest')\n        plt.axis('off')\n\n    plt.tight_layout()\n    plt.show()\n    \n    \ndef plot_loss(epoch, g_losses, d_losses):\n    plt.figure(figsize=(10,5))\n    plt.title(\"Loss, Epochs 0-\" + str(epoch))\n    plt.plot(g_losses,label=\"Generator\")\n    plt.plot(d_losses,label=\"Discriminator\")\n    plt.xlabel(\"Epoch\")\n    plt.ylabel(\"Loss\")\n    plt.legend()\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_noise(size):\n    return np.random.normal(0, 1, size=[size, INPUT_SIZE])\n\n\ndef training(epochs=1, batch_size=32):\n    #Loading Data\n    batches = x_train.shape[0] / batch_size\n    \n    # Adversarial Labels\n    y_valid = np.ones(batch_size)*0.9\n    y_fake = np.zeros(batch_size)\n    discriminator_loss, generator_loss = [], []\n\n    for epoch in range(1, epochs+1):\n        g_loss = 0; d_loss = 0\n\n        for _ in range(int(batches)):\n            # Random Noise and Images Set\n            noise = generate_noise(batch_size)\n            image_batch = x_train[np.random.randint(0, x_train.shape[0], size=batch_size)]\n\n            # Generate Fake Images\n            generated_images = generator.predict(noise)\n            \n            # Train Discriminator (Fake and Real)\n            discriminator.trainable = True\n            d_valid_loss = discriminator.train_on_batch(image_batch, y_valid)\n            d_fake_loss = discriminator.train_on_batch(generated_images, y_fake)            \n\n            d_loss += (d_fake_loss + d_valid_loss)/2\n            \n            # Train Generator\n            noise = generate_noise(batch_size)\n            discriminator.trainable = False\n            g_loss += gan.train_on_batch(noise, y_valid)\n            \n        discriminator_loss.append(d_loss/batches)\n        generator_loss.append(g_loss/batches)\n            \n        if epoch % PLOT_FRECUENCY == 0:\n            print('Epoch', epoch)\n            plot_images(generator)\n            plot_loss(epoch, generator_loss, discriminator_loss)\n\n    \ntraining(epochs=200)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"def save_images(generator):\n    if not os.path.exists('../output'):\n        os.mkdir('../output')\n\n    noise = generate_noise(10000)\n    generated_images = generator.predict(noise)\n\n    for i in range(generated_images.shape[0]):\n        image = denormalize_image(generated_images[i])\n        image = array_to_img(image)\n        image.save( '../output/' + str(i) + '.png')\n\n    shutil.make_archive('images', 'zip', '../output')\n    \n    \nsave_images(generator)","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}