{"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"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-09T14:39:12.794339Z","iopub.execute_input":"2024-12-09T14:39:12.794717Z","iopub.status.idle":"2024-12-09T14:39:26.961959Z","shell.execute_reply.started":"2024-12-09T14:39:12.794683Z","shell.execute_reply":"2024-12-09T14:39:26.960689Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import Conv2D, Conv2DTranspose, BatchNormalization, LeakyReLU, ReLU, Input\nfrom tensorflow.keras.models import Model\nimport matplotlib.pyplot as plt\nimport os\nimport zipfile\nimport numpy as np\n\n# Constants\nIMG_HEIGHT, IMG_WIDTH, CHANNELS = 256, 256, 3  # Adjusted resolution to competition requirement\nBATCH_SIZE = 16  # Adjusted batch size for training\nBUFFER_SIZE = 1000  # Adjusted buffer size\nEPOCHS = 10  # Increased epochs for better results\n\n# Function to load and preprocess images\ndef load_image(file_path):\n    image = tf.io.read_file(file_path)\n    image = tf.image.decode_jpeg(image, channels=3)  # RGB\n    image = tf.image.resize(image, [IMG_HEIGHT, IMG_WIDTH])\n    image = (image - 127.5) / 127.5  # Normalize to [-1, 1]\n    return image\n\ndef load_dataset_from_kaggle(path):\n    dataset = tf.data.Dataset.list_files(path + \"/*.jpg\", shuffle=True)\n    dataset = dataset.map(load_image, num_parallel_calls=tf.data.AUTOTUNE)\n    dataset = dataset.cache()  # Cache for faster loading\n    dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)\n    return dataset\n\n# Generator Model\ndef build_generator():\n    inputs = Input(shape=[IMG_HEIGHT, IMG_WIDTH, CHANNELS])\n    x = inputs\n\n    # Downsampling\n    for filters in [64, 128, 256]:  # Increased filters for better quality\n        x = Conv2D(filters, kernel_size=4, strides=2, padding='same', use_bias=False)(x)\n        x = BatchNormalization()(x)\n        x = ReLU()(x)\n\n    # Upsampling\n    for filters in [128, 64]:  # Enhanced upsampling\n        x = Conv2DTranspose(filters, kernel_size=4, strides=2, padding='same', use_bias=False)(x)\n        x = BatchNormalization()(x)\n        x = ReLU()(x)\n\n    outputs = Conv2DTranspose(CHANNELS, kernel_size=4, strides=2, padding='same', activation='tanh')(x)\n    return Model(inputs, outputs, name='Generator')\n\n# Discriminator Model\ndef build_discriminator():\n    inputs = Input(shape=[IMG_HEIGHT, IMG_WIDTH, CHANNELS])\n    x = inputs\n\n    for filters in [64, 128, 256]:  # Enhanced discriminator layers\n        x = Conv2D(filters, kernel_size=4, strides=2, padding='same')(x)\n        x = LeakyReLU(0.2)(x)\n\n    outputs = Conv2D(1, kernel_size=4, strides=1, padding='same')(x)\n    return Model(inputs, outputs, name='Discriminator')\n\n# Loss Functions\ndef generator_loss_fn(fake_output):\n    return tf.keras.losses.BinaryCrossentropy(from_logits=True)(tf.ones_like(fake_output), fake_output)\n\ndef discriminator_loss_fn(real_output, fake_output):\n    real_loss = tf.keras.losses.BinaryCrossentropy(from_logits=True)(tf.ones_like(real_output), real_output)\n    fake_loss = tf.keras.losses.BinaryCrossentropy(from_logits=True)(tf.zeros_like(fake_output), fake_output)\n    return real_loss + fake_loss\n\n# Optimizers\ngenerator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\ndiscriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\n\n# Model Instances\ngenerator = build_generator()\ndiscriminator = build_discriminator()\n\n# Training Function\n@tf.function\ndef train_step(real_images):\n    noise = tf.random.normal([BATCH_SIZE, IMG_HEIGHT, IMG_WIDTH, CHANNELS])\n\n    with tf.GradientTape(persistent=True) as tape:\n        fake_images = generator(noise, training=True)\n        real_output = discriminator(real_images, training=True)\n        fake_output = discriminator(fake_images, training=True)\n\n        gen_loss = generator_loss_fn(fake_output)\n        disc_loss = discriminator_loss_fn(real_output, fake_output)\n\n    generator_gradients = tape.gradient(gen_loss, generator.trainable_variables)\n    discriminator_gradients = tape.gradient(disc_loss, discriminator.trainable_variables)\n\n    generator_optimizer.apply_gradients(zip(generator_gradients, generator.trainable_variables))\n    discriminator_optimizer.apply_gradients(zip(discriminator_gradients, discriminator.trainable_variables))\n\n    return gen_loss, disc_loss\n\ndef train(dataset, epochs):\n    for epoch in range(epochs):\n        print(f\"Epoch {epoch+1}/{epochs}\")\n        for real_images in dataset:\n            gen_loss, disc_loss = train_step(real_images)\n        print(f\"Generator Loss: {gen_loss}, Discriminator Loss: {disc_loss}\")\n\n        # Save example images\n        if (epoch + 1) % 5 == 0:\n            noise = tf.random.normal([1, IMG_HEIGHT, IMG_WIDTH, CHANNELS])\n            generated_image = generator(noise, training=False)\n            plt.imshow((generated_image[0].numpy() + 1) / 2)  # De-normalize\n            plt.axis('off')\n            plt.savefig(f\"generated_image_epoch_{epoch+1}.png\")\n\n# Save Images to Zip\ndef save_images_to_zip(generator, num_images=7000):  # Updated number of images\n    output_dir = '/kaggle/working/generated_images'\n    os.makedirs(output_dir, exist_ok=True)\n\n    with zipfile.ZipFile('/kaggle/working/images.zip', 'w') as z:\n        for i in range(num_images):\n            noise = tf.random.normal([1, IMG_HEIGHT, IMG_WIDTH, CHANNELS])\n            generated_image = generator(noise, training=False).numpy()[0]\n            generated_image = ((generated_image + 1) * 127.5).astype(np.uint8)  # De-normalize\n\n            file_path = os.path.join(output_dir, f'image_{i+1:05d}.jpg')\n            plt.imsave(file_path, generated_image)\n            z.write(file_path, arcname=f'image_{i+1:05d}.jpg')\n\n# Load Dataset\nmonet_dataset_path = '/kaggle/input/gan-getting-started/monet_jpg'\nmonet_dataset = load_dataset_from_kaggle(monet_dataset_path)\n\n# Train the Model\ntrain(monet_dataset, EPOCHS)\n\n# Generate and Save Images\nsave_images_to_zip(generator)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-14T04:13:43.474952Z","iopub.execute_input":"2024-12-14T04:13:43.475379Z","iopub.status.idle":"2024-12-14T04:43:53.282690Z","shell.execute_reply.started":"2024-12-14T04:13:43.475343Z","shell.execute_reply":"2024-12-14T04:43:53.280857Z"}},"outputs":[],"execution_count":null}]}