{"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":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30823,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array, array_to_img\nimport tensorflow as tf\nfrom PIL import Image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:28.09269Z","iopub.execute_input":"2025-01-17T06:20:28.092896Z","iopub.status.idle":"2025-01-17T06:20:35.75536Z","shell.execute_reply.started":"2025-01-17T06:20:28.092872Z","shell.execute_reply":"2025-01-17T06:20:35.754656Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load high-resolution images from CSV file, now includes folder path\ndef load_images_from_csv(csv_file, folder_path, image_size=(96, 96)):\n    data = pd.read_csv(csv_file)  # Assuming the CSV has a column 'image_name'\n    image_names = data['id_code'].tolist()  # Column containing image filenames\n    \n    images = []\n    for img_name in image_names:\n        img_path = os.path.join(folder_path, img_name + '.png')  # Add the folder path to image name\n        img = load_img(img_path, target_size=image_size)  # Load and resize\n        img_array = img_to_array(img) / 255.0  # Normalize\n        images.append(img_array)\n    \n    return np.array(images), image_names  # Return paths to map to filenames\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.756141Z","iopub.execute_input":"2025-01-17T06:20:35.756595Z","iopub.status.idle":"2025-01-17T06:20:35.761165Z","shell.execute_reply.started":"2025-01-17T06:20:35.756551Z","shell.execute_reply":"2025-01-17T06:20:35.760436Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Downscale the high-resolution images to low-resolution for training\ndef downscale_images(hr_images, scale_factor=4):\n    lr_images = []\n    for img in hr_images:\n        hr_size = img.shape[:2]\n        lr_size = (hr_size[1] // scale_factor, hr_size[0] // scale_factor)  # Width, Height\n        lr_img = tf.image.resize(img, size=lr_size, method='bicubic')\n        lr_images.append(lr_img.numpy())\n    return np.array(lr_images)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.762544Z","iopub.execute_input":"2025-01-17T06:20:35.762817Z","iopub.status.idle":"2025-01-17T06:20:35.773429Z","shell.execute_reply.started":"2025-01-17T06:20:35.762797Z","shell.execute_reply":"2025-01-17T06:20:35.772619Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Build Generator Model\ndef build_generator(input_shape=(24, 24, 3)):\n    input_lr = layers.Input(shape=input_shape)\n    \n    x = layers.Conv2D(64, (3, 3), padding='same', activation='relu')(input_lr)\n    \n    for _ in range(16):  # 16 residual blocks\n        residual = x\n        x = layers.Conv2D(64, (3, 3), padding='same', activation='relu')(x)\n        x = layers.Conv2D(64, (3, 3), padding='same')(x)\n        x = layers.Add()([x, residual])  # Skip connection\n    \n    x = layers.Conv2D(256, (3, 3), padding='same', activation='relu')(x)\n    x = layers.UpSampling2D(size=(2, 2))(x)  # Double the image size\n    \n    output_hr = layers.Conv2D(3, (3, 3), padding='same', activation='sigmoid')(x)\n    \n    generator = models.Model(inputs=input_lr, outputs=output_hr)\n    return generator","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.774622Z","iopub.execute_input":"2025-01-17T06:20:35.774852Z","iopub.status.idle":"2025-01-17T06:20:35.788233Z","shell.execute_reply.started":"2025-01-17T06:20:35.774832Z","shell.execute_reply":"2025-01-17T06:20:35.7875Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Build Discriminator Model\ndef build_discriminator(input_shape=(96, 96, 3)):\n    input_image = layers.Input(shape=input_shape)\n    \n    x = layers.Conv2D(64, (3, 3), strides=2, padding='same')(input_image)\n    x = layers.LeakyReLU(alpha=0.2)(x)\n    \n    x = layers.Conv2D(128, (3, 3), strides=2, padding='same')(x)\n    x = layers.LeakyReLU(alpha=0.2)(x)\n    \n    x = layers.Conv2D(256, (3, 3), strides=2, padding='same')(x)\n    x = layers.LeakyReLU(alpha=0.2)(x)\n    \n    x = layers.Conv2D(512, (3, 3), strides=2, padding='same')(x)\n    x = layers.LeakyReLU(alpha=0.2)(x)\n    \n    x = layers.Flatten()(x)\n    x = layers.Dense(1, activation='sigmoid')(x)\n    \n    discriminator = models.Model(inputs=input_image, outputs=x)\n    return discriminator","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.788974Z","iopub.execute_input":"2025-01-17T06:20:35.789242Z","iopub.status.idle":"2025-01-17T06:20:35.801764Z","shell.execute_reply.started":"2025-01-17T06:20:35.789214Z","shell.execute_reply":"2025-01-17T06:20:35.801033Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compile the Discriminator and Combined Model\ndef compile_models(generator, discriminator):\n    discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n    \n    # Make discriminator non-trainable during generator training\n    discriminator.trainable = False\n    \n    input_lr = layers.Input(shape=(24, 24, 3))\n    generated_hr = generator(input_lr)\n    validity = discriminator(generated_hr)\n    \n    combined = models.Model(inputs=input_lr, outputs=[generated_hr, validity])\n    combined.compile(optimizer='adam', loss=['mse', 'binary_crossentropy'], metrics=['accuracy'])\n    \n    return discriminator, combined","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.802399Z","iopub.execute_input":"2025-01-17T06:20:35.802638Z","iopub.status.idle":"2025-01-17T06:20:35.813551Z","shell.execute_reply.started":"2025-01-17T06:20:35.802611Z","shell.execute_reply":"2025-01-17T06:20:35.812862Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train SRGAN Model\ndef train_srgan(generator, discriminator, lr_images, hr_images, epochs=100, batch_size=16):\n    for epoch in range(epochs):\n        # Train discriminator\n        idx = np.random.randint(0, hr_images.shape[0], batch_size)\n        real_images = hr_images[idx]\n        fake_images = generator.predict(lr_images[idx])\n        \n        real_labels = np.ones((batch_size, 1))\n        fake_labels = np.zeros((batch_size, 1))\n        \n        d_loss_real = discriminator.train_on_batch(real_images, real_labels)\n        d_loss_fake = discriminator.train_on_batch(fake_images, fake_labels)\n        \n        d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)\n        \n        # Train generator\n        g_loss = combined.train_on_batch(lr_images[idx], [real_images, real_labels])\n        print(f\"{epoch} [D loss: {d_loss[0]}] [G loss: {g_loss[0]}]\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.814373Z","iopub.execute_input":"2025-01-17T06:20:35.814652Z","iopub.status.idle":"2025-01-17T06:20:35.827627Z","shell.execute_reply.started":"2025-01-17T06:20:35.814625Z","shell.execute_reply":"2025-01-17T06:20:35.826764Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Use Generator to Predict and Save Super-Resolution Images for Test Set\ndef generate_and_save_sr_images(generator, test_csv, output_folder, image_size=(96, 96), scale_factor=4):\n    test_images, test_image_paths = load_images_from_csv(test_csv, image_size)\n    lr_images = downscale_images(test_images, scale_factor)\n    \n    generated_images = []\n    for lr_img in lr_images:\n        lr_img = np.expand_dims(lr_img, axis=0)  # Add batch dimension\n        sr_img = generator.predict(lr_img)[0]  # Generate super-resolution image\n        sr_img = np.clip(sr_img * 255, 0, 255).astype(np.uint8)  # De-normalize and clip\n        generated_images.append(sr_img)\n    \n    # Save super-resolution images\n    os.makedirs(output_folder, exist_ok=True)\n    \n    for i, sr_img in enumerate(generated_images):\n        filename = os.path.basename(test_image_paths[i])  # Extract original filename\n        output_path = os.path.join(output_folder, f\"sr_{filename}\")\n        Image.fromarray(sr_img).save(output_path)\n    \n    print(\"Super-resolution images have been saved successfully!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.829602Z","iopub.execute_input":"2025-01-17T06:20:35.829816Z","iopub.status.idle":"2025-01-17T06:20:35.83893Z","shell.execute_reply.started":"2025-01-17T06:20:35.829797Z","shell.execute_reply":"2025-01-17T06:20:35.838243Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load training data from CSV\n# Load training data from CSV (Add folder path for train_images)\nhr_images, _ = load_images_from_csv('/kaggle/input/aptos2019-blindness-detection/train.csv', '/kaggle/input/aptos2019-blindness-detection/train_images')\n\n# Load testing data from CSV (Add folder path for test_images)\ntest_images, test_image_names = load_images_from_csv('/kaggle/input/aptos2019-blindness-detection/test.csv', '/kaggle/input/aptos2019-blindness-detection/test_images')\n\nlr_images = downscale_images(hr_images)\n\n# Build and compile the models\ngenerator = build_generator()\ndiscriminator = build_discriminator()\ndiscriminator, combined = compile_models(generator, discriminator)\n\n# Train the SRGAN model\ntrain_srgan(generator, discriminator, lr_images, hr_images)\n\n# After training, generate and save super-resolution images for the test set\ngenerate_and_save_sr_images(generator, '/kaggle/input/aptos2019-blindness-detection/test.csv', '/kaggle/working/sr-images-test/')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T06:20:35.839802Z","iopub.execute_input":"2025-01-17T06:20:35.839989Z"}},"outputs":[],"execution_count":null}]}