{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:53:42.699125Z","iopub.execute_input":"2024-12-21T04:53:42.699621Z","iopub.status.idle":"2024-12-21T04:53:46.933005Z","shell.execute_reply.started":"2024-12-21T04:53:42.699569Z","shell.execute_reply":"2024-12-21T04:53:46.931854Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom kaggle_datasets import KaggleDatasets\n%matplotlib inline","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:53:46.935191Z","iopub.execute_input":"2024-12-21T04:53:46.935671Z","iopub.status.idle":"2024-12-21T04:54:00.053346Z","shell.execute_reply.started":"2024-12-21T04:53:46.935593Z","shell.execute_reply":"2024-12-21T04:54:00.052222Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.layers import Input, Conv2D, Conv2DTranspose, Dropout, LeakyReLU, ReLU, ZeroPadding2D, GroupNormalization, Concatenate, ZeroPadding2D\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.losses import BinaryCrossentropy\nfrom tensorflow.keras.optimizers import Adam\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:00.054606Z","iopub.execute_input":"2024-12-21T04:54:00.055238Z","iopub.status.idle":"2024-12-21T04:54:00.147222Z","shell.execute_reply.started":"2024-12-21T04:54:00.055201Z","shell.execute_reply":"2024-12-21T04:54:00.146223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"GCS_PATH = KaggleDatasets().get_gcs_path()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:00.148457Z","iopub.execute_input":"2024-12-21T04:54:00.148807Z","iopub.status.idle":"2024-12-21T04:54:00.631339Z","shell.execute_reply.started":"2024-12-21T04:54:00.148753Z","shell.execute_reply":"2024-12-21T04:54:00.630387Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"monet_files= tf.io.gfile.glob(str(GCS_PATH + '/monet_tfrec/*.tfrec'))\nphoto_files= tf.io.gfile.glob(str(GCS_PATH + '/photo_tfrec/*.tfrec'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:00.634003Z","iopub.execute_input":"2024-12-21T04:54:00.634360Z","iopub.status.idle":"2024-12-21T04:54:02.066430Z","shell.execute_reply.started":"2024-12-21T04:54:00.634327Z","shell.execute_reply":"2024-12-21T04:54:02.065277Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('No. of Monet TFRecord files: ',len(monet_files))\nprint('No. of Photo TFRecord files: ',len(photo_files))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:02.067963Z","iopub.execute_input":"2024-12-21T04:54:02.068372Z","iopub.status.idle":"2024-12-21T04:54:02.073951Z","shell.execute_reply.started":"2024-12-21T04:54:02.068327Z","shell.execute_reply":"2024-12-21T04:54:02.072847Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_SIZE= [256,256]                                            \n\ndef decode_img(image):                                           \n    image= tf.image.decode_jpeg(image,channels= 3)               # 3 channels because of RGB\n    image= (tf.cast(image, tf.float32)/255)*2 -1                 # converting the pixel values in range [-1,1]\n    image= tf.reshape(image, shape= [*IMAGE_SIZE,3])             # reshaping the image to proper size\n    return image\n\ndef read_tfrec(example):                                         # function for extracting image from TFRecord format\n    tfrec_format= {\n        'image_name': tf.io.FixedLenFeature([], tf.string),      # [] denotes fixed length feature where length= 1\n        'image': tf.io.FixedLenFeature([], tf.string),\n        'target': tf.io.FixedLenFeature([], tf.string)\n    }\n    example= tf.io.parse_single_example(example, tfrec_format)\n    image= decode_img(example['image'])\n    return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:02.075196Z","iopub.execute_input":"2024-12-21T04:54:02.075472Z","iopub.status.idle":"2024-12-21T04:54:02.085632Z","shell.execute_reply.started":"2024-12-21T04:54:02.075445Z","shell.execute_reply":"2024-12-21T04:54:02.084563Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_data(files):\n    data= tf.data.TFRecordDataset(files)\n    data= data.map(read_tfrec)                                   # (num_parallel_calls= AUTOTUNE) in  case of TPU\n    return data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:02.087056Z","iopub.execute_input":"2024-12-21T04:54:02.087541Z","iopub.status.idle":"2024-12-21T04:54:02.104839Z","shell.execute_reply.started":"2024-12-21T04:54:02.087493Z","shell.execute_reply":"2024-12-21T04:54:02.103872Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"monet_data= load_data(monet_files).batch(1)                      # forming batches of size=1 (i.e. 1 image processed at a time)\nphoto_data= load_data(photo_files).batch(1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:02.106001Z","iopub.execute_input":"2024-12-21T04:54:02.106319Z","iopub.status.idle":"2024-12-21T04:54:02.320591Z","shell.execute_reply.started":"2024-12-21T04:54:02.106289Z","shell.execute_reply":"2024-12-21T04:54:02.319514Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"monet_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:02.321967Z","iopub.execute_input":"2024-12-21T04:54:02.322269Z","iopub.status.idle":"2024-12-21T04:54:02.330013Z","shell.execute_reply.started":"2024-12-21T04:54:02.322240Z","shell.execute_reply":"2024-12-21T04:54:02.328866Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ex_monet= next(iter(monet_data))\nex_photo= next(iter(photo_data))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:02.330998Z","iopub.execute_input":"2024-12-21T04:54:02.331278Z","iopub.status.idle":"2024-12-21T04:54:07.966054Z","shell.execute_reply.started":"2024-12-21T04:54:02.331250Z","shell.execute_reply":"2024-12-21T04:54:07.964861Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.subplot(1,2,1)                                       # creating a subplot with 1 row and 2 columns\nplt.title('Photo')\nplt.imshow(ex_photo[0]*0.5 +0.5)                         # rescaling the image to [0,1] for displaying\n\nplt.subplot(1,2,2)\nplt.title('Monet')\nplt.imshow(ex_monet[0]*0.5 +0.5)   ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:07.967731Z","iopub.execute_input":"2024-12-21T04:54:07.968287Z","iopub.status.idle":"2024-12-21T04:54:08.518207Z","shell.execute_reply.started":"2024-12-21T04:54:07.968238Z","shell.execute_reply":"2024-12-21T04:54:08.517107Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def downsample(filters, size, instance_norm= True):                                   # for extracting important features (size is reduced)\n    initializer= tf.random_normal_initializer(0,0.02)                                 # mean=0 and standard deviation=0.02 for initializing kernel weights\n    gamma_init= keras.initializers.RandomNormal(mean= 0, stddev= 0.02)\n    \n    model= keras.Sequential()                                          \n    model.add(Conv2D(filters, size, strides=2, padding='same', kernel_initializer= initializer, use_bias= False))\n    \n    if instance_norm:\n         model.add(GroupNormalization(groups= -1, gamma_initializer= gamma_init))     # groups= -1 to make it work like Instance Normalization\n   \n    model.add(LeakyReLU())\n    \n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:08.519463Z","iopub.execute_input":"2024-12-21T04:54:08.519783Z","iopub.status.idle":"2024-12-21T04:54:08.526531Z","shell.execute_reply.started":"2024-12-21T04:54:08.519752Z","shell.execute_reply":"2024-12-21T04:54:08.525283Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def upsample(filters, size, dropout= False):                                         # for locating features accurately using skip connections \n    initializer= tf.random_normal_initializer(0,0.02)\n    gamma_init= keras.initializers.RandomNormal(mean= 0, stddev= 0.02)\n    \n    model= keras.Sequential()\n    model.add(Conv2DTranspose(filters, size, strides= 2, padding= 'same', kernel_initializer= initializer, use_bias= False))\n    model.add(GroupNormalization(groups= -1, gamma_initializer= gamma_init))\n    \n    if dropout:\n        model.add(Dropout(0.5))\n    \n    model.add(ReLU())\n    \n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:08.530187Z","iopub.execute_input":"2024-12-21T04:54:08.530502Z","iopub.status.idle":"2024-12-21T04:54:08.543854Z","shell.execute_reply.started":"2024-12-21T04:54:08.530471Z","shell.execute_reply":"2024-12-21T04:54:08.542812Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def generator():\n    down_stack= [\n        downsample(64,4,False),                 # size= (128,128,64)  (size denotes the dimensions of image after the corresponding layer/operation)\n        downsample(128,4),                      # size= (64,64,128)\n        downsample(256,4),                      # size= (32,32,256)\n        downsample(512,4),                      # size= (16,16,512)\n        downsample(512,4),                      # size= (8,8,512)\n        downsample(512,4),                      # size= (4,4,512)\n        downsample(512,4),                      # size= (2,2,512)\n        downsample(512,4),                      # size= (1,1,512)\n    ]\n    \n    up_stack= [\n        upsample(512,4,True),                   # size= (2,2,1024)  (no. of channels doubled because upsample block concats output of last downsample block)    \n        upsample(512,4,True),                   # size= (4,4,1024)\n        upsample(512,4,True),                   # size= (8,8,1024)\n        upsample(512,4),                        # size= (16,16,1024)  (dropout= false so that information is maintained for generating detailed outputs)\n        upsample(256,4),                        # size= (32,32,512)\n        upsample(128,4),                        # size= (64,64,256)\n        upsample(64,4)                          # size= (128,128,128)\n    ]\n    \n    initializer= tf.random_normal_initializer(0,0.02)\n    last_layer= Conv2DTranspose(3, 4, strides= 2, padding= 'same', kernel_initializer= initializer, activation= 'tanh')     # 3 output channels required\n    \n    i= Input(shape= [256,256,3])                # input layer\n    x= i\n    skips= []\n    for down in down_stack:                     # downsampling\n        x= down (x) \n        skips.append(x)                         # appending skip connections to the 'skips' list\n        \n    skips= reversed(skips[:-1])                 # last skip connection is not used because of alignment with upsampling path\n    \n    for up, skip in zip(up_stack,skips):        # upsampling and concatenating output with skip connection\n        x= up (x)\n        x= Concatenate() ([x,skip])\n        \n    x= last_layer(x)                            # last layer (Conv2DTranspose) for generating the final output \n    \n    model= Model(i,x)\n    \n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:08.545386Z","iopub.execute_input":"2024-12-21T04:54:08.545761Z","iopub.status.idle":"2024-12-21T04:54:08.558441Z","shell.execute_reply.started":"2024-12-21T04:54:08.545729Z","shell.execute_reply":"2024-12-21T04:54:08.557446Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def discriminator():\n    i= Input(shape= [256,256,3])\n    x= downsample(64,4) (i)                                 # size= (128,128,64) \n    x= downsample(128,4) (x)                                # size= (64,64,128) \n    x= downsample(256,4) (x)                                # size= (32,32,256)\n    \n    x= ZeroPadding2D() (x)                                  # size= (34,34,256)    (1 pixel padding is added at top,bottom,left,right) \n    \n    initializer= tf.random_normal_initializer(0,0.02)\n    gamma_init= keras.initializers.RandomNormal(mean= 0, stddev= 0.02)\n    x= Conv2D(512, 4, strides= 1, padding= 'same', kernel_initializer= initializer, use_bias= False) (x)      # size= (31,31,512) (size= orig - kernel + 1)\n    x= GroupNormalization(groups= -1, gamma_initializer= gamma_init) (x)\n    x= LeakyReLU() (x)\n    \n    x= ZeroPadding2D() (x)                                  # size= (33,33,512)    (zero padding applied to maintain spatial information)\n    \n    x= Conv2D(1, 4, strides= 1, padding= 'same', kernel_initializer= initializer) (x)       # size= (30,30,1) \n                                                                                            # sigmoid not used to output unbounded logits\n    model= Model(i,x)                                                                       # (more numerically stable during training)\n    \n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:08.560178Z","iopub.execute_input":"2024-12-21T04:54:08.560618Z","iopub.status.idle":"2024-12-21T04:54:08.581991Z","shell.execute_reply.started":"2024-12-21T04:54:08.560573Z","shell.execute_reply":"2024-12-21T04:54:08.580965Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# with strategy.scope():\nmonet_generator= generator()                     # photo to monet-esque\nmonet_discriminator= discriminator()             # to differentiate between generated monet-esque images and real monet-esque images\nphoto_generator= generator()                     # monet-esque to photo\nphoto_discriminator= discriminator()             # to differentiate between generated 'normal' images and real 'normal' images","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:08.583421Z","iopub.execute_input":"2024-12-21T04:54:08.583881Z","iopub.status.idle":"2024-12-21T04:54:10.796940Z","shell.execute_reply.started":"2024-12-21T04:54:08.583834Z","shell.execute_reply":"2024-12-21T04:54:10.795848Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"photo_to_monet= monet_generator(ex_photo)                # won't generate monet-esque photos as we have not fit the data into generator yet\n\nplt.subplot(1,2,1)                                       # creating a subplot with 1 row and 2 columns\nplt.title('Original Photo')\nplt.imshow(ex_photo[0]*0.5 +0.5)                         # rescaling the image to [0,1] for displaying\n\nplt.subplot(1,2,2)\nplt.title('Generated Monet-esque photo')\nplt.imshow(photo_to_monet[0]*0.5 +0.5)  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:10.798214Z","iopub.execute_input":"2024-12-21T04:54:10.798529Z","iopub.status.idle":"2024-12-21T04:54:11.674175Z","shell.execute_reply.started":"2024-12-21T04:54:10.798498Z","shell.execute_reply":"2024-12-21T04:54:11.672976Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CycleGAN(keras.Model):                       # CycleGAN class inheriting from keras.Model class so that it can use its methods to train, compile etc.\n    def __init__(                                  # arguments to be passed in a CycleGAN class object   \n        self,\n        monet_gen,\n        monet_disc,\n        photo_gen,\n        photo_disc,\n        lambda_cycle= 10                           # 'lambda_cycle' controls the importance of cycle consistency loss\n    ):\n        super(CycleGAN,self).__init__()            # calls the constructor of the parent class (keras.Model), initializing the base properties and methods\n        self.m_gen= monet_gen                      # assigning argument values to attributes of a CycleGAN class object/instance\n        self.m_disc= monet_disc\n        self.p_gen= photo_gen\n        self.p_disc= photo_disc\n        self.lambda_cycle= lambda_cycle\n        \n    def compile(                                   \n        self,\n        m_gen_optimizer,\n        m_disc_optimizer,\n        p_gen_optimizer,\n        p_disc_optimizer,\n        gen_loss_function,\n        disc_loss_function,\n        cycle_loss_function,\n        identity_loss_function\n    ):\n        super(CycleGAN,self).compile()             # calls the 'compile' fn of the parent class (keras.Model), initializing the base properties and methods\n        self.m_gen_optimizer = m_gen_optimizer\n        self.m_disc_optimizer = m_disc_optimizer\n        self.p_gen_optimizer = p_gen_optimizer\n        self.p_disc_optimizer = p_disc_optimizer\n        self.gen_loss_function = gen_loss_function\n        self.disc_loss_function = disc_loss_function\n        self.cycle_loss_function = cycle_loss_function\n        self.identity_loss_function = identity_loss_function\n        \n    def train_step(self,batch_data):                                # automatically invoked when fit() method is called \n        real_monet, real_photo= batch_data\n        \n        with tf.GradientTape(persistent= True) as tape:             # to keep a track of operations (persistent= True bcz of multiple calls to Gradient())\n            \n            fake_monet= self.m_gen(real_photo, training= True)      # photo to monet and then cycled back to photo\n            cycled_photo= self.p_gen(fake_monet, training= True)\n            \n            fake_photo= self.p_gen(real_monet, training= True)      # monet to photo and then cycled back to monet\n            cycled_monet= self.m_gen(fake_photo, training= True)\n            \n            same_photo= self.p_gen(real_photo, training= True)      # generating itself (useful in calculating identity loss)\n            same_monet= self.m_gen(real_monet, training= True)      \n            \n            disc_real_photo= self.p_disc(real_photo, training= True)   # discriminator used to check by inputing real images\n            disc_real_monet= self.m_disc(real_monet, training= True)   \n            \n            disc_fake_photo= self.p_disc(fake_photo, training= True)   # discriminator used to check by inputing fake images\n            disc_fake_monet= self.m_disc(fake_monet, training= True)\n            \n            gen_monet_loss= self.gen_loss_function(disc_fake_monet)    # generator loss\n            gen_photo_loss= self.gen_loss_function(disc_fake_photo)\n            \n            total_cycle_loss = (self.cycle_loss_function(real_monet, cycled_monet, self.lambda_cycle) +     # total cycle consistency loss\n            self.cycle_loss_function(real_photo, cycled_photo, self.lambda_cycle))\n            \n            total_gen_monet_loss= (gen_monet_loss + total_cycle_loss   +                                    # total generator monet loss\n            self.identity_loss_function(real_monet, same_monet, self.lambda_cycle) )  \n            \n            total_gen_photo_loss= (gen_photo_loss + total_cycle_loss   +                                    # total generator photo loss\n            self.identity_loss_function(real_photo, same_photo, self.lambda_cycle) )\n            \n            disc_monet_loss= self.disc_loss_function(disc_real_monet, disc_fake_monet)                      # discriminator monet loss \n            disc_photo_loss= self.disc_loss_function(disc_real_photo, disc_fake_photo)                      # discriminator photo loss\n            \n            \n        gen_monet_gradients= tape.gradient(total_gen_monet_loss, self.m_gen.trainable_variables)            # calculate gradients for generators\n        gen_photo_gradients= tape.gradient(total_gen_photo_loss, self.p_gen.trainable_variables)            # diff loss fn wrt trainable variables of model\n        \n        disc_monet_gradients= tape.gradient(disc_monet_loss, self.m_disc.trainable_variables)               # calculate gradients for discriminators\n        disc_photo_gradients= tape.gradient(disc_photo_loss, self.p_disc.trainable_variables)\n        \n        self.m_gen_optimizer.apply_gradients(zip(gen_monet_gradients, self.m_gen.trainable_variables))      # apply the gradients to optimizer\n        self.p_gen_optimizer.apply_gradients(zip(gen_photo_gradients, self.p_gen.trainable_variables))      # basically performing gradient descent\n        self.m_disc_optimizer.apply_gradients(zip(disc_monet_gradients, self.m_disc.trainable_variables))\n        self.p_disc_optimizer.apply_gradients(zip(disc_photo_gradients, self.p_disc.trainable_variables))\n        \n        return {\n            'gen_monet_loss': total_gen_monet_loss,\n            'gen_photo_loss': total_gen_photo_loss,\n            'disc_monet_loss': disc_monet_loss,\n            'disc_photo_loss': disc_photo_loss\n        }","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.675966Z","iopub.execute_input":"2024-12-21T04:54:11.676312Z","iopub.status.idle":"2024-12-21T04:54:11.692491Z","shell.execute_reply.started":"2024-12-21T04:54:11.676277Z","shell.execute_reply":"2024-12-21T04:54:11.691229Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# with strategy.scope():\ndef gen_loss_fn(generated):            \n    return BinaryCrossentropy(from_logits= True, reduction= tf.keras.losses.Reduction.NONE)(tf.ones_like(generated),generated)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.694060Z","iopub.execute_input":"2024-12-21T04:54:11.694480Z","iopub.status.idle":"2024-12-21T04:54:11.709729Z","shell.execute_reply.started":"2024-12-21T04:54:11.694433Z","shell.execute_reply":"2024-12-21T04:54:11.708520Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# with strategy.scope():\ndef disc_loss_fn(real, generated):\n    loss_real= BinaryCrossentropy(from_logits= True, reduction= tf.keras.losses.Reduction.NONE)(tf.ones_like(real),real)\n    loss_fake= BinaryCrossentropy(from_logits= True, reduction= tf.keras.losses.Reduction.NONE)(tf.zeros_like(generated),generated)\n        \n    total_loss= (loss_real + loss_fake)/2\n        \n    return total_loss","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.711030Z","iopub.execute_input":"2024-12-21T04:54:11.711378Z","iopub.status.idle":"2024-12-21T04:54:11.725646Z","shell.execute_reply.started":"2024-12-21T04:54:11.711346Z","shell.execute_reply":"2024-12-21T04:54:11.724576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# with strategy.scope():\ndef cycle_loss_fn(real, cycled, lambda_cycle):\n    loss= tf.reduce_mean(tf.abs(real - cycled))\n        \n    return lambda_cycle*loss                         ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.727034Z","iopub.execute_input":"2024-12-21T04:54:11.727340Z","iopub.status.idle":"2024-12-21T04:54:11.738961Z","shell.execute_reply.started":"2024-12-21T04:54:11.727310Z","shell.execute_reply":"2024-12-21T04:54:11.737860Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# with strategy.scope():\ndef identity_loss_fn(real, same, Lambda):           \n    loss= tf.reduce_mean(tf.abs(real - same))\n        \n    return Lambda*loss*0.5  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.740103Z","iopub.execute_input":"2024-12-21T04:54:11.740413Z","iopub.status.idle":"2024-12-21T04:54:11.751401Z","shell.execute_reply.started":"2024-12-21T04:54:11.740383Z","shell.execute_reply":"2024-12-21T04:54:11.750141Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"m_gen_opt= Adam(learning_rate= 2e-4, beta_1= 0.5)\nm_disc_opt= Adam(learning_rate= 2e-4, beta_1= 0.5)\n\np_gen_opt= Adam(learning_rate= 2e-4, beta_1= 0.5)\np_disc_opt= Adam(learning_rate= 2e-4, beta_1= 0.5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.752847Z","iopub.execute_input":"2024-12-21T04:54:11.753276Z","iopub.status.idle":"2024-12-21T04:54:11.776033Z","shell.execute_reply.started":"2024-12-21T04:54:11.753227Z","shell.execute_reply":"2024-12-21T04:54:11.774862Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cyclegan_model= CycleGAN(monet_generator, monet_discriminator, photo_generator, photo_discriminator, 10)\ncyclegan_model.compile(m_gen_opt, m_disc_opt, p_gen_opt, p_disc_opt, gen_loss_fn, disc_loss_fn, \n                        cycle_loss_fn, identity_loss_fn)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.777168Z","iopub.execute_input":"2024-12-21T04:54:11.777488Z","iopub.status.idle":"2024-12-21T04:54:11.791816Z","shell.execute_reply.started":"2024-12-21T04:54:11.777456Z","shell.execute_reply":"2024-12-21T04:54:11.790772Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cyclegan_model.fit(tf.data.Dataset.zip((monet_data, photo_data)), epochs= 5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T04:54:11.793116Z","iopub.execute_input":"2024-12-21T04:54:11.794210Z","iopub.status.idle":"2024-12-21T07:02:46.940093Z","shell.execute_reply.started":"2024-12-21T04:54:11.794161Z","shell.execute_reply":"2024-12-21T07:02:46.936871Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig,ax= plt.subplots(6,2, figsize=(7,20))\nfor i,img in enumerate(photo_data.take(6)):\n    pred= monet_generator(img, training= False)[0].numpy()   \n    pred= (pred*127.5 + 127.5).astype(np.uint8)              # pixel[0,255]\n    img= (img[0]*127.5 + 127.5).numpy().astype(np.uint8)\n    \n    ax[i,0].imshow(img)\n    ax[i,1].imshow(pred)\n    ax[i,0].set_title('Real Photo')\n    ax[i,1].set_title('Generated Monet-esque')\n    ax[i,0].axis('off')\n    ax[i,1].axis('off')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T07:02:46.944515Z","iopub.execute_input":"2024-12-21T07:02:46.945074Z","iopub.status.idle":"2024-12-21T07:02:52.626994Z","shell.execute_reply.started":"2024-12-21T07:02:46.945037Z","shell.execute_reply":"2024-12-21T07:02:52.625519Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import PIL\n!mkdir ../images","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T07:02:52.628715Z","iopub.execute_input":"2024-12-21T07:02:52.629093Z","iopub.status.idle":"2024-12-21T07:02:53.878032Z","shell.execute_reply.started":"2024-12-21T07:02:52.629058Z","shell.execute_reply":"2024-12-21T07:02:53.876359Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"i = 1\nfor image in photo_data:\n    pred = monet_generator(image, training=False)[0].numpy()\n    pred = (pred*127.5 + 127.5).astype(np.uint8)\n    im = PIL.Image.fromarray(pred)\n    im.save(\"../images/\" + str(i) + \".jpg\")\n    i += 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T07:02:53.880451Z","iopub.execute_input":"2024-12-21T07:02:53.881033Z","iopub.status.idle":"2024-12-21T07:37:34.026842Z","shell.execute_reply.started":"2024-12-21T07:02:53.880980Z","shell.execute_reply":"2024-12-21T07:37:34.023545Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\nshutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/images\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T07:37:34.030945Z","iopub.execute_input":"2024-12-21T07:37:34.031357Z","iopub.status.idle":"2024-12-21T07:37:36.984310Z","shell.execute_reply.started":"2024-12-21T07:37:34.031320Z","shell.execute_reply":"2024-12-21T07:37:36.983251Z"}},"outputs":[],"execution_count":null}]}