{"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":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30887,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport os\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import InceptionResNetV2\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-15T00:37:32.194639Z","iopub.execute_input":"2025-02-15T00:37:32.194917Z","iopub.status.idle":"2025-02-15T00:37:44.107725Z","shell.execute_reply.started":"2025-02-15T00:37:32.194895Z","shell.execute_reply":"2025-02-15T00:37:44.107075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Enable GPU memory growth (Prevents TensorFlow from consuming all GPU memory)\ngpus = tf.config.list_physical_devices('GPU')\nif gpus:\n    try:\n        for gpu in gpus:\n            tf.config.experimental.set_memory_growth(gpu, True)\n        print(\"✅ GPU is available and memory growth is enabled.\")\n    except RuntimeError as e:\n        print(e)  # Catch runtime errors if devices are already initialized\nelse:\n    print(\"❌ No GPU detected. Using CPU instead.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-15T00:38:16.793321Z","iopub.execute_input":"2025-02-15T00:38:16.793922Z","iopub.status.idle":"2025-02-15T00:38:17.44657Z","shell.execute_reply.started":"2025-02-15T00:38:16.793894Z","shell.execute_reply":"2025-02-15T00:38:17.445563Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DATA_DIR = \"../input/aptos2019-blindness-detection/train_images\"\nLABELS_FILE = \"../input/aptos2019-blindness-detection/train.csv\"\nIMG_SIZE = (299, 299)  # Required input size for InceptionResNetV2\nBATCH_SIZE = 32\nEPOCHS = 10\n\n# Read CSV file\ndf = pd.read_csv(LABELS_FILE)\ndf[\"id_code\"] = df[\"id_code\"].astype(str) + \".png\"  # Ensure filenames match\n\n# Split into train and validation\ntrain_df, val_df = train_test_split(df, test_size=0.2, stratify=df[\"diagnosis\"], random_state=42)\n\ntrain_df = train_df.reset_index(drop=True)\nval_df = val_df.reset_index(drop=True)\n\ntrain_df[\"filepath\"] = train_df[\"id_code\"].apply(lambda x: os.path.join(DATA_DIR, x))\nval_df[\"filepath\"] = val_df[\"id_code\"].apply(lambda x: os.path.join(DATA_DIR, x))\n\n\nprint(\"Train DF Columns:\", train_df.columns)\nprint(\"Validation DF Columns:\", val_df.columns)\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-15T00:38:25.530449Z","iopub.execute_input":"2025-02-15T00:38:25.53075Z","iopub.status.idle":"2025-02-15T00:38:25.568479Z","shell.execute_reply.started":"2025-02-15T00:38:25.530727Z","shell.execute_reply":"2025-02-15T00:38:25.567794Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Custom Data Generator\nclass DataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, df, batch_size=32, is_train=True, num_classes=5, shuffle=True, **kwargs):\n        super().__init__(**kwargs)\n        \n        self.df = df.copy().reset_index(drop=True)\n        self.batch_size = batch_size\n        self.is_train = is_train\n        self.num_classes = num_classes\n        self.shuffle = shuffle\n        self.indexes = np.arange(len(self.df))\n        self.on_epoch_end()\n        \n    def __len__(self):\n        return int(np.ceil(len(self.df) / self.batch_size))\n    \n    def on_epoch_end(self):\n        if self.shuffle:\n            np.random.shuffle(self.indexes)\n    \n    def __getitem__(self, index):\n        batch_indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]\n        batch_df = self.df.iloc[batch_indexes]\n        \n        images = []\n        labels = []\n        for _, row in batch_df.iterrows():\n            image = self.load_and_preprocess_image(row[\"filepath\"])\n            images.append(image)\n            if self.is_train:\n                label = tf.keras.utils.to_categorical(row[\"diagnosis\"] - 1, num_classes=self.num_classes)\n                labels.append(label)\n        \n        images = np.stack(images, axis=0)\n        if self.is_train:\n            labels = np.stack(labels, axis=0)\n            return images, labels\n        else:\n            return images\n\n    @staticmethod\n    def load_and_preprocess_image(filepath):\n        image = load_img(filepath, target_size=IMG_SIZE)\n        image = img_to_array(image) / 255.0  # Normalize\n        return image\n\n# Create data generators\ntrain_generator = DataGenerator(train_df, batch_size=BATCH_SIZE, is_train=True)\nval_generator = DataGenerator(val_df, batch_size=BATCH_SIZE, is_train=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-15T00:38:30.333834Z","iopub.execute_input":"2025-02-15T00:38:30.334159Z","iopub.status.idle":"2025-02-15T00:38:30.344575Z","shell.execute_reply.started":"2025-02-15T00:38:30.334129Z","shell.execute_reply":"2025-02-15T00:38:30.343775Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model = InceptionResNetV2(weights='imagenet', include_top=False, input_shape=(299, 299, 3))\nx = GlobalAveragePooling2D()(base_model.output)\nx = Dense(512, activation='relu')(x)\nx = Dense(256, activation='relu')(x)\nout = Dense(len(df[\"diagnosis\"].unique()), activation='softmax')(x)\nmodel = Model(inputs=base_model.input, outputs=out)\n\n# Freeze base model layers\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# Compile Model\nmodel.compile(optimizer=Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-15T00:38:38.742985Z","iopub.execute_input":"2025-02-15T00:38:38.743297Z","iopub.status.idle":"2025-02-15T00:38:45.635966Z","shell.execute_reply.started":"2025-02-15T00:38:38.743273Z","shell.execute_reply":"2025-02-15T00:38:45.635311Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    train_generator,\n    validation_data=val_generator,\n    epochs=EPOCHS,\n    steps_per_epoch=max(1, len(train_df) // BATCH_SIZE),  \n    validation_steps=max(1, len(val_df) // BATCH_SIZE)\n)\n\n# Evaluate Model on Validation Data\neval_results = model.evaluate(val_generator)\nprint(f\"Validation Loss: {eval_results[0]:.4f}\")\nprint(f\"Validation Accuracy: {eval_results[1]:.4f}\")\n\n# Plot Accuracy & Loss\nplt.figure(figsize=(12, 5))\nplt.subplot(1, 2, 1)\nplt.plot(history.history['accuracy'], label='Train Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.legend()\nplt.title('Accuracy')\n\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Train Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.legend()\nplt.title('Loss')\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-15T01:15:56.369365Z","iopub.execute_input":"2025-02-15T01:15:56.369676Z","iopub.status.idle":"2025-02-15T01:46:00.090735Z","shell.execute_reply.started":"2025-02-15T01:15:56.369653Z","shell.execute_reply":"2025-02-15T01:46:00.089883Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport numpy as np\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Load the trained model\nmodel = tf.keras.models.load_model('history')\n\n# Define test data directory\ntest_dir = 'path_to_test_data/'\nimg_size = (299, 299)  # InceptionResNetV2 input size\nbatch_size = 32\n\n# Create test data generator\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,\n    target_size=img_size,\n    batch_size=batch_size,\n    class_mode='categorical',  # Change as per your classification type\n    shuffle=False  # Keep False to maintain label order\n)\n\n# Evaluate the model on test data\nevaluation = model.evaluate(test_generator)\nprint(f\"Test Loss: {evaluation[0]:.4f}\")\nprint(f\"Test Accuracy: {evaluation[1]:.4f}\")\n\n# Predict on test data\ny_pred = model.predict(test_generator)\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# Get true labels\ny_true = test_generator.classes\n\n# Display classification report and confusion matrix\nfrom sklearn.metrics import classification_report, confusion_matrix\nprint(\"Classification Report:\")\nprint(classification_report(y_true, y_pred_classes))\nprint(\"Confusion Matrix:\")\nprint(confusion_matrix(y_true, y_pred_classes))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T06:21:25.090532Z","iopub.execute_input":"2025-02-16T06:21:25.090824Z","iopub.status.idle":"2025-02-16T06:21:25.109305Z","shell.execute_reply.started":"2025-02-16T06:21:25.090804Z","shell.execute_reply":"2025-02-16T06:21:25.108172Z"}},"outputs":[],"execution_count":null}]}