{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"dockerImageVersionId":30648,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Preparations & Installations","metadata":{}},{"cell_type":"code","source":"import warnings\n\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:08.328174Z","iopub.execute_input":"2024-02-20T17:12:08.328666Z","iopub.status.idle":"2024-02-20T17:12:08.339961Z","shell.execute_reply.started":"2024-02-20T17:12:08.328623Z","shell.execute_reply":"2024-02-20T17:12:08.338967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\n!pip install git+https://github.com/tensorflow/examples.git","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:08.341736Z","iopub.execute_input":"2024-02-20T17:12:08.342036Z","iopub.status.idle":"2024-02-20T17:12:30.911207Z","shell.execute_reply.started":"2024-02-20T17:12:08.342009Z","shell.execute_reply":"2024-02-20T17:12:30.910008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_datasets as tfds\nfrom tensorflow_examples.models.pix2pix import pix2pix\n\nimport os\nimport time\nimport matplotlib.pyplot as plt\nfrom IPython.display import clear_output\nfrom kaggle_datasets import KaggleDatasets\n\nAUTOTUNE = tf.data.AUTOTUNE","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:30.912505Z","iopub.execute_input":"2024-02-20T17:12:30.912818Z","iopub.status.idle":"2024-02-20T17:12:44.673395Z","shell.execute_reply.started":"2024-02-20T17:12:30.912792Z","shell.execute_reply":"2024-02-20T17:12:44.672460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading dataset & Preprocessing","metadata":{}},{"cell_type":"code","source":"GCS_PATH = KaggleDatasets().get_gcs_path()","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:44.675656Z","iopub.execute_input":"2024-02-20T17:12:44.676699Z","iopub.status.idle":"2024-02-20T17:12:45.190647Z","shell.execute_reply.started":"2024-02-20T17:12:44.676646Z","shell.execute_reply":"2024-02-20T17:12:45.189803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":{"execution":{"iopub.status.busy":"2024-02-20T17:12:45.191640Z","iopub.execute_input":"2024-02-20T17:12:45.191921Z","iopub.status.idle":"2024-02-20T17:12:46.183672Z","shell.execute_reply.started":"2024-02-20T17:12:45.191898Z","shell.execute_reply":"2024-02-20T17:12:46.182859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE= [256,256]                                            \ndef decode_img(image):                                           \n    image= tf.image.decode_jpeg(image,channels= 3)\n    image= (tf.cast(image, tf.float32)/255)*2 -1\n    image= tf.reshape(image, shape= [*IMAGE_SIZE,3])\n    return image\n\ndef read_tfrec(example):\n    tfrec_format= {\n        'image_name': tf.io.FixedLenFeature([], tf.string),\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":{"execution":{"iopub.status.busy":"2024-02-20T17:12:46.184952Z","iopub.execute_input":"2024-02-20T17:12:46.185234Z","iopub.status.idle":"2024-02-20T17:12:46.193935Z","shell.execute_reply.started":"2024-02-20T17:12:46.185211Z","shell.execute_reply":"2024-02-20T17:12:46.193020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_data(files):\n    data= tf.data.TFRecordDataset(files)\n    data= data.map(read_tfrec)\n    return data","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:46.194969Z","iopub.execute_input":"2024-02-20T17:12:46.195220Z","iopub.status.idle":"2024-02-20T17:12:46.205777Z","shell.execute_reply.started":"2024-02-20T17:12:46.195197Z","shell.execute_reply":"2024-02-20T17:12:46.204919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_data= load_data(monet_files).batch(1)\nphoto_data= load_data(photo_files).batch(1)","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:46.207138Z","iopub.execute_input":"2024-02-20T17:12:46.207442Z","iopub.status.idle":"2024-02-20T17:12:46.998913Z","shell.execute_reply.started":"2024-02-20T17:12:46.207420Z","shell.execute_reply":"2024-02-20T17:12:46.997979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_monet = monet_data\ntrain_photo = photo_data.take(300)\ntest_photo = photo_data.skip(300)","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:47.002596Z","iopub.execute_input":"2024-02-20T17:12:47.002897Z","iopub.status.idle":"2024-02-20T17:12:47.012478Z","shell.execute_reply.started":"2024-02-20T17:12:47.002872Z","shell.execute_reply":"2024-02-20T17:12:47.011701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BUFFER_SIZE = 300\nBATCH_SIZE = 1\nIMG_WIDTH = 256\nIMG_HEIGHT = 256","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:47.013495Z","iopub.execute_input":"2024-02-20T17:12:47.013826Z","iopub.status.idle":"2024-02-20T17:12:47.020684Z","shell.execute_reply.started":"2024-02-20T17:12:47.013783Z","shell.execute_reply":"2024-02-20T17:12:47.019524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_photo = next(iter(train_photo))\nsample_monet = next(iter(train_monet))","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:47.021789Z","iopub.execute_input":"2024-02-20T17:12:47.022431Z","iopub.status.idle":"2024-02-20T17:12:51.376463Z","shell.execute_reply.started":"2024-02-20T17:12:47.022399Z","shell.execute_reply":"2024-02-20T17:12:51.375681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.subplot(121)\nplt.title('Photo')\nplt.imshow(sample_photo[0] * 0.5 + 0.5)\n\nplt.subplot(122)\nplt.title('Monet')\nplt.imshow(sample_monet[0] * 0.5 + 0.5)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:51.377550Z","iopub.execute_input":"2024-02-20T17:12:51.377849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating models","metadata":{}},{"cell_type":"code","source":"'''\ngenerator_g - photo to monet\ndiscriminator_y - estimating generator_g (photo-to-monet assessment)\ngenerator_f - monet to photo\ndiscriminator_y - estimating generator_f (monet-to-photo assessment)\n'''\n\nOUTPUT_CHANNELS = 3\n\ngenerator_g = pix2pix.unet_generator(OUTPUT_CHANNELS, norm_type='instancenorm')\ngenerator_f = pix2pix.unet_generator(OUTPUT_CHANNELS, norm_type='instancenorm')\n\ndiscriminator_x = pix2pix.discriminator(norm_type='instancenorm', target=False)\ndiscriminator_y = pix2pix.discriminator(norm_type='instancenorm', target=False)","metadata":{"execution":{"iopub.status.idle":"2024-02-20T17:12:53.808752Z","shell.execute_reply.started":"2024-02-20T17:12:51.791132Z","shell.execute_reply":"2024-02-20T17:12:53.807918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# initial generation results (before training)\n\nto_monet = generator_g(sample_photo)\nplt.figure(figsize=(8, 8))\ncontrast = 8\n\nimgs = [sample_photo, to_monet]\ntitle = ['Photo', 'To Monet']\n\nfor i in range(len(imgs)):\n  plt.subplot(2, 2, i+1)\n  plt.title(title[i])\n  if i % 2 == 0:\n    plt.imshow(imgs[i][0] * 0.5 + 0.5)\n  else:\n    plt.imshow(imgs[i][0] * 0.5 * contrast + 0.5)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:53.809925Z","iopub.execute_input":"2024-02-20T17:12:53.810296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LAMBDA = 10","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:56.656866Z","iopub.execute_input":"2024-02-20T17:12:56.657156Z","iopub.status.idle":"2024-02-20T17:12:56.661604Z","shell.execute_reply.started":"2024-02-20T17:12:56.657132Z","shell.execute_reply":"2024-02-20T17:12:56.660466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_obj = tf.keras.losses.BinaryCrossentropy(from_logits=True)","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:56.662749Z","iopub.execute_input":"2024-02-20T17:12:56.663442Z","iopub.status.idle":"2024-02-20T17:12:56.676273Z","shell.execute_reply.started":"2024-02-20T17:12:56.663407Z","shell.execute_reply":"2024-02-20T17:12:56.675503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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":"2024-02-20T17:12:56.677478Z","iopub.execute_input":"2024-02-20T17:12:56.677839Z","iopub.status.idle":"2024-02-20T17:12:56.685552Z","shell.execute_reply.started":"2024-02-20T17:12:56.677807Z","shell.execute_reply":"2024-02-20T17:12:56.684839Z"},"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":"2024-02-20T17:12:56.686442Z","iopub.execute_input":"2024-02-20T17:12:56.687109Z","iopub.status.idle":"2024-02-20T17:12:56.694012Z","shell.execute_reply.started":"2024-02-20T17:12:56.687086Z","shell.execute_reply":"2024-02-20T17:12:56.693131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calc_cycle_loss(real_image, cycled_image):\n  loss1 = tf.reduce_mean(tf.abs(real_image - cycled_image))\n\n  return LAMBDA * loss1","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:56.695237Z","iopub.execute_input":"2024-02-20T17:12:56.696191Z","iopub.status.idle":"2024-02-20T17:12:56.703233Z","shell.execute_reply.started":"2024-02-20T17:12:56.696159Z","shell.execute_reply":"2024-02-20T17:12:56.702464Z"},"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":"2024-02-20T17:12:56.704263Z","iopub.execute_input":"2024-02-20T17:12:56.704625Z","iopub.status.idle":"2024-02-20T17:12:56.712428Z","shell.execute_reply.started":"2024-02-20T17:12:56.704602Z","shell.execute_reply":"2024-02-20T17:12:56.711536Z"},"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":"2024-02-20T17:12:56.713909Z","iopub.execute_input":"2024-02-20T17:12:56.714161Z","iopub.status.idle":"2024-02-20T17:12:56.729850Z","shell.execute_reply.started":"2024-02-20T17:12:56.714141Z","shell.execute_reply":"2024-02-20T17:12:56.729029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"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":"2024-02-20T17:12:56.731305Z","iopub.execute_input":"2024-02-20T17:12:56.731597Z","iopub.status.idle":"2024-02-20T17:12:56.738619Z","shell.execute_reply.started":"2024-02-20T17:12:56.731576Z","shell.execute_reply":"2024-02-20T17:12:56.737792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 45","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:56.739592Z","iopub.execute_input":"2024-02-20T17:12:56.739892Z","iopub.status.idle":"2024-02-20T17:12:56.750396Z","shell.execute_reply.started":"2024-02-20T17:12:56.739869Z","shell.execute_reply":"2024-02-20T17:12:56.749499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for dinamic visualization\ndef 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] * 0.5 + 0.5)\n    plt.axis('off')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:56.755132Z","iopub.execute_input":"2024-02-20T17:12:56.755449Z","iopub.status.idle":"2024-02-20T17:12:56.761626Z","shell.execute_reply.started":"2024-02-20T17:12:56.755419Z","shell.execute_reply":"2024-02-20T17:12:56.760627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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_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))","metadata":{"execution":{"iopub.status.busy":"2024-02-20T17:12:56.762644Z","iopub.execute_input":"2024-02-20T17:12:56.762939Z","iopub.status.idle":"2024-02-20T17:12:56.774784Z","shell.execute_reply.started":"2024-02-20T17:12:56.762917Z","shell.execute_reply":"2024-02-20T17:12:56.773873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# training itself\n\nfor epoch in range(EPOCHS):\n  start = time.time()\n\n  n = 0\n  for image_x, image_y in tf.data.Dataset.zip((train_photo, train_monet)):\n    train_step(image_x, image_y)\n    if n % 10 == 0:\n      print ('.', end='')\n    n += 1\n\n  clear_output(wait=True)\n  # Using a consistent image (sample_photo) so that the progress of the model\n  # is clearly visible.\n  generate_images(generator_g, 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":"2024-02-20T17:12:56.775796Z","iopub.execute_input":"2024-02-20T17:12:56.776137Z","iopub.status.idle":"2024-02-20T18:02:49.517173Z","shell.execute_reply.started":"2024-02-20T17:12:56.776075Z","shell.execute_reply":"2024-02-20T18:02:49.516055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualizing results","metadata":{}},{"cell_type":"code","source":"# Run the trained model on the test dataset\nfor inp in test_photo.skip(5).take(5):\n  generate_images(generator_g, inp)","metadata":{"execution":{"iopub.status.busy":"2024-02-20T18:02:49.518607Z","iopub.execute_input":"2024-02-20T18:02:49.519275Z","iopub.status.idle":"2024-02-20T18:02:54.137649Z","shell.execute_reply.started":"2024-02-20T18:02:49.519238Z","shell.execute_reply":"2024-02-20T18:02:54.136835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Saving results","metadata":{}},{"cell_type":"code","source":"import PIL\n!mkdir /kaggle/working/images\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2024-02-20T18:02:54.138904Z","iopub.execute_input":"2024-02-20T18:02:54.139158Z","iopub.status.idle":"2024-02-20T18:02:55.157055Z","shell.execute_reply.started":"2024-02-20T18:02:54.139136Z","shell.execute_reply":"2024-02-20T18:02:55.155726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i = 1\nfor image in photo_data:\n    pred = generator_g(image, training=False)[0].numpy()\n    pred = (pred*127.5 + 127.5).astype(np.uint8)\n    im = PIL.Image.fromarray(pred)\n    im.save(\"/kaggle/working/images/\" + str(i) + \".jpg\")\n    i += 1","metadata":{"execution":{"iopub.status.busy":"2024-02-20T18:02:55.158809Z","iopub.execute_input":"2024-02-20T18:02:55.159143Z","iopub.status.idle":"2024-02-20T18:09:40.345690Z","shell.execute_reply.started":"2024-02-20T18:02:55.159109Z","shell.execute_reply":"2024-02-20T18:09:40.344615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nshutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/working/images\")","metadata":{"execution":{"iopub.status.busy":"2024-02-20T18:09:40.347128Z","iopub.execute_input":"2024-02-20T18:09:40.347425Z","iopub.status.idle":"2024-02-20T18:09:45.076817Z","shell.execute_reply.started":"2024-02-20T18:09:40.347400Z","shell.execute_reply":"2024-02-20T18:09:45.075834Z"},"trusted":true},"execution_count":null,"outputs":[]}]}