{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gan_monet_contents = os.listdir(\"/kaggle/input/gan-getting-started\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_tfrec_path = os.path.join('/kaggle/input/gan-getting-started/', 'monet_tfrec')\nphoto_tfrec_path = os.path.join('/kaggle/input/gan-getting-started/', 'photo_tfrec')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_description = {\n    'image': tf.io.FixedLenFeature([], tf.string),\n}","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def _parse_function(example_proto):\n    # Parse the input `tf.train.Example` proto using the feature description.\n    parsed_example = tf.io.parse_single_example(example_proto, feature_description)\n    \n    # Decode the image and reshape\n    image = tf.io.decode_jpeg(parsed_example['image'])\n    image = tf.image.resize(image, [256, 256])  # Resize to desired size\n    image = (image / 127.5) - 1  # Normalize to [-1, 1]\n    \n    return image","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_dataset = tf.data.Dataset.list_files(monet_tfrec_path + '/*.tfrec')\nmonet_dataset = monet_dataset.interleave(tf.data.TFRecordDataset, cycle_length=4)\nmonet_dataset = monet_dataset.map(_parse_function)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"photo_dataset = tf.data.Dataset.list_files(photo_tfrec_path + '/*.tfrec')\nphoto_dataset = photo_dataset.interleave(tf.data.TFRecordDataset, cycle_length=4)\nphoto_dataset = photo_dataset.map(_parse_function)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BUFFER_SIZE = 400\nBATCH_SIZE = 32\nmonet_dataset = monet_dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)\nphoto_dataset = photo_dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)\n\nmonet_dataset, photo_dataset","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_generator_model():\n    # Reshaping the images\n    inputs = tf.keras.layers.Input(shape=[256, 256, 3])\n    \n    # Encoder\n    down1 = tf.keras.layers.Conv2D(64, (4, 4), strides=2, padding='same', activation='relu')(inputs)\n    down2 = tf.keras.layers.Conv2D(128, (4, 4), strides=2, padding='same', activation='relu')(down1)\n    down3 = tf.keras.layers.Conv2D(256, (4, 4), strides=2, padding='same', activation='relu')(down2)\n    \n    # Decoder\n    up1 = tf.keras.layers.Conv2DTranspose(128, (4, 4), strides=2, padding='same', activation='relu')(down3)\n    up2 = tf.keras.layers.Conv2DTranspose(64, (4, 4), strides=2, padding='same', activation='relu')(up1)\n    \n    outputs = tf.keras.layers.Conv2DTranspose(3, (4, 4), strides=2, padding='same', activation='tanh')(up2)\n    \n    return tf.keras.Model(inputs=inputs, outputs=outputs)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_discriminator_model():\n    inputs = tf.keras.layers.Input(shape=[256, 256, 3])\n    \n    d1 = tf.keras.layers.Conv2D(64, (4, 4), strides=2, padding='same', activation='relu')(inputs)\n    d2 = tf.keras.layers.Conv2D(128, (4, 4), strides=2, padding='same', activation='relu')(d1)\n    d3 = tf.keras.layers.Conv2D(256, (4, 4), strides=2, padding='same', activation='relu')(d2)\n    \n    outputs = tf.keras.layers.Conv2D(1, (4, 4), padding='same')(d3)\n    \n    return tf.keras.Model(inputs=inputs, outputs=outputs)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def discriminator_loss(real, generated):\n    real_loss = loss_object(tf.ones_like(real), real)\n    generated_loss = loss_object(tf.zeros_like(generated), generated)\n    total_disc_loss = real_loss + generated_loss\n    return total_disc_loss","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generator_loss(generated):\n    return loss_object(tf.ones_like(generated), generated)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calc_cycle_loss(real_image, cycled_image, LAMBDA=10):\n    loss = tf.reduce_mean(tf.abs(real_image - cycled_image))\n    return LAMBDA * loss","metadata":{},"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.3)\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.3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator_g = make_generator_model()\ngenerator_f = make_generator_model()\ndiscriminator_x = make_discriminator_model()\ndiscriminator_y = make_discriminator_model()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.function\ndef train_step(real_x, real_y, generator_g, generator_f, discriminator_x, discriminator_y, \n               generator_g_optimizer, generator_f_optimizer, discriminator_x_optimizer, discriminator_y_optimizer):\n    with tf.GradientTape(persistent=True) as tape:\n        # Generate images\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        # Discriminator outputs\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        # Generator losses\n        gen_g_loss = generator_loss(disc_fake_y)\n        gen_f_loss = generator_loss(disc_fake_x)\n\n        # Total cycle consistency loss\n        total_cycle_loss = calc_cycle_loss(real_x, cycled_x) + calc_cycle_loss(real_y, cycled_y)\n\n        # Total generator loss\n        total_gen_g_loss = gen_g_loss + total_cycle_loss\n        total_gen_f_loss = gen_f_loss + total_cycle_loss\n\n        # Discriminator losses\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 gradients and apply them\n    generator_g_gradients = tape.gradient(total_gen_g_loss, generator_g.trainable_variables)\n    generator_f_gradients = tape.gradient(total_gen_f_loss, generator_f.trainable_variables)\n\n    discriminator_x_gradients = tape.gradient(disc_x_loss, discriminator_x.trainable_variables)\n    discriminator_y_gradients = tape.gradient(disc_y_loss, discriminator_y.trainable_variables)\n\n    generator_g_optimizer.apply_gradients(zip(generator_g_gradients, generator_g.trainable_variables))\n    generator_f_optimizer.apply_gradients(zip(generator_f_gradients, generator_f.trainable_variables))\n\n    discriminator_x_optimizer.apply_gradients(zip(discriminator_x_gradients, discriminator_x.trainable_variables))\n    discriminator_y_optimizer.apply_gradients(zip(discriminator_y_gradients, discriminator_y.trainable_variables))\n# Take a sample of photos for visualization\nsample_photos = next(iter(photo_dataset))\nNUM_SAMPLES = 4  # Number of samples to visualize\n\ndef generate_and_save_images(model, epoch, test_input):\n    predictions = model(test_input, training=False)\n    \n    fig = plt.figure(figsize=(12, 12))\n    \n    for i in range(predictions.shape[0]):\n        plt.subplot(4, 4, i + 1)\n        plt.imshow((predictions[i] + 1) / 2.0)\n        plt.axis('off')\n\n    plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))\n    plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 80\nfor epoch in range(EPOCHS):\n    for photo, monet in tf.data.Dataset.zip((photo_dataset, monet_dataset)):\n        train_step(photo, monet, generator_g, generator_f, discriminator_x, discriminator_y, \n                   generator_g_optimizer, generator_f_optimizer, discriminator_x_optimizer, discriminator_y_optimizer)\n    # Save generated images to visualize progress\n    if epoch % 5 == 0 or epoch == EPOCHS - 1:  # Save images every 5 epochs\n        generate_and_save_images(generator_g, epoch, sample_photos[:NUM_SAMPLES])\n        generator_g.save('generator_g_model_{}.h5'.format(epoch))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator_g = tf.keras.models.load_model('generator_g_model_79.h5')\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess_image(image_path):\n    image = tf.io.read_file(image_path)\n    image = tf.io.decode_jpeg(image)\n    image = tf.image.resize(image, [256, 256])\n    image = (tf.cast(image, tf.float32) / 127.5) - 1  # Normalize to [-1, 1]\n    image = tf.expand_dims(image, 0)  # Add batch dimension\n    return image","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"photo_directory = '/kaggle/input/gan-getting-started/photo_jpg'\noutput_directory = 'converted'\nos.makedirs(output_directory, exist_ok=True)\n\nfor filename in os.listdir(photo_directory):\n    if filename.endswith(\".jpg\"):\n        image_path = os.path.join(photo_directory, filename)\n        input_image = preprocess_image(image_path)\n        transformed_image = generator_g.predict(input_image)\n        transformed_image = (transformed_image + 1) * 127.5  # Denormalize to [0, 255]\n        transformed_image = tf.squeeze(transformed_image).numpy().astype(np.uint8)  # Remove batch dimension and convert to uint8\n\n        # Save the transformed image\n        output_path = os.path.join(output_directory, 'monet_' + filename)\n        tf.keras.preprocessing.image.save_img(output_path, transformed_image)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!zip -r images.zip converted\n","metadata":{},"execution_count":null,"outputs":[]}]}