{"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":"tpu1vmV38","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"},{"sourceId":10030853,"sourceType":"datasetVersion","datasetId":6177898}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"pip install git+https://github.com/tensorflow/examples.git\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:05:31.994987Z","iopub.execute_input":"2024-12-05T04:05:31.995846Z","iopub.status.idle":"2024-12-05T04:05:49.990484Z","shell.execute_reply.started":"2024-12-05T04:05:31.995797Z","shell.execute_reply":"2024-12-05T04:05:49.989475Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import kagglehub","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:05:49.992192Z","iopub.execute_input":"2024-12-05T04:05:49.992483Z","iopub.status.idle":"2024-12-05T04:05:50.23174Z","shell.execute_reply.started":"2024-12-05T04:05:49.992452Z","shell.execute_reply":"2024-12-05T04:05:50.231108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset_path = kagglehub.dataset_download('luongminhnhat7/dataset')\nprint(\"Dataset found.\")","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:05:50.232631Z","iopub.execute_input":"2024-12-05T04:05:50.232853Z","iopub.status.idle":"2024-12-05T04:05:51.483372Z","shell.execute_reply.started":"2024-12-05T04:05:50.232831Z","shell.execute_reply":"2024-12-05T04:05:51.482516Z"}},"outputs":[],"execution_count":null},{"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\n\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print('Device:', tpu.master())\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nexcept:\n    strategy = tf.distribute.get_strategy()\nprint('Number of replicas:', strategy.num_replicas_in_sync)\n\nAUTOTUNE = tf.data.experimental.AUTOTUNE\n    \nprint(tf.__version__)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:05:51.485037Z","iopub.execute_input":"2024-12-05T04:05:51.485316Z","iopub.status.idle":"2024-12-05T04:06:10.380764Z","shell.execute_reply.started":"2024-12-05T04:05:51.485289Z","shell.execute_reply":"2024-12-05T04:06:10.379859Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMG_WIDTH = 256\nIMG_HEIGHT = 256\nBUFFER_SIZE = 1000\nBATCH_SIZE = 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.381797Z","iopub.execute_input":"2024-12-05T04:06:10.382247Z","iopub.status.idle":"2024-12-05T04:06:10.386121Z","shell.execute_reply.started":"2024-12-05T04:06:10.382219Z","shell.execute_reply":"2024-12-05T04:06:10.385328Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# normalizing the images to [-1, 1]\ndef normalize(image):\n  image = tf.cast(image, tf.float32)\n  image = (image / 127.5) - 1\n  return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.387146Z","iopub.execute_input":"2024-12-05T04:06:10.387448Z","iopub.status.idle":"2024-12-05T04:06:10.408144Z","shell.execute_reply.started":"2024-12-05T04:06:10.387422Z","shell.execute_reply":"2024-12-05T04:06:10.407352Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def random_crop(image):\n  cropped_image = tf.image.random_crop(\n      image, size=[IMG_HEIGHT, IMG_WIDTH, 3])\n\n  return cropped_image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.409011Z","iopub.execute_input":"2024-12-05T04:06:10.409278Z","iopub.status.idle":"2024-12-05T04:06:10.42138Z","shell.execute_reply.started":"2024-12-05T04:06:10.409253Z","shell.execute_reply":"2024-12-05T04:06:10.420603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def random_jitter(image):\n  # resizing to 286 x 286 x 3\n  image = tf.image.resize(image, [286, 286],\n                          method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)\n\n  # randomly cropping to 256 x 256 x 3\n  image = random_crop(image)\n\n  # random mirroring\n  image = tf.image.random_flip_left_right(image)\n\n  return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.422375Z","iopub.execute_input":"2024-12-05T04:06:10.422691Z","iopub.status.idle":"2024-12-05T04:06:10.432727Z","shell.execute_reply.started":"2024-12-05T04:06:10.422655Z","shell.execute_reply":"2024-12-05T04:06:10.432142Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def preprocess_image_train(image, label):\n  image = random_jitter(image)\n  image = normalize(image)\n  return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.433522Z","iopub.execute_input":"2024-12-05T04:06:10.433755Z","iopub.status.idle":"2024-12-05T04:06:10.445291Z","shell.execute_reply.started":"2024-12-05T04:06:10.433731Z","shell.execute_reply":"2024-12-05T04:06:10.44452Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def preprocess_image_test(image, label):\n  image = normalize(image)\n  return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.44787Z","iopub.execute_input":"2024-12-05T04:06:10.448158Z","iopub.status.idle":"2024-12-05T04:06:10.458075Z","shell.execute_reply.started":"2024-12-05T04:06:10.448134Z","shell.execute_reply":"2024-12-05T04:06:10.457287Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import glob\nPHOTO_TFRECORD = glob.glob(dataset_path + '/Monet_Datasets_Zip/train_tfrec/train_tfrec/photo/*.tfrec')\nMONET_TFRECORD = glob.glob(dataset_path + '/Monet_Datasets_Zip/train_tfrec/train_tfrec/monet/*.tfrec')\n\n\ndef parse_tfrecord(example):\n    feature_description = {\n        'image': tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, feature_description)\n    image = tf.image.decode_jpeg(example['image'], channels=3)\n    image = tf.image.resize(image, [IMG_HEIGHT, IMG_WIDTH])\n    image = normalize(image)\n    return image\n\nphoto_dataset = tf.data.TFRecordDataset(PHOTO_TFRECORD).map(parse_tfrecord, num_parallel_calls=AUTOTUNE)\nmonet_dataset = tf.data.TFRecordDataset(MONET_TFRECORD).map(parse_tfrecord, num_parallel_calls=AUTOTUNE)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:10.4592Z","iopub.execute_input":"2024-12-05T04:06:10.459566Z","iopub.status.idle":"2024-12-05T04:06:11.712277Z","shell.execute_reply.started":"2024-12-05T04:06:10.45953Z","shell.execute_reply":"2024-12-05T04:06:11.711554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nprint(os.listdir(dataset_path + '/Monet_Datasets_Zip/train_tfrec/train_tfrec/photo'))\nprint(os.listdir(dataset_path + '/Monet_Datasets_Zip/train_tfrec/train_tfrec/monet'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:11.713286Z","iopub.execute_input":"2024-12-05T04:06:11.713523Z","iopub.status.idle":"2024-12-05T04:06:11.719724Z","shell.execute_reply.started":"2024-12-05T04:06:11.7135Z","shell.execute_reply":"2024-12-05T04:06:11.718864Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_photos = photo_dataset.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(AUTOTUNE)\ntrain_monets = monet_dataset.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(AUTOTUNE)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:11.720886Z","iopub.execute_input":"2024-12-05T04:06:11.721488Z","iopub.status.idle":"2024-12-05T04:06:11.746928Z","shell.execute_reply.started":"2024-12-05T04:06:11.72145Z","shell.execute_reply":"2024-12-05T04:06:11.746326Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_photo = next(iter(train_photos))\nsample_monet = next(iter(train_monets))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:11.747734Z","iopub.execute_input":"2024-12-05T04:06:11.747933Z","iopub.status.idle":"2024-12-05T04:06:13.438659Z","shell.execute_reply.started":"2024-12-05T04:06:11.747912Z","shell.execute_reply":"2024-12-05T04:06:13.437697Z"}},"outputs":[],"execution_count":null},{"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('Photo with random jitter')\nplt.imshow(random_jitter(sample_photo[0]) * 0.5 + 0.5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:13.43988Z","iopub.execute_input":"2024-12-05T04:06:13.440274Z","iopub.status.idle":"2024-12-05T04:06:14.111297Z","shell.execute_reply.started":"2024-12-05T04:06:13.440236Z","shell.execute_reply":"2024-12-05T04:06:14.110472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.subplot(121)\nplt.title('Monet')\nplt.imshow(sample_monet[0] * 0.5 + 0.5)\n\nplt.subplot(122)\nplt.title('Monet with random jitter')\nplt.imshow(random_jitter(sample_monet[0]) * 0.5 + 0.5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:14.112455Z","iopub.execute_input":"2024-12-05T04:06:14.112798Z","iopub.status.idle":"2024-12-05T04:06:14.736682Z","shell.execute_reply.started":"2024-12-05T04:06:14.11276Z","shell.execute_reply":"2024-12-05T04:06:14.735809Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"OUTPUT_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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:14.737645Z","iopub.execute_input":"2024-12-05T04:06:14.737901Z","iopub.status.idle":"2024-12-05T04:06:15.513868Z","shell.execute_reply.started":"2024-12-05T04:06:14.737876Z","shell.execute_reply":"2024-12-05T04:06:15.513134Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"to_monet = generator_g(sample_photo)\nto_photo = generator_f(sample_monet)\n\nplt.figure(figsize=(8, 8))\nimgs = [sample_photo, to_monet, sample_monet, to_photo]\ntitles = ['Photo', 'To Monet', 'Monet', 'To Photo']\n\nfor i in range(4):\n    plt.subplot(2, 2, i + 1)\n    plt.title(titles[i])\n    plt.imshow(imgs[i][0] * 0.5 + 0.5)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:15.514941Z","iopub.execute_input":"2024-12-05T04:06:15.515246Z","iopub.status.idle":"2024-12-05T04:06:20.151935Z","shell.execute_reply.started":"2024-12-05T04:06:15.515218Z","shell.execute_reply":"2024-12-05T04:06:20.151051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8, 8))\n\nplt.subplot(121)\nplt.title('Is a real photo?')\nplt.imshow(discriminator_y(sample_photo)[0, ..., -1], cmap='RdBu_r')\n\nplt.subplot(122)\nplt.title('Is a real Monet?')\nplt.imshow(discriminator_x(sample_monet)[0, ..., -1], cmap='RdBu_r')\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.152967Z","iopub.execute_input":"2024-12-05T04:06:20.153313Z","iopub.status.idle":"2024-12-05T04:06:20.637593Z","shell.execute_reply.started":"2024-12-05T04:06:20.153286Z","shell.execute_reply":"2024-12-05T04:06:20.636655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"LAMBDA = 10","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.638837Z","iopub.execute_input":"2024-12-05T04:06:20.639074Z","iopub.status.idle":"2024-12-05T04:06:20.642387Z","shell.execute_reply.started":"2024-12-05T04:06:20.639051Z","shell.execute_reply":"2024-12-05T04:06:20.641603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss_obj = tf.keras.losses.BinaryCrossentropy(from_logits=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.643495Z","iopub.execute_input":"2024-12-05T04:06:20.643829Z","iopub.status.idle":"2024-12-05T04:06:20.676484Z","shell.execute_reply.started":"2024-12-05T04:06:20.643792Z","shell.execute_reply":"2024-12-05T04:06:20.675666Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.677461Z","iopub.execute_input":"2024-12-05T04:06:20.6777Z","iopub.status.idle":"2024-12-05T04:06:20.691376Z","shell.execute_reply.started":"2024-12-05T04:06:20.677674Z","shell.execute_reply":"2024-12-05T04:06:20.690557Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def generator_loss(generated):\n  return loss_obj(tf.ones_like(generated), generated)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.692978Z","iopub.execute_input":"2024-12-05T04:06:20.693347Z","iopub.status.idle":"2024-12-05T04:06:20.702352Z","shell.execute_reply.started":"2024-12-05T04:06:20.693311Z","shell.execute_reply":"2024-12-05T04:06:20.701722Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.703272Z","iopub.execute_input":"2024-12-05T04:06:20.703617Z","iopub.status.idle":"2024-12-05T04:06:20.715304Z","shell.execute_reply.started":"2024-12-05T04:06:20.703592Z","shell.execute_reply":"2024-12-05T04:06:20.714698Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.716184Z","iopub.execute_input":"2024-12-05T04:06:20.716388Z","iopub.status.idle":"2024-12-05T04:06:20.726145Z","shell.execute_reply.started":"2024-12-05T04:06:20.716367Z","shell.execute_reply":"2024-12-05T04:06:20.725543Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.727179Z","iopub.execute_input":"2024-12-05T04:06:20.727739Z","iopub.status.idle":"2024-12-05T04:06:20.749202Z","shell.execute_reply.started":"2024-12-05T04:06:20.727702Z","shell.execute_reply":"2024-12-05T04:06:20.748506Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.750058Z","iopub.execute_input":"2024-12-05T04:06:20.750321Z","iopub.status.idle":"2024-12-05T04:06:20.75635Z","shell.execute_reply.started":"2024-12-05T04:06:20.750297Z","shell.execute_reply":"2024-12-05T04:06:20.755544Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"EPOCHS = 120","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.759431Z","iopub.execute_input":"2024-12-05T04:06:20.759644Z","iopub.status.idle":"2024-12-05T04:06:20.774372Z","shell.execute_reply.started":"2024-12-05T04:06:20.759623Z","shell.execute_reply":"2024-12-05T04:06:20.773723Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def generate_images(model, test_input):\n    # Ensure the input has a batch dimension of 1\n    if len(test_input.shape) == 3:  # Shape should be (256, 256, 3)\n        test_input = tf.expand_dims(test_input, axis=0)\n    \n    # Generate the prediction\n    prediction = model(test_input, training=False)\n\n    # Plot the input and the prediction\n    plt.figure(figsize=(12, 12))\n    display_list = [test_input[0], prediction[0]]\n    titles = ['Input Image', 'Predicted Image']\n\n    for i in range(2):\n        plt.subplot(1, 2, i + 1)\n        plt.title(titles[i])\n        plt.imshow((display_list[i] * 0.5 + 0.5))  # Normalize to [0, 1] for display\n        plt.axis('off')\n\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.775229Z","iopub.execute_input":"2024-12-05T04:06:20.775563Z","iopub.status.idle":"2024-12-05T04:06:20.787801Z","shell.execute_reply.started":"2024-12-05T04:06:20.775537Z","shell.execute_reply":"2024-12-05T04:06:20.787194Z"}},"outputs":[],"execution_count":null},{"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))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.788714Z","iopub.execute_input":"2024-12-05T04:06:20.788948Z","iopub.status.idle":"2024-12-05T04:06:20.802148Z","shell.execute_reply.started":"2024-12-05T04:06:20.788925Z","shell.execute_reply":"2024-12-05T04:06:20.80153Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for epoch in range(EPOCHS):\n    start = time.time()\n\n    for image_photo, image_monet in tf.data.Dataset.zip((train_photos, train_monets)):\n        train_step(image_photo, image_monet)\n\n    clear_output(wait=True)\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, ckpt_save_path))\n\n    print('Time taken for epoch {} is {} sec\\n'.format(epoch + 1, time.time() - start))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-05T04:06:20.802972Z","iopub.execute_input":"2024-12-05T04:06:20.803276Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Run the trained model on the test dataset\nfor test_photo in photo_dataset.take(5): \n    generate_images(generator_g, test_photo)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import PIL\nimport numpy as np\n\n# Create a directory to save the images\nos.makedirs(\"../images\", exist_ok=True)\n\ni = 1\nfor img_batch in train_photos:  # Use train_photos to ensure batched input\n    # Get the prediction for the current batch\n    prediction = generator_g(img_batch, training=False)[0].numpy()\n    # Convert prediction to uint8 format for saving as an image\n    prediction = (prediction * 127.5 + 127.5).astype(np.uint8)\n    # Save the image\n    im = PIL.Image.fromarray(prediction)\n    im.save(f\"../images/{i}.jpg\")\n    i += 1\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\nshutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/images\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}