{"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\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 read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"!unzip /kaggle/input/generative-dog-images/Annotation.zip\n!unzip /kaggle/input/generative-dog-images/all-dogs.zip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"breeds = os.listdir('Annotation/')\nbreeds[0:5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import xml.etree.ElementTree as ET # for parsing XML\nimport matplotlib.pyplot as plt # to show images\nfrom PIL import Image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_width = 64\nimage_height = 64\nimage_channels = 3\nscale_factor = 16\n\ndataset = []\ndog_breed = []\n\nfor breed in breeds:\n    for dog in os.listdir('Annotation/' + breed):\n        try: img = Image.open('all-dogs/' + dog + '.jpg')\n        except: continue\n        tree = ET.parse('Annotation/' + breed + '/' + dog)\n        root = tree.getroot()\n        objects = root.findall('object')\n        for o in objects:\n            bndbox = o.find('bndbox') # reading bound box\n            xmin = int(bndbox.find('xmin').text)\n            ymin = int(bndbox.find('ymin').text)\n            xmax = int(bndbox.find('xmax').text)\n            ymax = int(bndbox.find('ymax').text)\n            w = np.min((xmax - xmin, ymax - ymin))\n            img_cropped = img.crop((xmin, ymin, xmin+w, ymin+w))\n            img_cropped = img_cropped.resize((image_width, image_height))\n            dataset.append(np.asarray(img_cropped))\n            dog_breed.append(breed.split('-')[1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, axes = plt.subplots(nrows=5, ncols=5, figsize=(16,16))\nfor indx, axis in enumerate(axes.flatten()):\n    i = np.random.randint(0, len(dataset))\n    axis.set_axis_off()\n    axis.imshow((dataset[i]).astype('uint8'))\n    axis.text(0,-5,dog_breed[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(dataset)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\ndog_features_tf = tf.cast(dataset, 'float32')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def flip(x: tf.Tensor) -> (tf.Tensor):\n    x = tf.image.random_flip_left_right(x)\n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dog_features_data = tf.data.Dataset.from_tensor_slices(dog_features_tf).shuffle(22125).map(flip).batch(batch_size = 32, drop_remainder=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dog_features_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(len(dataset)):\n    dataset[i] = (dataset[i].astype(np.float32) - 127.5) / 127.5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras\nfrom keras.layers import Input, Dense, Reshape, Flatten, Dropout, Concatenate, ReLU\nfrom keras.backend import random_normal, ones_like, zeros_like, mean\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\nfrom keras.layers import concatenate\nfrom keras.initializers import TruncatedNormal\nfrom keras.callbacks import LearningRateScheduler, EarlyStopping, History","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import tensorflow as tf\nweight_initializer = tf.keras.initializers.TruncatedNormal(stddev=0.02, mean=0, seed=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def transposed_conv(model, out_channels, ksize, stride_size, ptype='same'):\n    model.add(Conv2DTranspose(out_channels, (ksize, ksize),\n                              strides=(stride_size, stride_size), \n                              padding=ptype, \n                              kernel_initializer=weight_initializer, \n                              use_bias=False))\n    model.add(BatchNormalization())\n    model.add(ReLU())\n    return model\n\n\ndef convSN(model, out_channels, ksize, stride_size):\n    model.add(Conv2D(out_channels, (ksize, ksize), strides=(stride_size, stride_size), padding='same',\n                     kernel_initializer=weight_initializer, use_bias=False))\n    model.add(BatchNormalization())\n    model.add(LeakyReLU(alpha=0.2))\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def DogGenerator():\n    model = Sequential()\n    model.add(Dense(image_width // scale_factor * image_height // scale_factor * 128,\n                    input_shape=(128,), kernel_initializer=weight_initializer))\n    model.add(Reshape((image_height // scale_factor, image_width // scale_factor, 128)))\n    \n    model = transposed_conv(model, 512, ksize=5, stride_size=1)\n    model.add(Dropout(0.3))\n    model = transposed_conv(model, 256, ksize=5, stride_size=2)\n    model.add(Dropout(0.3))\n    model = transposed_conv(model, 128, ksize=5, stride_size=2)\n    model = transposed_conv(model, 64, ksize=5, stride_size=2)\n    model = transposed_conv(model, 32, ksize=5, stride_size=2)\n    \n    model.add(Dense(3, activation='tanh', kernel_initializer=weight_initializer))\n\n    return model\n\ndog_generator = DogGenerator()\ndog_generator.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def DogDiscriminator():\n    model = Sequential()\n    model.add(Conv2D(64, (5, 5), strides=(1,1), padding='same', use_bias=False,\n                     input_shape=[image_height, image_width, image_channels], \n                     kernel_initializer=weight_initializer))\n    model.add(LeakyReLU(alpha=0.2))\n\n    model = convSN(model, 64, ksize=5, stride_size=2)\n    model = convSN(model, 128, ksize=5, stride_size=2)\n    model = convSN(model, 256, ksize=5, stride_size=2)\n    model.add(Dropout(0.2))\n    model = convSN(model, 512, ksize=5, stride_size=2)\n    model.add(Dropout(0.2))\n\n    model.add(Flatten())\n    model.add(Dense(1, activation='sigmoid'))\n    return model\n\ndog_discriminator = DogDiscriminator()\ndog_discriminator.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n\ndef discriminator_loss(real_output, fake_output): \n        real_loss = cross_entropy(tf.ones_like(real_output), real_output)\n        fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)\n        loss = fake_loss + real_loss\n        return loss\n    \ndef generator_loss(fake_output):\n    return cross_entropy(tf.ones_like(fake_output), fake_output)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"generator_optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=0.0002, beta1=0.5)\ndiscriminator_optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=0.0002, beta1=0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 250\nnum_examples_to_generate = 1000\n\nnoise_dim = 128\nbatch_size = 32","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_step(images):\n    noise = tf.random.normal([batch_size, noise_dim])\n\n    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:\n        generated_images = dog_generator(noise, training = True)\n        \n        real_output = dog_discriminator(images, training = True)\n        fake_output = dog_discriminator(generated_images, training = True)\n        \n        gen_loss = generator_loss(fake_output)\n        disc_loss = discriminator_loss(real_output, fake_output)\n \n    gradients_of_generator = gen_tape.gradient(gen_loss, dog_generator.trainable_variables)\n    gradients_of_discriminator = disc_tape.gradient(disc_loss, dog_discriminator.trainable_variables)\n    \n\n    generator_optimizer.apply_gradients(zip(gradients_of_generator, dog_generator.trainable_variables))\n    discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, dog_discriminator.trainable_variables))\n    \n    return gen_loss, disc_loss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import time\nfrom tqdm import tqdm\n\ndecay_step = 25\n\ndef decayed_learning_rate(lr, step, alpha = 0.1):\n  step = min(step, decay_step)\n  cosine_decay = 0.5 * (1 + cos(pi * step / decay_step))\n  decayed = (1 - alpha) * cosine_decay + alpha\n  return lr * decayed\n\ndef train(dataset, epochs):\n    all_gl = np.array([]); all_dl = np.array([])\n    for epoch in tqdm(range(epochs)):\n        \n        G_loss = []; D_loss = []\n        \n        start = time.time()\n        new_lr_d = new_lr_g = 0.0002\n        global_step = 0\n        np.random.seed(seed=int(time.perf_counter()))\n        \n        for image_batch in dataset:\n            g_loss, d_loss = train_step(image_batch)\n            global_step = global_step + 1\n            G_loss.append(g_loss); D_loss.append(d_loss)\n            all_gl = np.append(all_gl,np.array([G_loss]))\n            all_dl = np.append(all_dl,np.array([D_loss]))\n        \n        # Cosine learning rate decay\n        if (epoch + 1) % decay_step == 0:\n            new_lr_d = decayed_learning_rate(new_lr_d, global_step)\n            new_lr_g = decayed_learning_rate(new_lr_g, global_step)\n            generator_optimizer = tf.train.AdamOptimizer(learning_rate=new_lr_d, beta1=0.5)\n            discriminator_optimizer = tf.train.AdamOptimizer(learning_rate=new_lr_g, beta1=0.5)          \n\n        print('Epoch: {} computed for {} sec'.format(epoch + 1, time.time() - start))\n        print('Gen_loss mean: ', np.mean(G_loss),' std: ', np.std(G_loss))\n        print('Disc_loss mean: ', np.mean(D_loss),' std: ', np.std(D_loss))\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"dog_discriminator.compile(loss='binary_crossentropy',\n    optimizer=generator_optimizer,\n    metrics=['accuracy'])\n\ndog_generator.compile(loss='binary_crossentropy', optimizer=discriminator_optimizer)\n\ntrain(batches, epochs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nz = zipfile.PyZipFile('images.zip', mode='w')\nfor k in range(num_examples_to_generate):\n    generated_image = dog_generator(tf.random.normal([1, noise_dim]), training=False)\n    f = str(k)+'.png'\n    img = np.array(generated_image)\n    img = (img[0, :, :, :] + 1.) / 2.\n    img = Image.fromarray((255*img).astype('uint8').reshape((image_height,image_width,image_channels)))\n    img.save(f,'PNG')\n    z.write(f)\n    os.remove(f)\nz.close()\nprint('Saved final images for submission.')\n","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}