{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom scipy.stats import describe\nimport matplotlib.pyplot as plt\nfrom keras.layers import Input, Dense, Reshape, Flatten, Dropout, BatchNormalization, Activation, ZeroPadding2D, LeakyReLU, UpSampling2D, Conv2D\nfrom keras.models import Sequential, Model\nfrom keras.optimizers import Adam, SGD\nfrom keras.preprocessing.image import img_to_array, load_img, save_img, ImageDataGenerator\nimport xml.etree.ElementTree as ET # for parsing XML\nimport glob\nfrom tqdm import tqdm_notebook as tqdm\nimport os\nSHAPE = (64, 64, 3)\nBATCH_SIZE = 128","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nxmls = glob.glob(\"../input/annotation/Annotation/*/*\")\ntrain_data = []\nfor x in tqdm(xmls):\n    tree = ET.parse(x)\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        image_filename = \"../input/all-dogs/all-dogs/\" + tree.find(\"filename\").text + \".jpg\"\n        try:\n            image = load_img(image_filename)\n            image = img_to_array(image.crop((xmin,ymin,xmax,ymax)).resize(SHAPE[:2])) / 255\n            train_data.append(image)\n        except:\n            continue\nprint(len(train_data))\ntrain_data = np.stack(train_data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(25, 16))\nfor i, im in enumerate(train_data[:10]):\n    ax = fig.add_subplot(5, 10, i + 1)\n    plt.imshow(im)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = train_data * 2 - 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DCGAN():\n    def __init__(self, image_shape, generator_input_dim, img_channels, debug=False):\n        optimizer = Adam(0.0002, 0.5)\n        \n        self.img_shape = image_shape\n        self.generator_input_dim = generator_input_dim\n        self.channels = img_channels\n        self.history = []\n        self.debug = debug\n\n        # Build models\n        self._build_generator_model()\n        self._build_and_compile_discriminator_model(optimizer)\n        self._build_and_compile_gan(optimizer)\n\n    def train(self, epochs, train_data, batch_size):\n        \n        real = np.ones((batch_size, 1))\n        fake = np.zeros((batch_size, 1))\n        for epoch in tqdm(range(epochs)):\n            #  Train Discriminator\n            batch_indexes = np.random.randint(0, train_data.shape[0], batch_size)\n            batch = train_data[batch_indexes]\n            generated = self._predict_noise(batch_size)\n            loss_real = self.discriminator_model.train_on_batch(batch, real)\n            loss_fake = self.discriminator_model.train_on_batch(generated, fake)\n            discriminator_loss = 0.5 * np.add(loss_real, loss_fake)\n\n            #  Train Generator\n            noise = np.random.normal(0, 1, (batch_size, self.generator_input_dim))\n            generator_loss = self.gan.train_on_batch(noise, real)\n            \n            if epoch > 0 and epoch % 100 == 0 and self.debug:\n                print (\"---------------------------------------------------------\")\n                print (\"******************Epoch {}***************************\".format(epoch))\n                print (\"Discriminator loss: {}\".format(discriminator_loss[0]))\n                print (\"Generator loss: {}\".format(generator_loss))\n                print (\"---------------------------------------------------------\")\n                sample = self.gen(1)[0]\n                plt.imshow(sample)\n                plt.show()\n                self.plot_loss()\n            \n            self.history.append({\"D\":discriminator_loss[0],\"G\":generator_loss})\n    \n    def _build_generator_model(self):\n        generator_input = Input(shape=(self.generator_input_dim,))\n        generator_sequence = Sequential(\n                [Dense(128 * 16 * 16, activation=\"relu\", input_dim=self.generator_input_dim),\n                 Reshape((16, 16, 128)),\n                 UpSampling2D(),\n                 Conv2D(128, kernel_size=3, padding=\"same\"),\n                 BatchNormalization(momentum=0.8),\n                 LeakyReLU(alpha=0.2),\n                 UpSampling2D(),\n                 Conv2D(64, kernel_size=3, padding=\"same\"),\n                 BatchNormalization(momentum=0.8),\n                 LeakyReLU(alpha=0.2),\n                 Conv2D(self.channels, kernel_size=3, padding=\"same\"),\n                 Activation(\"tanh\")])\n    \n        generator_output_tensor = generator_sequence(generator_input)\n        self.generator_model = Model(generator_input, generator_output_tensor)\n        \n    def _build_and_compile_discriminator_model(self, optimizer):\n        discriminator_input = Input(shape=self.img_shape)\n        discriminator_sequence = Sequential(\n                [Conv2D(32, kernel_size=3, strides=2, input_shape=self.img_shape, padding=\"same\"),\n                 LeakyReLU(alpha=0.2),\n                 Dropout(0.25),\n                 Conv2D(64, kernel_size=3, strides=2, padding=\"same\"),\n                 ZeroPadding2D(padding=((0,1),(0,1))),\n                 BatchNormalization(momentum=0.8),\n                 LeakyReLU(alpha=0.2),\n                 Dropout(0.25),\n                 Conv2D(128, kernel_size=3, strides=2, padding=\"same\"),\n                 BatchNormalization(momentum=0.8),\n                 LeakyReLU(alpha=0.2),\n                 Dropout(0.25),\n                 Conv2D(256, kernel_size=3, strides=2, padding=\"same\"),\n                 BatchNormalization(momentum=0.8),\n                 LeakyReLU(alpha=0.2),\n                 Dropout(0.25),\n                 Flatten(),\n                 Dense(1, activation='sigmoid')])\n    \n        discriminator_tensor = discriminator_sequence(discriminator_input)\n        self.discriminator_model = Model(discriminator_input, discriminator_tensor)\n        self.discriminator_model.compile(loss='binary_crossentropy',\n            optimizer=\"Adam\",\n            metrics=['accuracy'])\n        self.discriminator_model.trainable = False\n    \n    def _build_and_compile_gan(self, optimizer):\n        real_input = Input(shape=(self.generator_input_dim,))\n        generator_output = self.generator_model(real_input)\n        discriminator_output = self.discriminator_model(generator_output)        \n        \n        self.gan = Model(real_input, discriminator_output)\n        self.gan.compile(loss='binary_crossentropy', optimizer=optimizer)\n    \n    def _predict_noise(self, size):\n        noise = np.random.normal(0, 1, (size, self.generator_input_dim))\n        return self.generator_model.predict(noise)\n        \n    def gen(self, size):\n        generated = self._predict_noise(size)\n        generated = 0.5 * generated + 0.5\n        return generated\n\n    def plot_loss(self):\n        hist = pd.DataFrame(self.history)\n        plt.figure(figsize=(20,5))\n        for colnm in hist.columns:\n            plt.plot(hist[colnm],label=colnm)\n        plt.legend()\n        plt.ylabel(\"loss\")\n        plt.xlabel(\"epochs\")\n        plt.show()\n\ngan = DCGAN(SHAPE, 100, SHAPE[2], debug=0)\ngan.train(epochs = 20000, train_data = train_data, batch_size=BATCH_SIZE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gan.plot_loss()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ngens = gan.gen(10000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(25, 16))\nfor i in range(20):\n    ax = fig.add_subplot(10, 10, i + 1)\n    plt.imshow(gens[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists('../output_images'):\n    os.mkdir('../output_images')\n\nfor i in tqdm(range(len(gens))):\n    save_img(\"../output_images/{}.png\".format(i), gens[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import 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}