{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.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":30918,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"GAN Getting Started\nLucas Little\nCSCA 5642 Introduction To Deep Learning","metadata":{}},{"cell_type":"code","source":"# Import necessary libraries\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport os\nimport time\nimport glob\nimport random\nfrom PIL import Image\nfrom tqdm.notebook import tqdm\nimport zipfile\nimport cv2\n\nplt.style.use('default')\n\nnp.random.seed(42)\nrandom.seed(42)\ntf.random.set_seed(42)\n\nprint(\"Num GPUs Available: \", len(tf.config.list_physical_devices('GPU')))\nprint(\"TensorFlow version:\", tf.__version__)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:30.833329Z","iopub.execute_input":"2025-03-18T03:21:30.833794Z","iopub.status.idle":"2025-03-18T03:21:30.842438Z","shell.execute_reply.started":"2025-03-18T03:21:30.833763Z","shell.execute_reply":"2025-03-18T03:21:30.841480Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"MONET_JPG_DIR = \"/kaggle/input/gan-getting-started/monet_jpg\"\nPHOTO_JPG_DIR = \"/kaggle/input/gan-getting-started/photo_jpg\"\nMONET_TFREC_DIR = \"/kaggle/input/gan-getting-started/monet_tfrec\"\nPHOTO_TFREC_DIR = \"/kaggle/input/gan-getting-started/photo_tfrec\"\n\nOUTPUT_DIR = '/kaggle/working'\n\nMODELS_DIR = os.path.join(OUTPUT_DIR, 'models')\nCHECKPOINTS_DIR = os.path.join(OUTPUT_DIR, 'checkpoints')\nSUBMISSIONS_DIR = os.path.join(OUTPUT_DIR, 'submissions')\n\nos.makedirs(MODELS_DIR, exist_ok=True)\nos.makedirs(CHECKPOINTS_DIR, exist_ok=True)\nos.makedirs(SUBMISSIONS_DIR, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:30.843449Z","iopub.execute_input":"2025-03-18T03:21:30.843709Z","iopub.status.idle":"2025-03-18T03:21:30.859431Z","shell.execute_reply.started":"2025-03-18T03:21:30.843681Z","shell.execute_reply":"2025-03-18T03:21:30.858575Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_jpg_dataset(dir_path, shuffle=True, batch_size=1):\n    \"\"\"Load a dataset from JPG files.\"\"\"\n    image_paths = [os.path.join(dir_path, fname) for fname in os.listdir(dir_path) if fname.endswith('.jpg')]\n    \n    def load_and_preprocess_image(path):\n        img = tf.io.read_file(path)\n        img = tf.image.decode_jpeg(img, channels=3)\n        img = tf.image.resize(img, [256, 256])\n        img = tf.cast(img, tf.float32)\n        img = (img / 127.5) - 1\n        return img\n    \n    dataset = tf.data.Dataset.from_tensor_slices(image_paths)\n    dataset = dataset.map(load_and_preprocess_image, num_parallel_calls=tf.data.AUTOTUNE)\n    \n    if shuffle:\n        dataset = dataset.shuffle(buffer_size=len(image_paths))\n    \n    dataset = dataset.batch(batch_size)\n    dataset = dataset.prefetch(tf.data.AUTOTUNE)\n    \n    return dataset, len(image_paths)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:30.860742Z","iopub.execute_input":"2025-03-18T03:21:30.860934Z","iopub.status.idle":"2025-03-18T03:21:30.874745Z","shell.execute_reply.started":"2025-03-18T03:21:30.860917Z","shell.execute_reply":"2025-03-18T03:21:30.874145Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def decode_image(image):\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.cast(image, tf.float32)\n    image = (image / 127.5) - 1 \n    image = tf.reshape(image, [256, 256, 3])\n    return image\n\ndef read_tfrecord(example):\n    tfrecord_format = {\n        'image': tf.io.FixedLenFeature([], tf.string)\n    }\n    example = tf.io.parse_single_example(example, tfrecord_format)\n    image = decode_image(example['image'])\n    return image\n\ndef load_tfrecord_dataset(filenames, shuffle=True, batch_size=1):\n    dataset = tf.data.TFRecordDataset(filenames)\n    dataset = dataset.map(read_tfrecord, num_parallel_calls=tf.data.AUTOTUNE)\n    \n    if shuffle:\n        dataset = dataset.shuffle(buffer_size=10000)\n    \n    dataset = dataset.batch(batch_size)\n    dataset = dataset.prefetch(tf.data.AUTOTUNE)\n    \n    return dataset","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:30.876018Z","iopub.execute_input":"2025-03-18T03:21:30.876314Z","iopub.status.idle":"2025-03-18T03:21:30.887234Z","shell.execute_reply.started":"2025-03-18T03:21:30.876287Z","shell.execute_reply":"2025-03-18T03:21:30.886562Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"datasets = {}\ncounts = {}\n\ntry:\n    if os.path.exists(MONET_JPG_DIR):\n        datasets['monet_jpg'], counts['monet_jpg'] = load_jpg_dataset(MONET_JPG_DIR, batch_size=1)\n        print(f\"Loaded {counts['monet_jpg']} Monet paintings from JPG files\")\n    \n    if os.path.exists(PHOTO_JPG_DIR):\n        datasets['photo_jpg'], counts['photo_jpg'] = load_jpg_dataset(PHOTO_JPG_DIR, batch_size=1)\n        print(f\"Loaded {counts['photo_jpg']} photographs from JPG files\")\nexcept Exception as e:\n    print(f\"Error loading JPG datasets: {e}\")\n\ntry:\n    if os.path.exists(MONET_TFREC_DIR):\n        monet_tfrecords = tf.io.gfile.glob(os.path.join(MONET_TFREC_DIR, '*.tfrec'))\n        if monet_tfrecords:\n            datasets['monet_tfrec'] = load_tfrecord_dataset(monet_tfrecords, batch_size=1)\n            print(f\"Loaded Monet paintings from TFRecord files\")\n    \n    if os.path.exists(PHOTO_TFREC_DIR):\n        photo_tfrecords = tf.io.gfile.glob(os.path.join(PHOTO_TFREC_DIR, '*.tfrec'))\n        if photo_tfrecords:\n            datasets['photo_tfrec'] = load_tfrecord_dataset(photo_tfrecords, batch_size=1)\n            print(f\"Loaded photographs from TFRecord files\")\nexcept Exception as e:\n    print(f\"Error loading TFRecord datasets: {e}\")\n\nmonet_dataset = datasets.get('monet_tfrec', datasets.get('monet_jpg'))\nphoto_dataset = datasets.get('photo_tfrec', datasets.get('photo_jpg'))\n\nif monet_dataset is not None and photo_dataset is not None:\n    print(\"Datasets loaded successfully and ready for training\")\nelse:\n    print(\"Error: Could not load required datasets\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:30.888041Z","iopub.execute_input":"2025-03-18T03:21:30.888326Z","iopub.status.idle":"2025-03-18T03:21:31.057787Z","shell.execute_reply.started":"2025-03-18T03:21:30.888307Z","shell.execute_reply":"2025-03-18T03:21:31.057072Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def downsample(filters, size, apply_batchnorm=True):\n    initializer = tf.random_normal_initializer(0., 0.02)\n    \n    result = tf.keras.Sequential()\n    result.add(tf.keras.layers.Conv2D(filters, size, strides=2, padding='same',\n                                      kernel_initializer=initializer, use_bias=False))\n    \n    if apply_batchnorm:\n        result.add(tf.keras.layers.BatchNormalization())\n    \n    result.add(tf.keras.layers.LeakyReLU())\n    \n    return result\n\ndef upsample(filters, size, apply_dropout=False):\n    initializer = tf.random_normal_initializer(0., 0.02)\n    \n    result = tf.keras.Sequential()\n    result.add(tf.keras.layers.Conv2DTranspose(filters, size, strides=2, padding='same',\n                                              kernel_initializer=initializer, use_bias=False))\n    \n    result.add(tf.keras.layers.BatchNormalization())\n    \n    if apply_dropout:\n        result.add(tf.keras.layers.Dropout(0.5))\n    \n    result.add(tf.keras.layers.ReLU())\n    \n    return result","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:31.058700Z","iopub.execute_input":"2025-03-18T03:21:31.059000Z","iopub.status.idle":"2025-03-18T03:21:31.064771Z","shell.execute_reply.started":"2025-03-18T03:21:31.058970Z","shell.execute_reply":"2025-03-18T03:21:31.063967Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def build_generator():\n    inputs = tf.keras.layers.Input(shape=[256, 256, 3])\n    \n    # Downsampling\n    down_stack = [\n        downsample(64, 4, apply_batchnorm=False),  # (128, 128, 64)\n        downsample(128, 4),  # (64, 64, 128)\n        downsample(256, 4),  # (32, 32, 256)\n        downsample(512, 4),  # (16, 16, 512)\n    ]\n    \n    # Upsampling\n    up_stack = [\n        upsample(256, 4, apply_dropout=True),  # (32, 32, 256)\n        upsample(128, 4),  # (64, 64, 128)\n        upsample(64, 4),  # (128, 128, 64)\n    ]\n    \n    initializer = tf.random_normal_initializer(0., 0.02)\n    last = tf.keras.layers.Conv2DTranspose(3, 4, strides=2, padding='same',\n                                          kernel_initializer=initializer,\n                                          activation='tanh')  # (256, 256, 3)\n    \n    x = inputs\n    \n    skips = []\n    for down in down_stack:\n        x = down(x)\n        skips.append(x)\n\n    skips = reversed(skips[:-1])\n    for up, skip in zip(up_stack, skips):\n        x = up(x)\n        x = tf.keras.layers.Concatenate()([x, skip])\n    \n    x = last(x)\n    \n    return tf.keras.Model(inputs=inputs, outputs=x)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:31.065734Z","iopub.execute_input":"2025-03-18T03:21:31.065977Z","iopub.status.idle":"2025-03-18T03:21:31.079989Z","shell.execute_reply.started":"2025-03-18T03:21:31.065956Z","shell.execute_reply":"2025-03-18T03:21:31.079066Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def build_discriminator():\n    initializer = tf.random_normal_initializer(0., 0.02)\n    \n    inp = tf.keras.layers.Input(shape=[256, 256, 3], name='input_image')\n    \n    # Downsampling\n    x = downsample(64, 4, apply_batchnorm=False)(inp)  # (128, 128, 64)\n    x = downsample(128, 4)(x)  # (64, 64, 128)\n    x = downsample(256, 4)(x)  # (32, 32, 256)\n    \n    # Final layer\n    x = tf.keras.layers.Conv2D(512, 4, strides=1, padding='same',\n                              kernel_initializer=initializer, use_bias=False)(x)  # (32, 32, 512)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.LeakyReLU()(x)\n    \n    x = tf.keras.layers.Conv2D(1, 4, strides=1, padding='same',\n                              kernel_initializer=initializer)(x)  # (32, 32, 1)\n    \n    return tf.keras.Model(inputs=inp, outputs=x)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:31.082054Z","iopub.execute_input":"2025-03-18T03:21:31.082282Z","iopub.status.idle":"2025-03-18T03:21:31.095142Z","shell.execute_reply.started":"2025-03-18T03:21:31.082264Z","shell.execute_reply":"2025-03-18T03:21:31.094349Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"generator_g = build_generator()  # Photo to Monet\ngenerator_f = build_generator()  # Monet to Photo\n\ndiscriminator_x = build_discriminator()  # Photo discriminator\ndiscriminator_y = build_discriminator()  # Monet discriminator\n\nprint(\"Generator Model Summary:\")\ngenerator_g.summary()\n\nprint(\"\\nDiscriminator Model Summary:\")\ndiscriminator_x.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:31.096400Z","iopub.execute_input":"2025-03-18T03:21:31.096619Z","iopub.status.idle":"2025-03-18T03:21:31.572548Z","shell.execute_reply.started":"2025-03-18T03:21:31.096601Z","shell.execute_reply":"2025-03-18T03:21:31.571693Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def discriminator_loss(real, generated):\n    real_loss = tf.keras.losses.BinaryCrossentropy(from_logits=True, reduction=tf.keras.losses.Reduction.NONE)(tf.ones_like(real), real)\n    generated_loss = tf.keras.losses.BinaryCrossentropy(from_logits=True, reduction=tf.keras.losses.Reduction.NONE)(tf.zeros_like(generated), generated)\n    \n    total_loss = real_loss + generated_loss\n    return tf.reduce_mean(total_loss) * 0.5\n\ndef generator_loss(generated):\n    return tf.reduce_mean(tf.keras.losses.BinaryCrossentropy(from_logits=True, reduction=tf.keras.losses.Reduction.NONE)(tf.ones_like(generated), generated))\n\ndef calc_cycle_loss(real_image, cycled_image, LAMBDA=10):\n    loss = tf.reduce_mean(tf.abs(real_image - cycled_image))\n    return LAMBDA * loss\n\ndef identity_loss(real_image, same_image, LAMBDA=5):\n    loss = tf.reduce_mean(tf.abs(real_image - same_image))\n    return LAMBDA * 0.5 * loss","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:31.573424Z","iopub.execute_input":"2025-03-18T03:21:31.573658Z","iopub.status.idle":"2025-03-18T03:21:31.579599Z","shell.execute_reply.started":"2025-03-18T03:21:31.573632Z","shell.execute_reply":"2025-03-18T03:21:31.578638Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"generator_g.save(os.path.join(MODELS_DIR, 'generator_g.keras'))\ngenerator_f.save(os.path.join(MODELS_DIR, 'generator_f.keras'))\ndiscriminator_x.save(os.path.join(MODELS_DIR, 'discriminator_x.keras'))\ndiscriminator_y.save(os.path.join(MODELS_DIR, 'discriminator_y.keras'))\n\nprint(f\"Models saved successfully to '{MODELS_DIR}'.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:31.580437Z","iopub.execute_input":"2025-03-18T03:21:31.580619Z","iopub.status.idle":"2025-03-18T03:21:32.079492Z","shell.execute_reply.started":"2025-03-18T03:21:31.580603Z","shell.execute_reply":"2025-03-18T03:21:32.078394Z"}},"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":"2025-03-18T03:21:32.080505Z","iopub.execute_input":"2025-03-18T03:21:32.080788Z","iopub.status.idle":"2025-03-18T03:21:32.094063Z","shell.execute_reply.started":"2025-03-18T03:21:32.080765Z","shell.execute_reply":"2025-03-18T03:21:32.093108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_step(real_x, real_y):\n    with tf.GradientTape(persistent=True) as tape:\n        # Generate fake images\n        fake_y = generator_g(real_x, training=True)\n        fake_x = generator_f(real_y, training=True)\n        \n        # Cycle consistency\n        cycled_x = generator_f(fake_y, training=True)\n        cycled_y = generator_g(fake_x, training=True)\n        \n        # Identity mapping\n        same_x = generator_f(real_x, training=True)\n        same_y = generator_g(real_y, training=True)\n        \n        # Discriminator outputs\n        disc_real_x = discriminator_x(real_x, training=True)\n        disc_fake_x = discriminator_x(fake_x, training=True)\n        \n        disc_real_y = discriminator_y(real_y, training=True)\n        disc_fake_y = discriminator_y(fake_y, training=True)\n        \n        # Calculate losses\n        gen_g_loss = generator_loss(disc_fake_y)\n        gen_f_loss = generator_loss(disc_fake_x)\n        \n        # Cycle consistency losses\n        cycle_loss_x = calc_cycle_loss(real_x, cycled_x)\n        cycle_loss_y = calc_cycle_loss(real_y, cycled_y)\n        total_cycle_loss = cycle_loss_x + cycle_loss_y\n        \n        # Identity losses\n        id_loss_x = identity_loss(real_x, same_x)\n        id_loss_y = identity_loss(real_y, same_y)\n        total_id_loss = id_loss_x + id_loss_y\n        \n        # Total generator losses\n        total_gen_g_loss = gen_g_loss + total_cycle_loss + total_id_loss\n        total_gen_f_loss = gen_f_loss + total_cycle_loss + total_id_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\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    # Apply gradients\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))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:32.095457Z","iopub.execute_input":"2025-03-18T03:21:32.095686Z","iopub.status.idle":"2025-03-18T03:21:32.119064Z","shell.execute_reply.started":"2025-03-18T03:21:32.095668Z","shell.execute_reply":"2025-03-18T03:21:32.118300Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"checkpoint = tf.train.Checkpoint(\n    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)\ncheckpoint_dir = CHECKPOINTS_DIR\ncheckpoint_manager = tf.train.CheckpointManager(\n    checkpoint, \n    checkpoint_dir, \n    max_to_keep=2\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:32.120113Z","iopub.execute_input":"2025-03-18T03:21:32.120418Z","iopub.status.idle":"2025-03-18T03:21:32.134328Z","shell.execute_reply.started":"2025-03-18T03:21:32.120390Z","shell.execute_reply":"2025-03-18T03:21:32.133688Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def generate_images(model, test_input):\n    prediction = model(test_input)\n    \n    plt.figure(figsize=(12, 6))\n    \n    display_list = [test_input[0], prediction[0]]\n    title = ['Input Photo', 'Generated Monet-style Image']\n    \n    for i in range(2):\n        plt.subplot(1, 2, i+1)\n        plt.title(title[i])\n        plt.imshow(display_list[i] * 0.5 + 0.5)\n        plt.axis('off')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:32.134982Z","iopub.execute_input":"2025-03-18T03:21:32.135200Z","iopub.status.idle":"2025-03-18T03:21:32.147327Z","shell.execute_reply.started":"2025-03-18T03:21:32.135171Z","shell.execute_reply":"2025-03-18T03:21:32.146595Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train(monet_dataset, photo_dataset, epochs=10):\n    for epoch in range(epochs):\n        start = time.time()\n        \n        n = 0\n                \n        print(f\"Epoch {epoch + 1}/{epochs}\")\n        \n        monet_iter = iter(monet_dataset)\n        photo_iter = iter(photo_dataset)\n        \n        n_monet = counts.get('monet_jpg', 300)  \n        n_photo = counts.get('photo_jpg', 300)  \n        n_batches = min(n_monet, n_photo)\n        \n        for i in tqdm(range(n_batches)):\n            try:\n                monet_batch = next(monet_iter)\n                photo_batch = next(photo_iter)\n            except StopIteration:\n                monet_iter = iter(monet_dataset)\n                photo_iter = iter(photo_dataset)\n                monet_batch = next(monet_iter)\n                photo_batch = next(photo_iter)\n            \n            train_step(photo_batch, monet_batch)\n            \n            n += 1\n            \n            if i % 50 == 0:\n                print(f\"  Batch {i}/{n_batches}\")\n        \n        checkpoint_manager.save()\n        \n        print(f\"Time taken for epoch {epoch + 1}: {time.time() - start:.2f} sec\")\n        \n        for sample_photo in photo_dataset.take(1):\n            generate_images(generator_g, sample_photo)\n            break\n    \n    return","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:32.148050Z","iopub.execute_input":"2025-03-18T03:21:32.148311Z","iopub.status.idle":"2025-03-18T03:21:32.161817Z","shell.execute_reply.started":"2025-03-18T03:21:32.148292Z","shell.execute_reply":"2025-03-18T03:21:32.160987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train(monet_dataset, photo_dataset, epochs=50)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:21:32.162634Z","iopub.execute_input":"2025-03-18T03:21:32.162869Z","iopub.status.idle":"2025-03-18T03:31:56.455178Z","shell.execute_reply.started":"2025-03-18T03:21:32.162839Z","shell.execute_reply":"2025-03-18T03:31:56.454472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if photo_dataset is not None:\n    for sample_photo in photo_dataset.take(1):\n        generate_images(generator_g, sample_photo)\n        break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:31:56.456019Z","iopub.execute_input":"2025-03-18T03:31:56.456285Z","iopub.status.idle":"2025-03-18T03:32:00.774892Z","shell.execute_reply.started":"2025-03-18T03:31:56.456263Z","shell.execute_reply":"2025-03-18T03:32:00.774221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def preprocess_image(image_path):\n    img = tf.io.read_file(image_path)\n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.image.resize(img, [256, 256])\n    img = tf.cast(img, tf.float32)\n    img = (img / 127.5) - 1 \n    return img\n\ndef deprocess_image(image):\n    image = (image + 1) * 127.5 \n    image = tf.clip_by_value(image, 0, 255)\n    image = tf.cast(image, tf.uint8)\n\n    return image\n\ndef generate_and_save_images(model, input_image_path, output_image_path=None):\n    input_image = preprocess_image(input_image_path)\n    input_image = tf.expand_dims(input_image, 0)  \n\n    prediction = model(input_image, training=False) \n    prediction_image = deprocess_image(prediction[0])  \n\n    if output_image_path is None:\n        return prediction_image\n\n    encoded_image = tf.image.encode_jpeg(prediction_image)\n    tf.io.write_file(output_image_path, encoded_image)\n\n    return prediction_image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:32:00.775835Z","iopub.execute_input":"2025-03-18T03:32:00.776691Z","iopub.status.idle":"2025-03-18T03:32:00.782965Z","shell.execute_reply.started":"2025-03-18T03:32:00.776657Z","shell.execute_reply":"2025-03-18T03:32:00.781986Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if generator_g is not None and os.path.exists(PHOTO_JPG_DIR):\n    photo_files = [os.path.join(PHOTO_JPG_DIR, f) for f in os.listdir(PHOTO_JPG_DIR) if f.endswith('.jpg')]\n    print(f\"Generating Monet-style images for {len(photo_files)} photos...\")\n\n    submission_zip = os.path.join(OUTPUT_DIR, 'images.zip')\n\n    with zipfile.ZipFile(submission_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        for photo_path in tqdm(photo_files):\n            filename = os.path.basename(photo_path)\n\n            image_tensor = generate_and_save_images(generator_g, photo_path, None)\n\n            np_image = image_tensor.numpy()\n\n            _, encoded_image = cv2.imencode('.jpg', cv2.cvtColor(np_image, cv2.COLOR_RGB2BGR))\n\n            zipf.writestr(filename, encoded_image.tobytes())\n\n    print(f\"Submission zip file created: {submission_zip}\")\nelse:\n    print(\"Model not loaded or directory missing.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T03:32:00.783899Z","iopub.execute_input":"2025-03-18T03:32:00.784138Z","iopub.status.idle":"2025-03-18T03:35:48.802228Z","shell.execute_reply.started":"2025-03-18T03:32:00.784119Z","shell.execute_reply":"2025-03-18T03:35:48.801380Z"}},"outputs":[],"execution_count":null}]}