{"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 glob import glob\nfrom PIL import Image\nfrom tqdm import tqdm_notebook as tqdm\nimport gc, os\nimport xml.etree.ElementTree as ET \nimport matplotlib.pyplot as plt, zipfile\n%matplotlib inline\n\nfrom keras.models import Sequential, Model\nfrom keras.layers import Dense, Conv2D, Conv2DTranspose, Flatten, Dropout, LeakyReLU, Reshape, Input, BatchNormalization, ReLU, GlobalAveragePooling2D\nfrom keras.optimizers import Adam, SGD\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.initializers import RandomNormal, TruncatedNormal","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# manually change to True to execute this cell\n# this has been added to prevent the commit to execute this line, since it executes the whole notebook\nif False:\n    root_images = \"../input/generative-dog-images/all-dogs/all-dogs/\"\n    root_annots = \"../input/generative-dog-images/annotation/Annotation/\"\n    INPUT_DATA_DIR = \"../input/generative-dog-images/all-dogs/all-dogs/\"\n    IMG_DIR = \"images\"\n    ComputeLB = False\n    DogsOnly = True\n\n\n    ROOT = '../input/generative-dog-images/'\n    if not ComputeLB: ROOT = '../input/'\n    IMAGES = os.listdir(ROOT + 'all-dogs/all-dogs/')\n    breeds = os.listdir(ROOT + 'annotation/Annotation/') \n\n    idxIn = 0; namesIn = []\n    imagesIn = np.zeros((25000,64,64,3))\n\n    # CROP WITH BOUNDING BOXES TO GET DOGS ONLY\n    # https://www.kaggle.com/paulorzp/show-annotations-and-breeds\n    if DogsOnly:\n        for breed in breeds:\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                tree = ET.parse(ROOT+'annotation/Annotation/'+breed+'/'+dog)\n                root = tree.getroot()\n                objects = root.findall('object')\n                for o in objects:\n                    bndbox = o.find('bndbox') \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                    img2 = img.crop((xmin, ymin, xmin+w, ymin+w))\n                    img2 = img2.resize((64,64), Image.ANTIALIAS)\n                    imagesIn[idxIn,:,:,:] = np.asarray(img2)\n                    #if idxIn%1000==0: print(idxIn)\n                    namesIn.append(breed)\n                    idxIn += 1\n        idx = np.arange(idxIn)\n        np.random.shuffle(idx)\n        imagesIn = imagesIn[idx,:,:,:]\n        namesIn = np.array(namesIn)[idx]\n\n\n    # DISPLAY CROPPED IMAGES\n    x = np.random.randint(0,idxIn,25)\n    for k in range(5):\n        plt.figure(figsize=(15,3))\n        for j in range(5):\n            plt.subplot(1,5,j+1)\n            img = Image.fromarray( imagesIn[x[k*5+j],:,:,:].astype('uint8') )\n            plt.axis('off')\n            if not DogsOnly: plt.title(namesIn[x[k*5+j]],fontsize=11)\n            else: plt.title(namesIn[x[k*5+j]].split('-')[1],fontsize=11)\n            plt.imshow(img)\n        plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# imgs = (imagesIn/127.5)-1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"files = None\nimgs = None\ngc.collect()\nfiles = glob('../input/all-dogs/all-dogs/*.jpg')\n# need to split this\nimgs = np.array([-1 + np.dot(2, np.array(Image.open(file).resize((64,64))).astype('float32')) / 255 for file in tqdm(files)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def encode_img(X):\n    return -1 + np.dot(2, X) / 255\n    \ndef decode_img(X):\n    return (np.dot(X + 1, 255) / 2).astype('uint8')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_gen = ImageDataGenerator(\n    rotation_range=10,\n    # width_shift_range=0.1,\n    # height_shift_range=0.1,\n    horizontal_flip=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_real_samples(n_samples, size=(64, 64)):\n    # choose random instances\n    # ix = np.random.randint(0, len(files), n_samples)\n    ix = np.random.randint(0, imgs.shape[0], n_samples)\n    # retrieve selected images\n    # X = np.array([encode_img(data_gen.random_transform(np.array(Image.open(files[i]).resize(size)))) for i in ix])\n    X = imgs[ix]\n    # generate 'real' class labels (1)\n    y = np.ones((n_samples, 1))\n    # y = np.random.uniform(0.9, 1, size=(n_samples, 1))\n    return X, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(decode_img(generate_real_samples(1)[0][0]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# generate points in latent space as input for the generator\ndef generate_latent_points(latent_dim, n_samples):\n    # generate points in the latent space\n    # x_input = np.random.randn(latent_dim * n_samples)\n    # reshape into a batch of inputs for the network\n    # x_input = x_input.reshape(n_samples, latent_dim)\n    x_input = np.random.randn(n_samples, latent_dim)\n    return x_input","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# use the generator to generate n fake examples, with class labels\ndef generate_fake_samples(generator, latent_dim, n_samples):\n    # generate points in latent space\n    x_input = generate_latent_points(latent_dim, n_samples)\n    # predict outputs\n    X = generator.predict(x_input)\n    # create 'fake' class labels (0)\n    y = np.zeros((n_samples, 1)) \n    # y = np.random.uniform(0, 0.1, size=(n_samples, 1))\n    return X, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def define_generator(inp, n_filters=64, size=(64, 64)):\n    initializer = TruncatedNormal(mean=0.0, stddev=0.02)\n    kernel_size = 4\n    batchnorm = BatchNormalization(epsilon=0.0005)\n    activation = LeakyReLU(alpha=0.2)\n    \n    adaptative_mode = False\n    if adaptative_mode:\n        print(\"generator size: {}\".format(size))\n        r = size[0]//2**6\n        print(r)\n        n_nodes = r * r * n_filters\n        #x = Dense(n_nodes)(inp)\n        #x = LeakyReLU(alpha=0.2)(x)\n        #x = Dropout(0.5)(x)\n        #x = Reshape((8, 8, N_FILTERS))(x)\n        \n        x = Flatten()(inp)\n        x = Dense(n_nodes)(x)\n        x = ReLU()(x)\n        x = Reshape((r, r, n_filters))(x)\n    else:\n        # x = inp\n        x = Dense(4 * 4 * 512)(inp)\n        x = Reshape((4, 4, 512))(x)\n        # x = LeakyReLU(alpha=0.2)(x)\n    \n    x = Conv2DTranspose(n_filters * 8, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    x = ReLU()(x)\n    x = BatchNormalization(momentum=0.1, epsilon=0.0005)(x)\n    \n    x = Conv2DTranspose(n_filters * 4, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    x = ReLU()(x)\n    x = BatchNormalization(momentum=0.1, epsilon=0.0005)(x)\n    \n    x = Conv2DTranspose(n_filters * 2, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    x = ReLU()(x)\n    x = BatchNormalization(momentum=0.1, epsilon=0.0005)(x)\n    \n    x = Conv2DTranspose(n_filters, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    x = ReLU()(x)\n    x = BatchNormalization(momentum=0.1, epsilon=0.0005)(x)\n    \n    out = Conv2D(3, kernel_size, strides=1, activation='tanh', padding='same', kernel_initializer=initializer)(x)\n    \n    '''\n    x = Conv2DTranspose(N_FILTERS, (3,3), strides=(2,2), padding='same')(x)\n    x = LeakyReLU(alpha=0.2)(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.5)(x)\n    '''\n    \n    # out = Conv2D(3, (5, 5), activation='sigmoid', padding='same')(x)\n    return out","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def define_discriminator(inp, n_filters=64):\n    initializer = TruncatedNormal(mean=0.0, stddev=0.02)\n    kernel_size = 4\n    batchnorm = BatchNormalization(epsilon=0.0005)\n    activation = LeakyReLU(alpha=0.2)\n    \n    x = Conv2D(n_filters, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(inp)\n    #\n    x = LeakyReLU(alpha=0.2)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    #x = Dropout(0.25)(x)\n    \n    x = Conv2D(n_filters * 2, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    x = LeakyReLU(alpha=0.2)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    # x = Dropout(0.25)(x)\n    \n    x = Conv2D(n_filters * 4, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    x = LeakyReLU(alpha=0.2)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    # x = Dropout(0.25)(x)\n    \n    x = Conv2D(n_filters * 8, kernel_size, strides=1, padding='same', kernel_initializer=initializer)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    x = LeakyReLU(alpha=0.2)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    # x = Dropout(0.25)(x)\n    \n    x = Conv2D(n_filters * 16, kernel_size, strides=2, padding='same', kernel_initializer=initializer)(x)\n    #x = BatchNormalization(epsilon=0.0005)(x)\n    # x = LeakyReLU(alpha=0.2)(x)\n    # x = GlobalAveragePooling2D()(x)\n    x = Flatten()(x)\n    x = Dense(1, activation='sigmoid')(x)\n    \n    return x\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_models(latent_dim=100, in_shape=(64, 64, 3), base_num_filters=64):\n    opt_G = Adam(lr=2e-4, beta_1=0.5)\n    opt_D = Adam(lr=5e-4, beta_1=0.5)\n    #opt_D = SGD(lr=5*1e-3, decay=1e-3)\n    \n    disc_inp = Input(shape=in_shape)\n    disc_out = define_discriminator(disc_inp, n_filters=base_num_filters)\n    discriminator = Model(inputs=disc_inp, outputs=disc_out)\n    discriminator.compile(loss='binary_crossentropy', optimizer=opt_D, metrics=['accuracy'])\n    \n    discriminator.trainable = False\n    \n    gen_inp = Input(shape=(latent_dim,))\n    gen_out = define_generator(gen_inp, n_filters=base_num_filters, size=(in_shape[0], in_shape[1]))\n    generator = Model(inputs=gen_inp, outputs=gen_out)\n    \n    gan = Sequential()\n    gan.add(generator)\n    gan.add(discriminator)\n    gan.compile(loss='binary_crossentropy', optimizer=opt_G, metrics=['accuracy'])\n    \n    return discriminator, generator, gan","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train the generator and discriminator\ndef train(generator, discriminator, gan, latent_dim, n_epochs=100, batch_size=256, size=(64, 64)):\n    # bat_per_epo = int(len(files) / batch_size)\n    bat_per_epo = int(imgs.shape[0] / batch_size)\n    half_batch = int(batch_size / 2)\n    # manually enumerate epochs\n    for i in range(n_epochs):\n        # enumerate batches over the training set\n        # print(\"epoch {}\".format(i))\n        for j in tqdm(range(bat_per_epo)):\n            # get randomly selected 'real' samples\n            X_real, y_real = generate_real_samples(half_batch, size)\n            # generate 'fake' examples\n            X_fake, y_fake = generate_fake_samples(generator, latent_dim, half_batch)\n            # create training set for the discriminator\n            X, y = np.vstack((X_real, X_fake)), np.vstack((y_real, y_fake))\n            # update discriminator model weights\n            d_loss, _ = discriminator.train_on_batch(X, y)\n            # prepare points in latent space as input for the generator\n            X_gan = generate_latent_points(latent_dim, batch_size)\n            # create inverted labels for the fake samples\n            y_gan = np.ones((batch_size, 1))\n            # update the generator via the discriminator's error\n            g_loss, _ = gan.train_on_batch(X_gan, y_gan)\n            # summarize loss on this batch\n        # evaluate the model performance, sometimes\n        if (i+1) % 1 == 0:\n            summarize_performance(i, generator, discriminator, latent_dim, size=size)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# evaluate the discriminator, plot generated images, save generator model\ndef summarize_performance(epoch, generator, discriminator, latent_dim, n_samples=200, size=(64, 64)):\n    # prepare real samples\n    X_real, y_real = generate_real_samples(n_samples, size)\n    # evaluate discriminator on real examples\n    val_real, acc_real = discriminator.evaluate(X_real, y_real, verbose=0)\n    # prepare fake examples\n    x_fake, y_fake = generate_fake_samples(generator, latent_dim, n_samples)\n    # evaluate discriminator on fake examples\n    val_fake, acc_fake = discriminator.evaluate(x_fake, y_fake, verbose=0)\n    # summarize discriminator performance\n    print('>Epoch {}. Loss real: {}, fake: {}. Accuracy real: {}, fake: {}'.format(epoch, val_real, val_fake, acc_real*100, acc_fake*100))\n    # save plot\n    save_plot(x_fake, epoch)\n    # save the generator model tile file\n    filename = 'generator_model_%03d.h5' % (epoch + 1)\n    generator.save(filename)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create and save a plot of generated images (reversed grayscale)\ndef save_plot(examples, epoch, n=10):\n    # plot images\n    for i in range(n * n):\n        # define subplot\n        plt.subplot(n, n, 1 + i)\n        # turn off axis\n        plt.axis('off')\n        # plot raw pixel data\n        plt.imshow(decode_img(examples[i]))\n    # save plot to file\n    filename = 'generated_plot_e%03d.png' % (epoch+1)\n    plt.savefig(filename)\n    plt.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"latent_dim = 128\nsize = (64, 64)\ndiscriminator, generator, gan = build_models(latent_dim, in_shape=(size[0], size[1], 3), base_num_filters=32)\ngenerator.summary()\ndiscriminator.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# training process\nfor i in range(100):\n    train(generator, discriminator, gan, latent_dim, size=size, n_epochs=1, batch_size=64)\n    # generate samples\n    n_samples = 10\n    X, _ = generate_fake_samples(generator, latent_dim, n_samples)\n    fig = plt.figure(figsize=(24, 24))\n    # plot the generated samples\n    for i in range(10):\n        ax = fig.add_subplot(1, 10, i + 1, xticks=[], yticks=[])\n        plt.imshow(decode_img(X[i]))\n    # show the figure\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"# generate samples\nn_samples = 25\nX, _ = generate_fake_samples(generator, latent_dim, n_samples)\n# plot the generated samples\nfor i in range(n_samples):\n    # define subplot\n    plt.subplot(5, 5, 1 + i)\n    # turn off axis labels\n    plt.axis('off')\n    # plot single image\n    plt.imshow(decode_img(X[i]))\n# show the figure\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}