{"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":4104,"databundleVersionId":46661,"sourceType":"competition"},{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30840,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import EfficientNetB3\nfrom tensorflow.keras.applications.efficientnet import preprocess_input\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n\nprint(\"TensorFlow Version:\", tf.__version__)\nprint(\"Num GPUs Available: \", len(tf.config.list_physical_devices('GPU')))\n\n# --- 1. DATA LOADING ---\ntry:\n    train_df = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\n    img_dir = '../input/aptos2019-blindness-detection/train_images/'\nexcept:\n    print(\"❌ Error: Dataset path nahi mila!\")\n\n# Extensions & Type Conversion\ntrain_df['id_code'] = train_df['id_code'].apply(lambda x: x + \".png\")\ntrain_df['diagnosis'] = train_df['diagnosis'].astype(str)\n\n# Splitting\ntrain_set, val_set = train_test_split(train_df, test_size=0.2, random_state=42, stratify=train_df['diagnosis'])\n\n# --- 2. GENERATORS (FAST VERSION) ---\n# Hum EfficientNet ki built-in preprocessing use kar rahe hain jo GPU friendly hai\ntrain_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rotation_range=20,\n    zoom_range=0.2\n)\n\nval_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    dataframe=train_set,\n    directory=img_dir,\n    x_col=\"id_code\",\n    y_col=\"diagnosis\",\n    batch_size=32, # P100 ke liye optimized\n    class_mode=\"categorical\",\n    target_size=(255, 255)\n)\n\nval_generator = val_datagen.flow_from_dataframe(\n    dataframe=val_set,\n    directory=img_dir,\n    x_col=\"id_code\",\n    y_col=\"diagnosis\",\n    batch_size=32,\n    class_mode=\"categorical\",\n    target_size=(255, 255)\n)\n\n# --- 3. MODEL BUILDING ---\ndef create_model():\n    # Weights download honge, thoda time lag sakta hai\n    base_model = EfficientNetB3(weights='imagenet', include_top=False, input_shape=(255, 255, 3))\n    \n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Dropout(0.5)(x)\n    x = Dense(1024, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    outputs = Dense(5, activation='softmax')(x)\n    \n    model = Model(inputs=base_model.input, outputs=outputs)\n    model.compile(loss='categorical_crossentropy', optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), metrics=['accuracy'])\n    return model\n\nmodel = create_model()\n\n# --- 4. TRAINING ---\nprint(\"🚀 Training Starting... Please wait 1-2 mins for Epoch 1\")\n\nearly_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\nreduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-6)\n\nhistory = model.fit(\n    train_generator,\n    validation_data=val_generator,\n    epochs=15,\n    callbacks=[early_stop, reduce_lr]\n)\n\n# --- 5. SAVE ---\nmodel.save('final_model.h5')\nprint(\"✅ Done!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-19T10:39:42.324380Z","iopub.execute_input":"2025-11-19T10:39:42.324631Z","iopub.status.idle":"2025-11-19T11:48:32.864186Z","shell.execute_reply.started":"2025-11-19T10:39:42.324609Z","shell.execute_reply":"2025-11-19T11:48:32.863147Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# === FIXING THE EVALUATION (Shuffle Error) ===\n\n# 1. Validation Generator ko dubara banayein (Shuffle=False ke sath)\n# Yeh bohot zaroori hai taake predictions aur labels match karein\ntest_generator = val_datagen.flow_from_dataframe(\n    dataframe=val_set,\n    directory='../input/aptos2019-blindness-detection/train_images/',\n    x_col=\"id_code\",\n    y_col=\"diagnosis\",\n    batch_size=32,\n    class_mode=\"categorical\",\n    target_size=(255, 255),\n    shuffle=False  # <--- YEH HAI MAGIC FIX\n)\n\n# 2. Ab Predict karein\nprint(\"Sahi tareeqay se Testing shuru... (Wait karein)\")\ntest_generator.reset()\npreds = model.predict(test_generator, verbose=1)\n\n# 3. Report Generate karein\ny_pred = np.argmax(preds, axis=1)\ny_true = test_generator.classes  # Ab ye order match karega\n\n# 4. Print Report\nprint(\"\\n--- REAL REPORT ---\")\nprint(classification_report(y_true, y_pred, target_names=['No DR', 'Mild', 'Moderate', 'Severe', 'Proliferative']))\n\n# 5. Confusion Matrix\ncm = confusion_matrix(y_true, y_pred)\nplt.figure(figsize=(8, 6))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues')\nplt.xlabel('Predicted')\nplt.ylabel('Actual')\nplt.title('Corrected Confusion Matrix')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-19T12:02:49.507779Z","iopub.execute_input":"2025-11-19T12:02:49.508510Z","iopub.status.idle":"2025-11-19T12:04:05.102462Z","shell.execute_reply.started":"2025-11-19T12:02:49.508477Z","shell.execute_reply":"2025-11-19T12:04:05.101765Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# === GRAD-CAM VISUALIZATION ===\nimport matplotlib.cm as cm\n\ndef make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):\n    grad_model = tf.keras.models.Model(\n        inputs=[model.inputs],\n        outputs=[model.get_layer(last_conv_layer_name).output, model.output]\n    )\n\n    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\n        if pred_index is None:\n            pred_index = tf.argmax(preds[0])\n        class_channel = preds[:, pred_index]\n\n    grads = tape.gradient(class_channel, last_conv_layer_output)\n    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))\n    last_conv_layer_output = last_conv_layer_output[0]\n    heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]\n    heatmap = tf.squeeze(heatmap)\n    heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)\n    return heatmap.numpy()\n\ndef display_gradcam(img_path, heatmap, alpha=0.4):\n    # Image load & Resize\n    img = cv2.imread(img_path)\n    img = cv2.resize(img, (255, 255)) # Humara target size\n    \n    # Heatmap ko color mein badalna\n    heatmap = np.uint8(255 * heatmap)\n    jet = cm.get_cmap(\"jet\")\n    jet_colors = jet(np.arange(256))[:, :3]\n    jet_heatmap = jet_colors[heatmap]\n    \n    jet_heatmap = cv2.resize(jet_heatmap, (img.shape[1], img.shape[0]))\n    jet_heatmap = np.uint8(jet_heatmap * 255)\n\n    # Overlay\n    superimposed_img = jet_heatmap * alpha + img\n    superimposed_img = np.uint8(superimposed_img)\n\n    # Plotting\n    plt.figure(figsize=(4, 4))\n    plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB))\n    plt.axis('off')\n    plt.title(\"Model Focus (Red Area)\")\n    plt.show()\n\n# --- RUNNING ON 3 SAMPLE IMAGES ---\n# EfficientNetB3 ki last layer ka naam usually 'top_activation' hota hai\nlast_conv_layer_name = \"top_activation\"\n\n# Hum Validation set se 3 random images uthayenge\nimport random\nrandom_indices = random.sample(range(len(test_generator.filenames)), 3)\n\nprint(\"Generating Heatmaps... (Red area = Disease Location)\")\n\nfor i in random_indices:\n    img_path = \"../input/aptos2019-blindness-detection/train_images/\" + test_generator.filenames[i]\n    \n    # Image Preprocess\n    original = cv2.imread(img_path)\n    original = cv2.resize(original, (255, 255))\n    img_array = preprocess_input(original)\n    img_array = np.expand_dims(img_array, axis=0)\n    \n    # Generate Heatmap\n    try:\n        heatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name)\n        display_gradcam(img_path, heatmap)\n        \n        # Asal bimari bhi print karte hain\n        print(f\"Actual Class: {test_generator.classes[i]}\")\n    except Exception as e:\n        print(f\"Error: {e}. Shayad layer ka naam ghalat hai.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-19T12:06:53.640494Z","iopub.execute_input":"2025-11-19T12:06:53.640918Z","iopub.status.idle":"2025-11-19T12:06:58.171486Z","shell.execute_reply.started":"2025-11-19T12:06:53.640889Z","shell.execute_reply":"2025-11-19T12:06:58.170612Z"}},"outputs":[],"execution_count":null}]}