{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport os\nimport tensorflow as tf\nimport tensorflow_addons as tfa\nfrom tensorflow import keras\nfrom tensorflow.keras import layers","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-03-22T19:38:52.433115Z","iopub.execute_input":"2023-03-22T19:38:52.433754Z","iopub.status.idle":"2023-03-22T19:39:01.894754Z","shell.execute_reply.started":"2023-03-22T19:38:52.433714Z","shell.execute_reply":"2023-03-22T19:39:01.893625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_pics_path = tf.io.gfile.glob(\"/kaggle/input/gan-getting-started/monet_tfrec/*.tfrec\")\nphoto_pics_path = tf.io.gfile.glob(\"/kaggle/input/gan-getting-started/photo_tfrec/*.tfrec\")\nimage_shape = [256,256]","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:01.896830Z","iopub.execute_input":"2023-03-22T19:39:01.897639Z","iopub.status.idle":"2023-03-22T19:39:01.918304Z","shell.execute_reply.started":"2023-03-22T19:39:01.897599Z","shell.execute_reply":"2023-03-22T19:39:01.917417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_pics_path","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:01.919366Z","iopub.execute_input":"2023-03-22T19:39:01.919660Z","iopub.status.idle":"2023-03-22T19:39:01.928712Z","shell.execute_reply.started":"2023-03-22T19:39:01.919634Z","shell.execute_reply":"2023-03-22T19:39:01.927641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features = {\"image\":tf.io.FixedLenFeature([],tf.string)} # configire the parsing one into fixed lenght\ndef read_tfrecord(images):\n    image_data = tf.io.parse_single_example(images,features) # serlize the data\n    image = image_data[\"image\"]\n    image = tf.image.decode_jpeg(image,channels=3)\n    image = (tf.cast(image,tf.float32)/127.5) - 1\n    image = tf.reshape(image,[*image_shape,3])\n    return image","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:01.931469Z","iopub.execute_input":"2023-03-22T19:39:01.932262Z","iopub.status.idle":"2023-03-22T19:39:01.939845Z","shell.execute_reply.started":"2023-03-22T19:39:01.932224Z","shell.execute_reply":"2023-03-22T19:39:01.938681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"AUTOTUNE = tf.data.experimental.AUTOTUNE\nmonet_dataset = tf.data.TFRecordDataset(monet_pics_path).map(read_tfrecord, num_parallel_calls=AUTOTUNE).batch(1)\nphoto_dataset = tf.data.TFRecordDataset(photo_pics_path).map(read_tfrecord, num_parallel_calls=AUTOTUNE).batch(1)","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:01.941293Z","iopub.execute_input":"2023-03-22T19:39:01.941867Z","iopub.status.idle":"2023-03-22T19:39:04.940426Z","shell.execute_reply.started":"2023-03-22T19:39:01.941832Z","shell.execute_reply":"2023-03-22T19:39:04.939417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# TO check number of images\nprint( len(list(iter(monet_dataset))))\nprint( len(list(iter(photo_dataset))))","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:04.942113Z","iopub.execute_input":"2023-03-22T19:39:04.942491Z","iopub.status.idle":"2023-03-22T19:39:22.902329Z","shell.execute_reply.started":"2023-03-22T19:39:04.942453Z","shell.execute_reply":"2023-03-22T19:39:22.901213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"something = next(iter(monet_dataset))\nsomething.shape","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:22.904332Z","iopub.execute_input":"2023-03-22T19:39:22.904733Z","iopub.status.idle":"2023-03-22T19:39:22.931357Z","shell.execute_reply.started":"2023-03-22T19:39:22.904695Z","shell.execute_reply":"2023-03-22T19:39:22.930325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"something = next(iter(monet_dataset))\nsomething.shape","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:22.932715Z","iopub.execute_input":"2023-03-22T19:39:22.933050Z","iopub.status.idle":"2023-03-22T19:39:22.958587Z","shell.execute_reply.started":"2023-03-22T19:39:22.933016Z","shell.execute_reply":"2023-03-22T19:39:22.957670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_addons as tfa\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:22.960352Z","iopub.execute_input":"2023-03-22T19:39:22.960710Z","iopub.status.idle":"2023-03-22T19:39:22.966507Z","shell.execute_reply.started":"2023-03-22T19:39:22.960675Z","shell.execute_reply":"2023-03-22T19:39:22.965080Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output_channels = 3\nclass cyclic_gans(keras.Model):\n    def __init__(self):\n        super(cyclic_gans,self).__init__()\n        self.monet_genrator = self.make_genrator()\n        self.photo_genrator = self.make_genrator()\n        self.monet_dicriminator = self.make_discriminator()\n        self.photo_dicriminator = self.make_discriminator()\n        self.lambda_cycles = 10\n    def compile(self):\n        super(cyclic_gans,self).compile()  \n        self.monet_genrator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n        self.photo_genrator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n        self.monet_dicriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n        self.photo_dicriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n    def create_downsmapler(self,filters,size,apply_instace_norm=True):\n        model = keras.Sequential()\n        model.add(layers.Conv2D(filters,size,strides=2,padding=\"same\",use_bias=False,kernel_initializer = tf.random_normal_initializer(0.0,0.02)))\n        if apply_instace_norm:\n            model.add(tfa.layers.InstanceNormalization(gamma_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.02)))\n        model.add(layers.LeakyReLU())\n        return model\n    def create_upsampler(self,filters,size,add_dropout=True):\n        model = keras.Sequential()\n        model.add(layers.Conv2DTranspose(filters,size,strides=2,padding=\"same\",use_bias=True,kernel_initializer = tf.random_normal_initializer(0.0,0.02)))\n        model.add(tfa.layers.InstanceNormalization(gamma_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.02)))\n        if add_dropout:\n                  model.add(layers.Dropout(0.5))\n        model.add(layers.LeakyReLU())\n        return model \n    def make_genrator(self):\n        down_samplers = [\n            self.create_downsmapler(64,4,apply_instace_norm=False),\n            self.create_downsmapler(128,4),\n            self.create_downsmapler(256,4),\n            self.create_downsmapler(512,4),\n            self.create_downsmapler(512,4),\n            self.create_downsmapler(512,4),\n            self.create_downsmapler(512,4),\n            self.create_downsmapler(512,4)\n        ]\n        up_samplers = [\n            self.create_upsampler(512,4,add_dropout=True),\n            self.create_upsampler(512,4,add_dropout=True),\n            self.create_upsampler(512,4,add_dropout=True),\n            self.create_upsampler(512,4),\n            self.create_upsampler(256,4),\n            self.create_upsampler(128,4),\n            self.create_upsampler(64,4),\n        ]\n        input_layers = layers.Input(shape=[256,256,3])\n        x =  input_layers\n        skips = []          \n        for downsampler in down_samplers:\n                  x = downsampler(x)\n                  skips.append(x)\n        skips = reversed(skips[:-1])          \n        for upsampler,skip_layer in zip(up_samplers,skips):\n                  x = upsampler(x)\n                  x = layers.Concatenate()([x,skip_layer])\n        last_layer = layers.Conv2DTranspose(output_channels,4,strides=2,padding=\"same\",kernel_initializer = tf.random_normal_initializer(0.0,0.02),activation=\"tanh\")       \n        x = last_layer(x)\n        return keras.Model(inputs=input_layers,outputs=x)\n    def make_discriminator(self):\n        input_layer = layers.Input(shape=[256,256,3],name=\"input_image\")\n        x = input_layer\n        downsampler1 = self.create_downsmapler(64,4,False)(x)\n        downsampler2 = self.create_downsmapler(128,4)(downsampler1)\n        downsampler3 = self.create_downsmapler(256,4)(downsampler2)\n        zero_padd1 = layers.ZeroPadding2D()(downsampler3)\n        conv_layer = layers.Conv2D(512,4,strides=1,use_bias=False,kernel_initializer = tf.random_normal_initializer(0.0,0.02))(zero_padd1)\n        norm_layer1 = tfa.layers.InstanceNormalization(gamma_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.02))(conv_layer)\n        leaky_layer = layers.LeakyReLU()(norm_layer1)\n        zero_pad2 = layers.ZeroPadding2D()(leaky_layer)\n        last_layers = layers.Conv2D(1,4,strides=1,kernel_initializer = tf.random_normal_initializer(0.0,0.02))(zero_pad2)\n        return keras.Model(inputs=input_layer,outputs=last_layers)\n    def descriminator_loss_fn(self,real,fake):\n        real_loss = tf.keras.losses.BinaryCrossentropy(from_logits = True,reduction=tf.keras.losses.Reduction.NONE)(tf.ones_like(real),real)\n        fake_loss = tf.keras.losses.BinaryCrossentropy(from_logits = True,reduction=tf.keras.losses.Reduction.NONE)(tf.ones_like(fake),fake)\n        return (real_loss+fake_loss)/2\n    def genrator_loss_fn(self,genrated_image):\n        return tf.keras.losses.BinaryCrossentropy(from_logits = True,reduction=tf.keras.losses.Reduction.NONE)(tf.ones_like(genrated_image),genrated_image)\n    def cycle_loss_fn(self,image,cycled_image,lambda_image):\n        return tf.reduce_mean(tf.abs(image-cycled_image))*lambda_image\n    def identiy_loss_fn(self,real_photo,photo,lambda_image):\n        return tf.reduce_mean(tf.abs(real_photo-photo))*lambda_image/2\n    def train_step(self,batch_data):\n        real_monet,real_photot = batch_data\n        with tf.GradientTape(persistent=True) as tape:\n            fake_monet = self.monet_genrator(real_photot,training=True)\n            cycled_photo = self.photo_genrator(fake_monet,training=True)\n            fake_photo = self.photo_genrator(real_monet,training=True)\n            cycled_monet = self.monet_genrator(fake_photo,training=True)\n            \n            monet1 = self.monet_genrator(real_monet,training=True)\n            phtot1 = self.photo_genrator(real_photot,training=True)\n            \n            monet_real_discriminated = self.monet_dicriminator(real_monet,training=True)\n            monet_fake_discriminated = self.monet_dicriminator(fake_monet,training=True)\n            photo_real_discriminated = self.photo_dicriminator(real_photot,training=True)\n            photo_fake_discriminated = self.photo_dicriminator(fake_photo,training=True)\n            \n            monet_loss = self.genrator_loss_fn(monet_fake_discriminated)\n            photo_loss = self.genrator_loss_fn(photo_fake_discriminated)\n            \n            cycle_loss = self.cycle_loss_fn(real_monet,cycled_monet,self.lambda_cycles) + self.cycle_loss_fn(real_photot,cycled_photo,self.lambda_cycles)\n            \n            total_monet_genrator_loss = monet_loss + cycle_loss + self.identiy_loss_fn(real_monet,monet1, self.lambda_cycles)\n            total_photo_genrator_loss = photo_loss + cycle_loss + self.identiy_loss_fn(real_photot,phtot1, self.lambda_cycles)\n            \n            monet_discriminator_loss = self.descriminator_loss_fn(monet_real_discriminated,monet_fake_discriminated)\n            photo_discriminator_loss = self.descriminator_loss_fn(photo_real_discriminated,photo_fake_discriminated)\n        monet_genrator_gradient = tape.gradient(total_monet_genrator_loss,self.monet_genrator.trainable_variables)\n        photo_genrator_gradient = tape.gradient(total_photo_genrator_loss,self.photo_genrator.trainable_variables)\n        monet_disr_gradient = tape.gradient(monet_discriminator_loss,self.monet_dicriminator.trainable_variables)\n        photo_disr_gradient = tape.gradient(photo_discriminator_loss, self.photo_dicriminator.trainable_variables)\n        self.monet_genrator_optimizer.apply_gradients(zip(monet_genrator_gradient,self.monet_genrator.trainable_variables))\n        self.photo_dicriminator_optimizer.apply_gradients(zip(photo_disr_gradient,self.photo_dicriminator.trainable_variables))\n        self.photo_genrator_optimizer.apply_gradients(zip(photo_genrator_gradient,self.photo_genrator.trainable_variables))\n        self.monet_dicriminator_optimizer.apply_gradients(zip(monet_disr_gradient,self.monet_dicriminator.trainable_variables))\n        return {\n            \"monet_generator_loss\": total_monet_genrator_loss,\n            \"photo_generator_loss\": total_photo_genrator_loss,\n            \"monet_discriminator_loss\": monet_discriminator_loss,\n            \"photo_discriminator_loss\": photo_discriminator_loss,\n        }","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:22.970402Z","iopub.execute_input":"2023-03-22T19:39:22.970796Z","iopub.status.idle":"2023-03-22T19:39:23.002257Z","shell.execute_reply.started":"2023-03-22T19:39:22.970762Z","shell.execute_reply":"2023-03-22T19:39:23.001083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cycle_gan = cyclic_gans()\ncycle_gan.compile()","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:23.005161Z","iopub.execute_input":"2023-03-22T19:39:23.005928Z","iopub.status.idle":"2023-03-22T19:39:25.956836Z","shell.execute_reply.started":"2023-03-22T19:39:23.005880Z","shell.execute_reply":"2023-03-22T19:39:25.955787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cycle_gan.fit(\n    tf.data.Dataset.zip((monet_dataset.repeat(-1), photo_dataset.repeat(-1))),\n    steps_per_epoch=300,\n    epochs=30\n)","metadata":{"execution":{"iopub.status.busy":"2023-03-22T19:39:25.958138Z","iopub.execute_input":"2023-03-22T19:39:25.958527Z","iopub.status.idle":"2023-03-22T20:19:15.158358Z","shell.execute_reply.started":"2023-03-22T19:39:25.958489Z","shell.execute_reply":"2023-03-22T20:19:15.157106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from io import BytesIO\nfrom PIL import Image\nfrom zipfile import ZipFile\nimport numpy as np\n\n\nwith ZipFile(\"images.zip\",mode=\"w\") as zipfiles:\n    i = 1\n    for img in photo_dataset:\n        genrated_image_cycle = cycle_gan.monet_genrator(img,training=False)[0].numpy()\n        scaled_img = (genrated_image_cycle*127.5+127.5).astype(np.uint8)\n        with BytesIO() as image_bytes:\n            Image.fromarray(scaled_img).save(image_bytes, 'JPEG')\n            image_bytes.seek(0)\n            zipfiles.writestr('{}.jpg'.format(i), image_bytes.read())\n            i += 1","metadata":{"execution":{"iopub.status.busy":"2023-03-22T20:26:43.837643Z","iopub.execute_input":"2023-03-22T20:26:43.838230Z","iopub.status.idle":"2023-03-22T20:35:10.889150Z","shell.execute_reply.started":"2023-03-22T20:26:43.838193Z","shell.execute_reply":"2023-03-22T20:35:10.888124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}