{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"dockerImageVersionId":30408,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Cycle GAN - Claude Monet generator","metadata":{}},{"cell_type":"markdown","source":"this notebook show my submission to \"I’m Something of a Painter Myself\" challenge. for the challenge, instead of 300 images of Monet, i used only 30 images.","metadata":{}},{"cell_type":"markdown","source":"some imports","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport numpy as np\nimport os\nimport time\nimport matplotlib.pyplot as plt\nfrom IPython.display import clear_output","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:42:46.199965Z","iopub.execute_input":"2023-02-28T11:42:46.200358Z","iopub.status.idle":"2023-02-28T11:42:46.206244Z","shell.execute_reply.started":"2023-02-28T11:42:46.200321Z","shell.execute_reply":"2023-02-28T11:42:46.205091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"important hyperparameters","metadata":{}},{"cell_type":"code","source":"# 30 - 200\nEPOCHS = 30\n# \nLAMBDA = 10\n#\nDropOut = 0.6","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:42:46.211081Z","iopub.execute_input":"2023-02-28T11:42:46.212529Z","iopub.status.idle":"2023-02-28T11:42:46.218749Z","shell.execute_reply.started":"2023-02-28T11:42:46.212487Z","shell.execute_reply":"2023-02-28T11:42:46.217569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## preprocess the data","metadata":{}},{"cell_type":"code","source":"photo_ds = tf.keras.utils.image_dataset_from_directory(\n  \"/kaggle/input/gan-getting-started/photo_jpg\",\n  labels=None,\n  seed=123,\n  image_size=(320,320),\n  batch_size=1)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:42:46.222096Z","iopub.execute_input":"2023-02-28T11:42:46.224436Z","iopub.status.idle":"2023-02-28T11:42:58.850441Z","shell.execute_reply.started":"2023-02-28T11:42:46.224396Z","shell.execute_reply":"2023-02-28T11:42:58.849264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! pip install gdown","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:42:58.852441Z","iopub.execute_input":"2023-02-28T11:42:58.853307Z","iopub.status.idle":"2023-02-28T11:43:09.612531Z","shell.execute_reply.started":"2023-02-28T11:42:58.853264Z","shell.execute_reply":"2023-02-28T11:43:09.611050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gdown\nurl = \"https://drive.google.com/drive/u/1/folders/1zbdIvBHk9Yrkf46vLe9PhoWK-amV2a8F\"\ngdown.download_folder(url, quiet=True)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:09.614354Z","iopub.execute_input":"2023-02-28T11:43:09.614761Z","iopub.status.idle":"2023-02-28T11:43:22.804764Z","shell.execute_reply.started":"2023-02-28T11:43:09.614712Z","shell.execute_reply":"2023-02-28T11:43:22.803413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = tf.keras.utils.image_dataset_from_directory(\n  \"monet-30\",\n  labels=None,\n  seed=123,\n  image_size=(320,320),\n  batch_size=1)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:22.807694Z","iopub.execute_input":"2023-02-28T11:43:22.808389Z","iopub.status.idle":"2023-02-28T11:43:22.937326Z","shell.execute_reply.started":"2023-02-28T11:43:22.808357Z","shell.execute_reply":"2023-02-28T11:43:22.936106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def decode_image(image):\n    #image = tf.image.decode_jpeg(image, channels=3)\n    image_tensor = tf.cast(image, tf.float32)\n    min_val = tf.reduce_min(image_tensor)\n    max_val = tf.reduce_max(image_tensor)\n    image_tensor = (image_tensor - min_val) / (max_val - min_val)\n    image_tensor = tf.reshape(image_tensor, [1,320,320, 3])\n    return image_tensor\nphoto_ds = photo_ds.map(decode_image)\ntrain_ds= train_ds.map(decode_image)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:22.938953Z","iopub.execute_input":"2023-02-28T11:43:22.939317Z","iopub.status.idle":"2023-02-28T11:43:23.033839Z","shell.execute_reply.started":"2023-02-28T11:43:22.939279Z","shell.execute_reply":"2023-02-28T11:43:23.032947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## bulilding the model components","metadata":{}},{"cell_type":"markdown","source":"### basic components - normalization, upsample and downsample","metadata":{}},{"cell_type":"code","source":"class InstanceNormalization(tf.keras.layers.Layer):\n  def __init__(self, epsilon=1e-5):\n    super(InstanceNormalization, self).__init__()\n    self.epsilon = epsilon\n\n  def build(self, input_shape):\n    self.scale = self.add_weight(\n        name='scale',\n        shape=input_shape[-1:],\n        initializer=tf.random_normal_initializer(1., 0.02),\n        trainable=True)\n\n    self.offset = self.add_weight(\n        name='offset',\n        shape=input_shape[-1:],\n        initializer='zeros',\n        trainable=True)\n\n  def call(self, x):\n    mean, variance = tf.nn.moments(x, axes=[1, 2], keepdims=True)\n    inv = tf.math.rsqrt(variance + self.epsilon)\n    normalized = (x - mean) * inv\n    return self.scale * normalized + self.offset","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:23.035412Z","iopub.execute_input":"2023-02-28T11:43:23.035790Z","iopub.status.idle":"2023-02-28T11:43:23.043941Z","shell.execute_reply.started":"2023-02-28T11:43:23.035753Z","shell.execute_reply":"2023-02-28T11:43:23.042739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def downsample(filters, size, norm_type='batchnorm', apply_norm=True, stride=2):\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  result = tf.keras.Sequential()\n  result.add(\n      tf.keras.layers.Conv2D(filters, size, strides=stride, padding='same',\n                             kernel_initializer=initializer, use_bias=False))\n\n  if apply_norm:\n    if norm_type.lower() == 'batchnorm':\n      result.add(tf.keras.layers.BatchNormalization())\n    elif norm_type.lower() == 'instancenorm':\n      result.add(InstanceNormalization())\n\n  result.add(tf.keras.layers.LeakyReLU(0.1))\n\n  return result","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:23.045834Z","iopub.execute_input":"2023-02-28T11:43:23.046357Z","iopub.status.idle":"2023-02-28T11:43:23.055483Z","shell.execute_reply.started":"2023-02-28T11:43:23.046261Z","shell.execute_reply":"2023-02-28T11:43:23.054120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def upsample(filters, size, norm_type='batchnorm', apply_dropout=False, stride=2, crop = None):\n\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  result = tf.keras.Sequential()\n  result.add(\n      tf.keras.layers.Conv2DTranspose(filters, size, strides=stride,\n                                      padding='same',\n                                      kernel_initializer=initializer,\n                                      use_bias=False))\n  if crop is not None:\n    result.add(\n        tf.keras.layers.Cropping2D(cropping=((1, 0), (1, 0)))\n    )\n\n  if norm_type.lower() == 'batchnorm':\n    result.add(tf.keras.layers.BatchNormalization())\n  elif norm_type.lower() == 'instancenorm':\n    result.add(InstanceNormalization())\n\n  if apply_dropout:\n    result.add(tf.keras.layers.Dropout(DropOut))\n#leaky relu\n  result.add(tf.keras.layers.LeakyReLU(0.1))\n\n  return result","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:23.058109Z","iopub.execute_input":"2023-02-28T11:43:23.058440Z","iopub.status.idle":"2023-02-28T11:43:23.070578Z","shell.execute_reply.started":"2023-02-28T11:43:23.058414Z","shell.execute_reply":"2023-02-28T11:43:23.069466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## UNET Generator","metadata":{}},{"cell_type":"code","source":"def unet_generator(output_channels, norm_type='batchnorm'):\n  down_stack = [\n      downsample(64, 4, norm_type, apply_norm=False),  # (bs, 160, 160, 64)\n      downsample(128, 4, norm_type),  # (bs, 80, 80, 128)\n      downsample(256, 4, norm_type),  # (bs, 40, 50, 256)\n      downsample(512, 4, norm_type),  # (bs, 20, 20, 512)\n      downsample(512, 4, norm_type),  # (bs, 10, 10, 512)\n      downsample(512, 4, norm_type),  # (bs, 5, 5, 512)\n      downsample(512, 4, norm_type),  # (bs, 3, 3, 512)\n      downsample(512, 4, norm_type, stride=3),  # (bs, 1, 1, 512)\n  ]\n\n  up_stack = [\n      upsample(512, 4, norm_type, apply_dropout=True,stride = 3),  # (bs, 3, 3, 1024)\n      upsample(512, 4, norm_type, apply_dropout=True, crop = True),  # (bs, 4, 4, 1024)\n      upsample(512, 4, norm_type, apply_dropout=True),  # (bs, 8, 8, 1024)\n      upsample(512, 4, norm_type),  # (bs, 16, 16, 1024)\n      upsample(256, 4, norm_type),  # (bs, 32, 32, 512)\n      upsample(128, 4, norm_type),  # (bs, 64, 64, 256)\n      upsample(64, 4, norm_type),  # (bs, 128, 128, 128)\n  ]\n\n  initializer = tf.random_normal_initializer(0., 0.02)\n  last = tf.keras.layers.Conv2DTranspose(\n      output_channels, 4, strides=2,\n      padding='same', kernel_initializer=initializer,\n      activation='tanh')  # (bs, 256, 256, 3)\n\n  concat = tf.keras.layers.Concatenate()\n\n  inputs = tf.keras.layers.Input(shape=[320, 320, 3])\n  x = inputs\n\n  # Downsampling through the model\n  skips = []\n  for down in down_stack:\n    x = down(x)\n    skips.append(x)\n\n  skips = reversed(skips[:-1])\n\n  # Upsampling and establishing the skip connections\n  for up, skip in zip(up_stack, skips):\n    up.build(x.shape)\n    x = up(x)\n    x = concat([x, skip])\n\n  x = last(x)\n\n  return tf.keras.Model(inputs=inputs, outputs=x)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:23.072465Z","iopub.execute_input":"2023-02-28T11:43:23.072753Z","iopub.status.idle":"2023-02-28T11:43:23.085881Z","shell.execute_reply.started":"2023-02-28T11:43:23.072707Z","shell.execute_reply":"2023-02-28T11:43:23.084839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Discriminator","metadata":{}},{"cell_type":"code","source":"def discriminator(norm_type='batchnorm', target=True):\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  inp = tf.keras.layers.Input(shape=[None, None, 3], name='input_image')\n  x = inp\n\n  if target:\n    tar = tf.keras.layers.Input(shape=[None, None, 3], name='target_image')\n    x = tf.keras.layers.concatenate([inp, tar])  # (bs, 320, 3230, channels*2)\n\n  down1 = downsample(64, 4, norm_type, False)(x)  # (bs, 160, 160, 64)\n  down2 = downsample(128, 4, norm_type)(down1)  # (bs, 80, 80, 128)\n  down3 = downsample(256, 4, norm_type)(down2)  # (bs, 40, 40, 256)\n  down4 = downsample(256, 4, norm_type)(down3)  # (bs, 20, 20, 256)\n\n  zero_pad1 = tf.keras.layers.ZeroPadding2D()(down4)  # (bs, 42, 42, 256)\n  conv = tf.keras.layers.Conv2D(\n      512, 4, strides=1, kernel_initializer=initializer,\n      use_bias=False)(zero_pad1)  # (bs, 39, 39, 512)\n\n  if norm_type.lower() == 'batchnorm':\n    norm1 = tf.keras.layers.BatchNormalization()(conv)\n  elif norm_type.lower() == 'instancenorm':\n    norm1 = InstanceNormalization()(conv)\n\n  leaky_relu = tf.keras.layers.LeakyReLU()(norm1)\n\n  zero_pad2 = tf.keras.layers.ZeroPadding2D()(leaky_relu)  # (bs, 41, 41, 512)\n\n  last = tf.keras.layers.Conv2D(\n      1, 4, strides=1,\n      kernel_initializer=initializer)(zero_pad2)  # (bs, 38, 38, 1)\n\n  if target:\n    return tf.keras.Model(inputs=[inp, tar], outputs=last)\n  else:\n    return tf.keras.Model(inputs=inp, outputs=last)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:23.091576Z","iopub.execute_input":"2023-02-28T11:43:23.091898Z","iopub.status.idle":"2023-02-28T11:43:23.103540Z","shell.execute_reply.started":"2023-02-28T11:43:23.091856Z","shell.execute_reply":"2023-02-28T11:43:23.102412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Put it all together","metadata":{}},{"cell_type":"code","source":"OUTPUT_CHANNELS = 3\n\ngenerator_g = unet_generator(OUTPUT_CHANNELS, norm_type='instancenorm')\ngenerator_f  = unet_generator(OUTPUT_CHANNELS, norm_type='instancenorm')\n\ndiscriminator_x  = discriminator(norm_type='instancenorm', target=False)\ndiscriminator_y  = discriminator(norm_type='instancenorm', target=False)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:23.105468Z","iopub.execute_input":"2023-02-28T11:43:23.105877Z","iopub.status.idle":"2023-02-28T11:43:25.071443Z","shell.execute_reply.started":"2023-02-28T11:43:23.105840Z","shell.execute_reply":"2023-02-28T11:43:25.070241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_obj = tf.keras.losses.BinaryCrossentropy(from_logits=True)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.072920Z","iopub.execute_input":"2023-02-28T11:43:25.073327Z","iopub.status.idle":"2023-02-28T11:43:25.078994Z","shell.execute_reply.started":"2023-02-28T11:43:25.073276Z","shell.execute_reply":"2023-02-28T11:43:25.077853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## defining the train details - loss and stuff","metadata":{}},{"cell_type":"code","source":"def discriminator_loss(real, generated):\n  real_loss = loss_obj(tf.ones_like(real), real)\n\n  generated_loss = loss_obj(tf.zeros_like(generated), generated)\n\n  total_disc_loss = real_loss + generated_loss\n\n  return total_disc_loss * 0.5","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.080532Z","iopub.execute_input":"2023-02-28T11:43:25.081450Z","iopub.status.idle":"2023-02-28T11:43:25.087647Z","shell.execute_reply.started":"2023-02-28T11:43:25.081410Z","shell.execute_reply":"2023-02-28T11:43:25.086608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generator_loss(generated):\n  return loss_obj(tf.ones_like(generated), generated)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.088964Z","iopub.execute_input":"2023-02-28T11:43:25.089953Z","iopub.status.idle":"2023-02-28T11:43:25.098701Z","shell.execute_reply.started":"2023-02-28T11:43:25.089911Z","shell.execute_reply":"2023-02-28T11:43:25.097634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calc_cycle_loss(original_image, cycled_image):\n  loss1 = tf.reduce_mean(tf.abs(original_image - cycled_image))\n\n  return LAMBDA * loss1","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.100155Z","iopub.execute_input":"2023-02-28T11:43:25.100742Z","iopub.status.idle":"2023-02-28T11:43:25.107368Z","shell.execute_reply.started":"2023-02-28T11:43:25.100692Z","shell.execute_reply":"2023-02-28T11:43:25.106253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def identity_loss(real_image, same_image):\n  loss = tf.reduce_mean(tf.abs(real_image - same_image))\n  return LAMBDA * 0.5 * loss","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.109308Z","iopub.execute_input":"2023-02-28T11:43:25.109745Z","iopub.status.idle":"2023-02-28T11:43:25.115542Z","shell.execute_reply.started":"2023-02-28T11:43:25.109696Z","shell.execute_reply":"2023-02-28T11:43:25.114403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator_g_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\ngenerator_f_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n\ndiscriminator_x_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\ndiscriminator_y_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.117213Z","iopub.execute_input":"2023-02-28T11:43:25.118007Z","iopub.status.idle":"2023-02-28T11:43:25.133098Z","shell.execute_reply.started":"2023-02-28T11:43:25.117967Z","shell.execute_reply":"2023-02-28T11:43:25.132142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_images(model, test_input):\n  prediction = model(test_input)\n\n  plt.figure(figsize=(12, 12))\n\n  display_list = [test_input[0], prediction[0]]\n  title = ['Input Image', 'Predicted Image']\n\n  for i in range(2):\n    plt.subplot(1, 2, i+1)\n    plt.title(title[i])\n    # getting the pixel values between [0, 1] to plot it.\n    plt.imshow(display_list[i])\n    plt.axis('off')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.134549Z","iopub.execute_input":"2023-02-28T11:43:25.134894Z","iopub.status.idle":"2023-02-28T11:43:25.141293Z","shell.execute_reply.started":"2023-02-28T11:43:25.134859Z","shell.execute_reply":"2023-02-28T11:43:25.140154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## training","metadata":{}},{"cell_type":"code","source":"@tf.function\ndef train_step(real_x, real_y):\n  # persistent is set to True because the tape is used more than\n  # once to calculate the gradients.\n  with tf.GradientTape(persistent=True) as tape:\n    # Generator G translates X -> Y\n    # Generator F translates Y -> X.\n\n    fake_y = generator_g(real_x, training=True)\n    cycled_x = generator_f(fake_y, training=True)\n\n    fake_x = generator_f(real_y, training=True)\n    cycled_y = generator_g(fake_x, training=True)\n\n    # same_x and same_y are used for identity loss.\n    same_x = generator_f(real_x, training=True)\n    same_y = generator_g(real_y, training=True)\n\n    disc_real_x = discriminator_x(real_x, training=True)\n    disc_real_y = discriminator_y(real_y, training=True)\n\n    disc_fake_x = discriminator_x(fake_x, training=True)\n    disc_fake_y = discriminator_y(fake_y, training=True)\n\n    # calculate the loss\n    gen_g_loss = generator_loss(disc_fake_y)\n    gen_f_loss = generator_loss(disc_fake_x)\n\n    total_cycle_loss = calc_cycle_loss(real_x, cycled_x) + calc_cycle_loss(real_y, cycled_y)\n\n    # Total generator loss = adversarial loss + cycle loss\n    total_gen_g_loss = gen_g_loss + total_cycle_loss + identity_loss(real_y, same_y)\n    total_gen_f_loss = gen_f_loss + total_cycle_loss + identity_loss(real_x, same_x)\n\n    disc_x_loss = discriminator_loss(disc_real_x, disc_fake_x)\n    disc_y_loss = discriminator_loss(disc_real_y, disc_fake_y)\n\n  # Calculate the gradients for generator and discriminator\n  generator_g_gradients = tape.gradient(total_gen_g_loss, \n                                        generator_g.trainable_variables)\n  generator_f_gradients = tape.gradient(total_gen_f_loss, \n                                        generator_f.trainable_variables)\n\n  discriminator_x_gradients = tape.gradient(disc_x_loss, \n                                            discriminator_x.trainable_variables)\n  discriminator_y_gradients = tape.gradient(disc_y_loss, \n                                            discriminator_y.trainable_variables)\n\n  # Apply the gradients to the optimizer\n  generator_g_optimizer.apply_gradients(zip(generator_g_gradients, \n                                            generator_g.trainable_variables))\n\n  generator_f_optimizer.apply_gradients(zip(generator_f_gradients, \n                                            generator_f.trainable_variables))\n\n  discriminator_x_optimizer.apply_gradients(zip(discriminator_x_gradients,\n                                                discriminator_x.trainable_variables))\n\n  discriminator_y_optimizer.apply_gradients(zip(discriminator_y_gradients,\n                                                discriminator_y.trainable_variables))\n  return total_cycle_loss","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.143026Z","iopub.execute_input":"2023-02-28T11:43:25.143809Z","iopub.status.idle":"2023-02-28T11:43:25.157022Z","shell.execute_reply.started":"2023-02-28T11:43:25.143773Z","shell.execute_reply":"2023-02-28T11:43:25.155937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_path = \"./checkpoints/train\"\n\nckpt = tf.train.Checkpoint(generator_g=generator_g,\n                           generator_f=generator_f,\n                           discriminator_x=discriminator_x,\n                           discriminator_y=discriminator_y,\n                           generator_g_optimizer=generator_g_optimizer,\n                           generator_f_optimizer=generator_f_optimizer,\n                           discriminator_x_optimizer=discriminator_x_optimizer,\n                           discriminator_y_optimizer=discriminator_y_optimizer)\n\nckpt_manager = tf.train.CheckpointManager(ckpt, checkpoint_path, max_to_keep=5)\n\n# if a checkpoint exists, restore the latest checkpoint.\nif ckpt_manager.latest_checkpoint:\n  ckpt.restore(ckpt_manager.latest_checkpoint)\n  print ('Latest checkpoint restored!!')","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.159471Z","iopub.execute_input":"2023-02-28T11:43:25.160278Z","iopub.status.idle":"2023-02-28T11:43:25.879211Z","shell.execute_reply.started":"2023-02-28T11:43:25.160235Z","shell.execute_reply":"2023-02-28T11:43:25.878059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_photo = next(iter(photo_ds))\nsample_monet = next(iter(train_ds))","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:25.880679Z","iopub.execute_input":"2023-02-28T11:43:25.881618Z","iopub.status.idle":"2023-02-28T11:43:26.092560Z","shell.execute_reply.started":"2023-02-28T11:43:25.881575Z","shell.execute_reply":"2023-02-28T11:43:26.091502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Analyzing the results","metadata":{}},{"cell_type":"code","source":"  plt.figure(figsize=(12, 12))\n\n  display_list = [sample_photo[0], sample_monet[0]]\n  title = ['Input Image', 'Predicted Image']\n\n  for i in range(2):\n    plt.subplot(1, 2, i+1)\n    plt.title(title[i])\n    # getting the pixel values between [0, 1] to plot it.\n    plt.imshow(display_list[i])\n    plt.axis('off')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:26.094045Z","iopub.execute_input":"2023-02-28T11:43:26.094468Z","iopub.status.idle":"2023-02-28T11:43:26.572208Z","shell.execute_reply.started":"2023-02-28T11:43:26.094425Z","shell.execute_reply":"2023-02-28T11:43:26.571268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.data.Dataset.zip((photo_ds, train_ds))","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:26.573155Z","iopub.execute_input":"2023-02-28T11:43:26.573472Z","iopub.status.idle":"2023-02-28T11:43:26.586137Z","shell.execute_reply.started":"2023-02-28T11:43:26.573440Z","shell.execute_reply":"2023-02-28T11:43:26.584877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_list = []\nfor epoch in range(EPOCHS):\n  start = time.time()\n  step_loss = 0.0\n  count = 0\n  n = 0\n  for photo_samp, monet_samp in tf.data.Dataset.zip((photo_ds, train_ds)):\n    step_loss += train_step(photo_samp, monet_samp)\n    count += 1\n    if n % 10 == 0:\n      print ('.', end='')\n    n += 1\n  loss_list.append(step_loss / count)\n  clear_output(wait=True)\n\n  generate_images(generator_g, sample_photo)\n  generate_images(generator_f, sample_photo)\n\n  if (epoch + 1) % 5 == 0:\n    ckpt_save_path = ckpt_manager.save()\n    print ('Saving checkpoint for epoch {} at {}'.format(epoch+1,\n                                                         ckpt_save_path))\n\n  print ('Time taken for epoch {} is {} sec\\n'.format(epoch + 1,\n                                                      time.time()-start))","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:43:26.587703Z","iopub.execute_input":"2023-02-28T11:43:26.588311Z","iopub.status.idle":"2023-02-28T11:52:48.934074Z","shell.execute_reply.started":"2023-02-28T11:43:26.588275Z","shell.execute_reply":"2023-02-28T11:52:48.932785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(range(EPOCHS), loss_list)","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:52:48.935555Z","iopub.execute_input":"2023-02-28T11:52:48.935952Z","iopub.status.idle":"2023-02-28T11:52:49.216480Z","shell.execute_reply.started":"2023-02-28T11:52:48.935913Z","shell.execute_reply":"2023-02-28T11:52:49.214782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i=4\nfor imager in photo_ds:\n    generate_images(generator_g, imager)\n    i -= 1\n    if i<0:\n        break","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:57:24.825732Z","iopub.execute_input":"2023-02-28T11:57:24.826109Z","iopub.status.idle":"2023-02-28T11:57:27.265749Z","shell.execute_reply.started":"2023-02-28T11:57:24.826076Z","shell.execute_reply":"2023-02-28T11:57:27.264538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator_to_monet.save(\"the_best_weights2\")","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:52:49.947196Z","iopub.status.idle":"2023-02-28T11:52:49.948334Z","shell.execute_reply.started":"2023-02-28T11:52:49.948026Z","shell.execute_reply":"2023-02-28T11:52:49.948054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! rm model.zip\n! zip -r model2.zip /kaggle/working/the_best_weights2","metadata":{"execution":{"iopub.status.busy":"2023-02-28T11:52:49.949798Z","iopub.status.idle":"2023-02-28T11:52:49.950910Z","shell.execute_reply.started":"2023-02-28T11:52:49.950638Z","shell.execute_reply":"2023-02-28T11:52:49.950677Z"},"trusted":true},"execution_count":null,"outputs":[]}]}