{"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"},{"sourceId":9559296,"sourceType":"datasetVersion","datasetId":5806740},{"sourceId":1102,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":949,"modelId":117}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import tensorflow as tf\nfrom tqdm import tqdm\nimport numpy as np\nfrom PIL import Image\nimport zipfile\nimport os\nimport shutil\nimport matplotlib.pyplot as plt\nimport numpy as np","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2024-10-06T10:17:31.524752Z","iopub.execute_input":"2024-10-06T10:17:31.525248Z","iopub.status.idle":"2024-10-06T10:17:31.532446Z","shell.execute_reply.started":"2024-10-06T10:17:31.525192Z","shell.execute_reply":"2024-10-06T10:17:31.530955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\n\ndef residual_block(x, filters):\n    \"\"\" A simple residual block that adds the input to the output. \"\"\"\n    shortcut = x\n    x = tf.keras.layers.Conv2D(filters, kernel_size=3, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.ReLU()(x)\n\n    x = tf.keras.layers.Conv2D(filters, kernel_size=3, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n\n    x = tf.keras.layers.add([shortcut, x])  # Adding the shortcut\n    return tf.keras.layers.ReLU()(x)\n\ndef build_generator():\n    inputs = tf.keras.layers.Input(shape=(256, 256, 3))\n    \n    # Initial Convolutional Layer\n    x = tf.keras.layers.Conv2D(64, kernel_size=7, padding='same')(inputs)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.ReLU()(x)\n\n    # Downsampling\n    x = tf.keras.layers.Conv2D(128, kernel_size=3, strides=2, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.ReLU()(x)\n\n    # Residual Blocks\n    for _ in range(6):  # Six residual blocks\n        x = residual_block(x, 128)\n\n    # Upsampling\n    x = tf.keras.layers.Conv2DTranspose(128, kernel_size=3, strides=2, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.ReLU()(x)\n\n    x = tf.keras.layers.Conv2DTranspose(64, kernel_size=3, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.ReLU()(x)\n\n    # Output Layer\n    outputs = tf.keras.layers.Conv2D(3, kernel_size=7, padding='same', activation='tanh')(x)\n\n    model = tf.keras.Model(inputs, outputs)\n    return model\n\ndef build_discriminator():\n    inputs = tf.keras.layers.Input(shape=(256, 256, 3))\n\n    # Downsampling Layers with Leaky ReLU and Instance Normalization\n    x = tf.keras.layers.Conv2D(64, kernel_size=4, strides=2, padding='same')(inputs)\n    x = tf.keras.layers.LeakyReLU(negative_slope=0.2)(x)  # Updated here\n\n    x = tf.keras.layers.Conv2D(128, kernel_size=4, strides=2, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.LeakyReLU(negative_slope=0.2)(x)  # Updated here\n\n    x = tf.keras.layers.Conv2D(256, kernel_size=4, strides=2, padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.LeakyReLU(negative_slope=0.2)(x)  # Updated here\n\n    # Final Layer\n    outputs = tf.keras.layers.Conv2D(1, kernel_size=4, padding='same', activation='sigmoid')(x)\n\n    model = tf.keras.Model(inputs, outputs)\n    return model","metadata":{"execution":{"iopub.status.busy":"2024-10-06T10:17:31.638863Z","iopub.execute_input":"2024-10-06T10:17:31.640198Z","iopub.status.idle":"2024-10-06T10:17:31.663240Z","shell.execute_reply.started":"2024-10-06T10:17:31.640146Z","shell.execute_reply":"2024-10-06T10:17:31.661797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build generators and discriminators\n# generator_g = build_generator()  # Generator for photos to Monet\ngenerator_g = tf.keras.models.load_model('/kaggle/input/competition-models/something of a painter/generator_g.keras')\n# generator_f = build_generator()  # Generator for Monet to photos\n# discriminator_x = build_discriminator()  # Discriminator for photos\n# discriminator_y = build_discriminator()  # Discriminator for Monet images\n\n# # Optimizers\n# generator_g_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n# generator_f_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n# discriminator_x_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n# discriminator_y_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)","metadata":{"execution":{"iopub.status.busy":"2024-10-06T10:17:32.819401Z","iopub.execute_input":"2024-10-06T10:17:32.819947Z","iopub.status.idle":"2024-10-06T10:17:33.954661Z","shell.execute_reply.started":"2024-10-06T10:17:32.819898Z","shell.execute_reply":"2024-10-06T10:17:33.952973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Import necessary loss functions directly\n# from tensorflow.keras.losses import MeanSquaredError, BinaryCrossentropy\n\n# # Define loss functions\n# mse = MeanSquaredError()\n# bce = BinaryCrossentropy(from_logits=True)\n\n# def train_step(real_photo, real_monet, generator_g, generator_f, discriminator_x, discriminator_y, \n#                 generator_g_optimizer, generator_f_optimizer, discriminator_x_optimizer, discriminator_y_optimizer):\n    \n#     # Expand dimensions to add a batch size\n#     real_photo = tf.expand_dims(real_photo, axis=0)  # Add batch dimension\n#     real_monet = tf.expand_dims(real_monet, axis=0)  # Add batch dimension\n\n#     with tf.GradientTape(persistent=True) as tape:\n#         # Generate fake images\n#         fake_monet = generator_g(real_photo, training=True)\n#         cycled_photo = generator_f(fake_monet, training=True)\n\n#         fake_photo = generator_f(real_monet, training=True)\n#         cycled_monet = generator_g(fake_photo, training=True)\n\n#         # Discriminator output\n#         disc_x_real = discriminator_x(real_photo, training=True)\n#         disc_x_fake = discriminator_x(fake_photo, training=True)\n\n#         disc_y_real = discriminator_y(real_monet, training=True)\n#         disc_y_fake = discriminator_y(fake_monet, training=True)\n\n#         # Calculate losses using tf.reduce_mean\n#         gen_g_loss = tf.reduce_mean(tf.square(real_monet - fake_monet))  # Mean Squared Error for generator G\n#         gen_f_loss = tf.reduce_mean(tf.square(real_photo - fake_photo))  # Mean Squared Error for generator F\n        \n#         # Discriminator losses\n#         disc_x_loss = tf.reduce_mean(tf.keras.losses.binary_crossentropy(tf.ones_like(disc_x_real), disc_x_real, from_logits=False)) + \\\n#                       tf.reduce_mean(tf.keras.losses.binary_crossentropy(tf.zeros_like(disc_x_fake), disc_x_fake, from_logits=False))\n\n#         disc_y_loss = tf.reduce_mean(tf.keras.losses.binary_crossentropy(tf.ones_like(disc_y_real), disc_y_real, from_logits=False)) + \\\n#                       tf.reduce_mean(tf.keras.losses.binary_crossentropy(tf.zeros_like(disc_y_fake), disc_y_fake, from_logits=False))\n\n#     # Calculate gradients and apply optimizers\n#     generator_g_gradients = tape.gradient(gen_g_loss, generator_g.trainable_variables)\n#     generator_f_gradients = tape.gradient(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\n#     return gen_g_loss, gen_f_loss, disc_x_loss, disc_y_loss","metadata":{"execution":{"iopub.status.busy":"2024-10-05T19:33:48.855635Z","iopub.execute_input":"2024-10-05T19:33:48.855939Z","iopub.status.idle":"2024-10-05T19:33:48.870646Z","shell.execute_reply.started":"2024-10-05T19:33:48.855907Z","shell.execute_reply":"2024-10-05T19:33:48.869746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def train_cycle_gan(generator_g, generator_f, discriminator_x, discriminator_y, \n#                     generator_g_optimizer, generator_f_optimizer, \n#                     discriminator_x_optimizer, discriminator_y_optimizer, \n#                     monet_images, photo_images, epochs):\n#     g_loss_history = []\n    \n#     for epoch in range(epochs):\n#         # Use the smaller of the two lengths for the progress bar\n#         num_batches = min(len(photo_images), len(monet_images))\n#         pbar = tqdm(total=num_batches, desc=f\"Training Epoch {epoch + 1}/{epochs}\")\n        \n#         # Initialize accumulators for losses\n#         total_gen_g_loss = 0.0\n#         total_gen_f_loss = 0.0\n#         total_disc_x_loss = 0.0\n#         total_disc_y_loss = 0.0\n        \n#         # Loop only for the number of batches that can be formed from both datasets\n#         for i in range(num_batches):\n#             real_photo = photo_images[i]\n#             real_monet = monet_images[i]\n            \n#             # Training step\n#             gen_g_loss, gen_f_loss, disc_x_loss, disc_y_loss = train_step(\n#                 real_photo, real_monet, generator_g, generator_f, \n#                 discriminator_x, discriminator_y, \n#                 generator_g_optimizer, generator_f_optimizer, \n#                 discriminator_x_optimizer, discriminator_y_optimizer\n#             )\n\n#             # Track losses\n#             total_gen_g_loss += gen_g_loss.numpy()\n#             total_gen_f_loss += gen_f_loss.numpy()\n#             total_disc_x_loss += disc_x_loss.numpy()\n#             total_disc_y_loss += disc_y_loss.numpy()\n\n#             # Store generator G loss history\n#             g_loss_history.append(gen_g_loss.numpy())\n#             pbar.update(1)\n\n#         pbar.close()\n        \n#         # Calculate average losses for the epoch\n#         avg_gen_g_loss = total_gen_g_loss / num_batches\n#         avg_gen_f_loss = total_gen_f_loss / num_batches\n#         avg_disc_x_loss = total_disc_x_loss / num_batches\n#         avg_disc_y_loss = total_disc_y_loss / num_batches\n\n#         # Print average losses for the epoch\n#         print(f\"Epoch {epoch + 1}/{epochs}:\")\n#         print(f\"  Generator G Loss: {avg_gen_g_loss:.4f}\")\n#         print(f\"  Generator F Loss: {avg_gen_f_loss:.4f}\")\n#         print(f\"  Discriminator X Loss: {avg_disc_x_loss:.4f}\")\n#         print(f\"  Discriminator Y Loss: {avg_disc_y_loss:.4f}\")\n\n#     return g_loss_history","metadata":{"execution":{"iopub.status.busy":"2024-10-06T10:17:40.921579Z","iopub.execute_input":"2024-10-06T10:17:40.922157Z","iopub.status.idle":"2024-10-06T10:17:40.936492Z","shell.execute_reply.started":"2024-10-06T10:17:40.922108Z","shell.execute_reply":"2024-10-06T10:17:40.934637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_images(generator, real_images, zip_filename, total_images=9000):\n    images_saved = 0\n    with zipfile.ZipFile(zip_filename, 'w') as zipf:\n        for real_image in tqdm(real_images):\n            generated_image = generator(tf.expand_dims(real_image, axis=0), training=False)[0].numpy()\n            generated_image = (generated_image * 127.5 + 127.5).astype(np.uint8)  # Denormalize to [0, 255]\n            generated_image = Image.fromarray(generated_image).resize((256, 256))  # Ensure 256x256 size\n            \n            img_name = f'generated_image_{images_saved + 1}.jpg'\n            with zipf.open(img_name, 'w') as img_file:\n                generated_image.save(img_file, format='JPEG')\n            images_saved += 1\n            \n            if images_saved >= total_images:\n                break\n\n    print(f\"Finished generating and saving {images_saved} images to {zip_filename}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-06T10:19:09.210895Z","iopub.execute_input":"2024-10-06T10:19:09.211416Z","iopub.status.idle":"2024-10-06T10:19:09.222363Z","shell.execute_reply.started":"2024-10-06T10:19:09.211371Z","shell.execute_reply":"2024-10-06T10:19:09.220836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def normalize_image(image):\n    \"\"\"Normalizes the image to the range [0, 1].\"\"\"\n    image = image.astype(np.float32)  # Ensure the image is float32\n    return image / 255.0  # Scale pixel values to [0, 1]\n\ndef load_images_from_folder(folder):\n    images = []\n    for filename in tqdm(os.listdir(folder)):\n        img = Image.open(os.path.join(folder, filename)).resize((256, 256))\n        img = np.array(img)\n        img = normalize_image(img)  # Ensure images are in float32\n        if img is not None:\n            images.append(img)\n    return np.array(images)\n\nmonet_images = load_images_from_folder('/kaggle/input/gan-getting-started/monet_jpg')\nphoto_images = load_images_from_folder('/kaggle/input/gan-getting-started/photo_jpg')","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2024-10-06T10:17:47.718488Z","iopub.execute_input":"2024-10-06T10:17:47.719674Z","iopub.status.idle":"2024-10-06T10:19:00.605228Z","shell.execute_reply.started":"2024-10-06T10:17:47.719609Z","shell.execute_reply":"2024-10-06T10:19:00.603802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# history = train_cycle_gan(generator_g, generator_f, discriminator_x, discriminator_y, \n#                  generator_g_optimizer, generator_f_optimizer, \n#                  discriminator_x_optimizer, discriminator_y_optimizer, \n#                  monet_images, photo_images, epochs=50)","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2024-10-05T19:34:40.278412Z","iopub.execute_input":"2024-10-05T19:34:40.278747Z","iopub.status.idle":"2024-10-05T19:34:51.836920Z","shell.execute_reply.started":"2024-10-05T19:34:40.278712Z","shell.execute_reply":"2024-10-05T19:34:51.835444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generator_g.save('generator_g.keras')","metadata":{"execution":{"iopub.status.busy":"2024-10-05T19:35:02.687162Z","iopub.execute_input":"2024-10-05T19:35:02.688108Z","iopub.status.idle":"2024-10-05T19:35:02.850704Z","shell.execute_reply.started":"2024-10-05T19:35:02.688057Z","shell.execute_reply":"2024-10-05T19:35:02.849784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generate_images(generator_g, photo_images, zip_filename='images.zip')","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2024-10-06T10:19:12.149339Z","iopub.execute_input":"2024-10-06T10:19:12.149866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Create a directory to unzip the images\n# unzip_dir = 'unzipped_images'\n# os.makedirs(unzip_dir, exist_ok=True)\n\n# # Unzip the images\n# with zipfile.ZipFile('images.zip', 'r') as zip_ref:\n#     zip_ref.extractall(unzip_dir)\n\n# # List the images in the directory\n# images = os.listdir(unzip_dir)\n# print(len(images))","metadata":{"execution":{"iopub.status.busy":"2024-10-05T19:34:51.841743Z","iopub.status.idle":"2024-10-05T19:34:51.842091Z","shell.execute_reply.started":"2024-10-05T19:34:51.841915Z","shell.execute_reply":"2024-10-05T19:34:51.841932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Display a few images\n# plt.figure(figsize=(15, 5))\n# for i in range(min(10, len(images))):\n#     img_path = os.path.join(unzip_dir, images[i])\n#     img = Image.open(img_path)\n#     plt.subplot(1, 10, i + 1)\n#     plt.imshow(img)\n#     plt.axis('off')\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-10-05T19:34:51.843375Z","iopub.status.idle":"2024-10-05T19:34:51.843769Z","shell.execute_reply.started":"2024-10-05T19:34:51.843555Z","shell.execute_reply":"2024-10-05T19:34:51.843592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# os.remove('/kaggle/working/images.zip')\n\n# # Specify the path to the directory\n# dir_path = '/kaggle/working/unzipped_images'  # Replace with your directory path\n\n# shutil.rmtree(dir_path)","metadata":{"execution":{"iopub.status.busy":"2024-10-05T19:34:51.846127Z","iopub.status.idle":"2024-10-05T19:34:51.846634Z","shell.execute_reply.started":"2024-10-05T19:34:51.846367Z","shell.execute_reply":"2024-10-05T19:34:51.846391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}