{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport os \nimport tensorflow as tf \nimport matplotlib.pyplot as plt\nimport cv2\nimport glob\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport keras\nfrom keras.optimizers import Adam\nfrom keras.models import Sequential, Model\nfrom keras.layers import Dense, LeakyReLU, BatchNormalization, Reshape, Flatten, Input\nfrom keras.layers import Conv2D, MaxPooling2D, Activation, Dropout, Conv2DTranspose","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def list_images(basePath, contains=None):\n    # return the set of files that are valid\n    return list_files(basePath, validExts=(\".jpg\", \".jpeg\", \".png\", \".bmp\"), contains=contains)\n\ndef list_files(basePath, validExts=(\".jpg\", \".jpeg\", \".png\", \".bmp\"), contains=None):\n    # loop over the directory structure\n    for (rootDir, dirNames, filenames) in os.walk(basePath):\n        # loop over the filenames in the current directory\n        for filename in filenames:\n            # if the contains string is not none and the filename does not contain\n            # the supplied string, then ignore the file\n            if contains is not None and filename.find(contains) == -1:\n                continue\n\n            # determine the file extension of the current file\n            ext = filename[filename.rfind(\".\"):].lower()\n\n            # check to see if the file is an image and should be processed\n            if ext.endswith(validExts):\n                # construct the path to the image and yield it\n                imagePath = os.path.join(rootDir, filename).replace(\" \", \"\\\\ \")\n                yield imagePath\n                \ndef load_images(directory='', size=(64,64)):\n    images = []\n    labels = []  # Integers corresponding to the categories in alphabetical order\n    label = 0\n    \n    imagePaths = list(list_images(directory))\n    \n    for path in imagePaths:\n        \n        if not('OSX' in path):\n        \n            path = path.replace('\\\\','/')\n\n            image = cv2.imread(path) #Reading the image with OpenCV\n            image = cv2.resize(image,size) #Resizing the image, in case some are not of the same size\n\n            images.append(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n    \n    return images","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images=load_images('../input', size = (64,64))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"_,ax = plt.subplots(3,3, figsize = (15,15)) \nfor i in range(3):\n    for j in range(3):\n        ax[i,j].imshow(images[5*i+j])\n        ax[i,j].axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class GAN():\n    def __init__(self):\n        self.img_shape = (64, 64, 3)\n        \n        self.noise_size = 100\n\n        optimizer = Adam(0.0002,0.5)\n\n        self.discriminator = self.build_discriminator()\n        self.discriminator.compile(loss='binary_crossentropy', \n                                   optimizer=optimizer,\n                                   metrics=['accuracy'])\n\n        self.generator = self.build_generator()\n        self.generator.compile(loss='binary_crossentropy', optimizer=optimizer)\n        \n        self.combined = Sequential()\n        self.combined.add(self.generator)\n        self.combined.add(self.discriminator)\n        \n        self.discriminator.trainable = False\n        \n        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)\n        \n        self.combined.summary()\n        \n    # Creating the generator, the large kernels in the convolutional layers allow the network to create complex structures.\n    def build_generator(self):\n        epsilon = 0.00001 # Small float added to variance to avoid dividing by zero in the BatchNorm layers.\n        noise_shape = (self.noise_size,)\n        \n        model = Sequential()\n        \n        model.add(Dense(4*4*512, activation='linear', input_shape=noise_shape))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(Reshape((4, 4, 512)))\n        \n        model.add(Conv2DTranspose(512, kernel_size=[5,5], strides=[2,2], padding=\"same\",\n                                  kernel_initializer= keras.initializers.TruncatedNormal(stddev=0.02)))\n        model.add(BatchNormalization(momentum=0.9, epsilon=epsilon))\n        model.add(LeakyReLU(alpha=0.2))\n        \n        model.add(Conv2DTranspose(256, kernel_size=[5,5], strides=[2,2], padding=\"same\",\n                                  kernel_initializer= keras.initializers.TruncatedNormal(stddev=0.02)))\n        model.add(BatchNormalization(momentum=0.9, epsilon=epsilon))\n        model.add(LeakyReLU(alpha=0.2))\n        \n        model.add(Conv2DTranspose(128, kernel_size=[5,5], strides=[2,2], padding=\"same\",\n                                  kernel_initializer= keras.initializers.TruncatedNormal(stddev=0.02)))\n        model.add(BatchNormalization(momentum=0.9, epsilon=epsilon))\n        model.add(LeakyReLU(alpha=0.2))\n        \n        model.add(Conv2DTranspose(64, kernel_size=[5,5], strides=[2,2], padding=\"same\",\n                                  kernel_initializer= keras.initializers.TruncatedNormal(stddev=0.02)))\n        model.add(BatchNormalization(momentum=0.9, epsilon=epsilon))\n        model.add(LeakyReLU(alpha=0.2))\n        \n        model.add(Conv2DTranspose(3, kernel_size=[5,5], strides=[1,1], padding=\"same\",\n                                  kernel_initializer= keras.initializers.TruncatedNormal(stddev=0.02)))\n\n        # Standard activation for the generator of a GAN\n        model.add(Activation(\"tanh\"))\n        \n        model.summary()\n\n        noise = Input(shape=noise_shape)\n        img = model(noise)\n\n        return Model(noise, img)\n\n    def build_discriminator(self):\n\n        model = Sequential()\n\n        model.add(Conv2D(64, (3,3), padding='same', input_shape=self.img_shape))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(BatchNormalization())\n        model.add(Conv2D(64, (3,3), padding='same'))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(BatchNormalization())\n        model.add(MaxPooling2D(pool_size=(3,3)))\n        model.add(Dropout(0.2))\n\n        model.add(Conv2D(128, (3,3), padding='same'))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(BatchNormalization())\n        model.add(Conv2D(128, (3,3), padding='same'))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(BatchNormalization())\n        model.add(MaxPooling2D(pool_size=(3,3)))\n        model.add(Dropout(0.3))\n\n        model.add(Flatten())\n        model.add(Dense(128))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(Dense(128))\n        model.add(LeakyReLU(alpha=0.2))\n        model.add(Dense(1, activation='sigmoid'))\n        \n        model.summary()\n        \n        img = Input(shape=self.img_shape)\n        validity = model(img)\n\n        return Model(img, validity)\n\n    def train(self, epochs, batch_size=128, save_images=100, save_model=2000):\n\n        X_train = np.array(images)\n        X_train = (X_train.astype(np.float32) - 127.5) / 127.5\n\n        half_batch = int(batch_size / 2)\n\n        for epoch in range(epochs):\n            idx = np.random.randint(0, X_train.shape[0], half_batch)\n            imgs = X_train[idx]\n\n            noise = np.random.normal(0, 1, (half_batch, self.noise_size))\n            gen_imgs = self.generator.predict(noise)\n\n            # Training the discriminator\n            \n            # The loss of the discriminator is the mean of the losses while training on authentic and fake images\n            d_loss = 0.5 * np.add(self.discriminator.train_on_batch(imgs, np.ones((half_batch, 1))),\n                                  self.discriminator.train_on_batch(gen_imgs, np.zeros((half_batch, 1))))\n\n            # Training the generator\n\n            noise = np.random.normal(0, 1, (batch_size, self.noise_size))\n\n            valid_y = np.array([1] * batch_size)\n            g_loss = self.combined.train_on_batch(noise, valid_y)\n            \n            \n            # We print the losses and accuracy of the networks every 10 batches mainly to make sure the accuracy of the discriminator\n            # is not stable at around 50% or 100% (which would mean the discriminator performs not well enough or too well)\n            if epoch % 30 == 0:\n              print (\"%d [Discriminator loss: %f, acc.: %.2f%%] [Generator loss: %f]\" % (epoch, d_loss[0], 100*d_loss[1], g_loss))\n\n            if epoch % save_images == 0:\n                self.save_images(epoch)\n            \n            # We save the architecture of the model, the weights and the state of the optimizer\n            # This way we can restart the training exactly where we stopped\n            if epoch % save_model == 0:\n                self.generator.save(\"generator_%d\" % epoch)\n                self.discriminator.save(\"discriminator_%d\" % epoch)\n\n    # Saving 25 generated images to have a representation of the spectrum of images created by the generator\n    def save_images(self, epoch):\n        noise = np.random.normal(0, 1, (25, self.noise_size))\n        gen_imgs = self.generator.predict(noise)\n        \n        # Rescale from [-1,1] into [0,1]\n        gen_imgs = 0.5 * gen_imgs + 0.5\n\n        fig, axs = plt.subplots(5,5, figsize = (8,8))\n        c = 0\n        for i in range(5):\n            for j in range(5):\n                axs[i,j].imshow(gen_imgs[c])\n                axs[i,j].axis('off')\n                c += 1\n\n        plt.show()\n        \n        fig.savefig(\"Generated/Dogs_%d.png\" % epoch)\n        plt.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir Generated","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gan = GAN()\ngan.train(epochs = 20001, batch_size = 128, save_images=500, save_model=100000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import zipfile\nfrom PIL import Image\n\nz = zipfile.PyZipFile('images.zip', mode='w')\n\nfor k in range(10000):\n    # GENERATE NEW DOGS\n    noise = np.random.normal(0, 1, (1, 100))\n    img = gan.generator.predict(noise)\n    # Rescale from [-1,1] into [0,1]\n    img = 0.5 * img + 0.5\n    img = Image.fromarray( (255*img).astype('uint8').reshape((64,64,3)))\n    # SAVE TO ZIP FILE  \n    f = str(k)+'.png'\n    img.save(f,'PNG'); z.write(f); os.remove(f)\n    #if k % 1000==0: print(k)\nz.close()","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":1}