{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":14774,"databundleVersionId":875431}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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":"2026-05-20T17:59:36.091363Z","iopub.execute_input":"2026-05-20T17:59:36.091632Z","iopub.status.idle":"2026-05-20T17:59:44.634072Z","shell.execute_reply.started":"2026-05-20T17:59:36.091611Z","shell.execute_reply":"2026-05-20T17:59:44.633325Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 1. DOWNLOAD DATASET\n# ============================================\n\nimport kagglehub\n\n# Download dataset\npath = kagglehub.competition_download(\n    'aptos2019-blindness-detection'\n)\n\nprint(\"Dataset Path:\", path)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:44.635431Z","iopub.execute_input":"2026-05-20T17:59:44.635773Z","iopub.status.idle":"2026-05-20T17:59:45.777274Z","shell.execute_reply.started":"2026-05-20T17:59:44.635735Z","shell.execute_reply":"2026-05-20T17:59:45.776493Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 2. IMPORT LIBRARIES\n# ============================================\n\nimport os\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report\nfrom sklearn.metrics import confusion_matrix\n\nimport tensorflow as tf\n\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.layers import GlobalAveragePooling2D\nfrom tensorflow.keras.layers import Dropout\nfrom tensorflow.keras.optimizers import Adam\n\nprint(\"TensorFlow Version:\", tf.__version__)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:45.778282Z","iopub.execute_input":"2026-05-20T17:59:45.778583Z","iopub.status.idle":"2026-05-20T17:59:46.514636Z","shell.execute_reply.started":"2026-05-20T17:59:45.778559Z","shell.execute_reply":"2026-05-20T17:59:46.513971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 3. CHECK DATASET FILES\n# ============================================\n\nprint(os.listdir(path))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:46.516293Z","iopub.execute_input":"2026-05-20T17:59:46.516802Z","iopub.status.idle":"2026-05-20T17:59:46.521072Z","shell.execute_reply.started":"2026-05-20T17:59:46.516776Z","shell.execute_reply":"2026-05-20T17:59:46.520490Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 4. DEFINE PATHS\n# ============================================\n\ncsv_path = os.path.join(path, \"train.csv\")\n\nimage_folder = os.path.join(path, \"train_images\")\n\nprint(\"CSV Path:\", csv_path)\nprint(\"Image Folder:\", image_folder)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:46.522076Z","iopub.execute_input":"2026-05-20T17:59:46.522615Z","iopub.status.idle":"2026-05-20T17:59:46.539810Z","shell.execute_reply.started":"2026-05-20T17:59:46.522590Z","shell.execute_reply":"2026-05-20T17:59:46.538917Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 5. LOAD CSV FILE\n# ============================================\n\ndf = pd.read_csv(csv_path)\n\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:46.540706Z","iopub.execute_input":"2026-05-20T17:59:46.541053Z","iopub.status.idle":"2026-05-20T17:59:46.595954Z","shell.execute_reply.started":"2026-05-20T17:59:46.541004Z","shell.execute_reply":"2026-05-20T17:59:46.595228Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 6. CONVERT LABELS\n# ============================================\n\n# 0 -> Healthy\n# 1,2,3,4 -> Diseased\n\ndf['binary_label'] = df['diagnosis'].apply(\n    lambda x: 0 if x == 0 else 1\n)\n\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:46.596783Z","iopub.execute_input":"2026-05-20T17:59:46.597087Z","iopub.status.idle":"2026-05-20T17:59:46.607046Z","shell.execute_reply.started":"2026-05-20T17:59:46.597050Z","shell.execute_reply":"2026-05-20T17:59:46.605998Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 7. TAKE SMALL SUBSET\n# ============================================\n\nhealthy_df = df[df['binary_label'] == 0].sample(\n    150,\n    random_state=42\n)\n\ndiseased_df = df[df['binary_label'] == 1].sample(\n    150,\n    random_state=42\n)\n\ndf = pd.concat([healthy_df, diseased_df])\n\ndf = df.sample(frac=1).reset_index(drop=True)\n\nprint(\"Total Images:\", len(df))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:46.608237Z","iopub.execute_input":"2026-05-20T17:59:46.608605Z","iopub.status.idle":"2026-05-20T17:59:46.654851Z","shell.execute_reply.started":"2026-05-20T17:59:46.608568Z","shell.execute_reply":"2026-05-20T17:59:46.654207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 8. LOAD AND PREPROCESS IMAGES\n# ============================================\n\nIMG_SIZE = 224\n\nimages = []\nlabels = []\n\nfor index, row in df.iterrows():\n\n    image_id = row['id_code']\n\n    label = row['binary_label']\n\n    image_path = os.path.join(\n        image_folder,\n        image_id + \".png\"\n    )\n\n    try:\n\n        img = cv2.imread(image_path)\n\n        img = cv2.cvtColor(\n            img,\n            cv2.COLOR_BGR2RGB\n        )\n\n        img = cv2.resize(\n            img,\n            (IMG_SIZE, IMG_SIZE)\n        )\n\n        # Optional enhancement\n        img = cv2.GaussianBlur(img, (5,5), 0)\n\n        # Normalize\n        img = img / 255.0\n\n        images.append(img)\n\n        labels.append(label)\n\n    except:\n        pass\n\nimages = np.array(images)\n\nlabels = np.array(labels)\n\nprint(\"Images Shape:\", images.shape)\n\nprint(\"Labels Shape:\", labels.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T17:59:46.655771Z","iopub.execute_input":"2026-05-20T17:59:46.656334Z","iopub.status.idle":"2026-05-20T18:00:18.339588Z","shell.execute_reply.started":"2026-05-20T17:59:46.656286Z","shell.execute_reply":"2026-05-20T18:00:18.338747Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 9. VISUALIZE SAMPLE IMAGES (Dengeli Gosterim)\n# ============================================\n\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Veri setinden saglikli (0) ve hasta (1) olanlarin indekslerini buluyoruz\nhealthy_indices = np.where(labels == 0)[0]\ndiseased_indices = np.where(labels == 1)[0]\n\n# Her iki siniftan da rastgele 3'er tane ornek seciyoruz\nnp.random.seed(42)  # Her calistiginda ayni guzel resimler gelsin diye sabitledik\nselected_healthy = np.random.choice(healthy_indices, 3, replace=False)\nselected_diseased = np.random.choice(diseased_indices, 3, replace=False)\n\n# Secilen 6 indeksi tek bir listede birlestiriyoruz (Ilk 3 saglikli, son 3 hasta)\ndisplay_indices = np.concatenate([selected_healthy, selected_diseased])\n\nplt.figure(figsize=(12, 7))\n\nfor i, idx in enumerate(display_indices):\n    plt.subplot(2, 3, i + 1)\n    plt.imshow(images[idx])\n    \n    # Ilk 3 resim saglikli (satir 1), son 3 resim hasta (satir 2) olacak sekilde basliklandirma\n  # Başlıkları tamamen temiz İngilizceye çeviriyoruz ki karakter hatası kalmasın:\n    if i < 3:\n        plt.title(\"Early Stage / Healthy (Stage 0-1)\", fontsize=11, color='green', fontweight='bold')\n    else:\n        plt.title(\"Advanced Stage / Diseased (Stage 2-4)\", fontsize=11, color='red', fontweight='bold')\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:00:18.342051Z","iopub.execute_input":"2026-05-20T18:00:18.342348Z","iopub.status.idle":"2026-05-20T18:00:19.019260Z","shell.execute_reply.started":"2026-05-20T18:00:18.342324Z","shell.execute_reply":"2026-05-20T18:00:19.018304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 10. TRAIN TEST SPLIT\n# ============================================\n\nX_train, X_test, y_train, y_test = train_test_split(\n    images,\n    labels,\n    test_size=0.2,\n    random_state=42,\n    stratify=labels\n)\n\nprint(\"Training Images:\", X_train.shape)\n\nprint(\"Testing Images:\", X_test.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:00:19.020272Z","iopub.execute_input":"2026-05-20T18:00:19.020700Z","iopub.status.idle":"2026-05-20T18:00:19.112078Z","shell.execute_reply.started":"2026-05-20T18:00:19.020673Z","shell.execute_reply":"2026-05-20T18:00:19.111160Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 11. BUILD TRANSFER LEARNING MODEL\n# ============================================\n\nbase_model = MobileNetV2(\n    weights='imagenet',\n    include_top=False,\n    input_shape=(224,224,3)\n)\n\nbase_model.trainable = False\n\nx = base_model.output\n\nx = GlobalAveragePooling2D()(x)\n\nx = Dense(128, activation='relu')(x)\n\nx = Dropout(0.3)(x)\n\noutput = Dense(1, activation='sigmoid')(x)\n\nmodel = Model(\n    inputs=base_model.input,\n    outputs=output\n)\n\nmodel.compile(\n    optimizer=Adam(learning_rate=0.0001),\n    loss='binary_crossentropy',\n    metrics=['accuracy']\n)\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:00:19.113192Z","iopub.execute_input":"2026-05-20T18:00:19.113533Z","iopub.status.idle":"2026-05-20T18:00:20.269390Z","shell.execute_reply.started":"2026-05-20T18:00:19.113496Z","shell.execute_reply":"2026-05-20T18:00:20.268601Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 12. TRAIN MODEL\n# ============================================\n\nhistory = model.fit(\n    X_train,\n    y_train,\n    validation_data=(X_test, y_test),\n    epochs=3,\n    batch_size=16\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:00:20.270417Z","iopub.execute_input":"2026-05-20T18:00:20.270774Z","iopub.status.idle":"2026-05-20T18:00:55.298994Z","shell.execute_reply.started":"2026-05-20T18:00:20.270749Z","shell.execute_reply":"2026-05-20T18:00:55.298343Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 13. PLOT ACCURACY AND LOSS\n# ============================================\n\nplt.figure(figsize=(12,5))\n\n# Accuracy Plot\nplt.subplot(1,2,1)\n\nplt.plot(\n    history.history['accuracy'],\n    label='Train Accuracy'\n)\n\nplt.plot(\n    history.history['val_accuracy'],\n    label='Validation Accuracy'\n)\n\nplt.title(\"Accuracy\")\n\nplt.xlabel(\"Epoch\")\n\nplt.ylabel(\"Accuracy\")\n\nplt.legend()\n\n# Loss Plot\nplt.subplot(1,2,2)\n\nplt.plot(\n    history.history['loss'],\n    label='Train Loss'\n)\n\nplt.plot(\n    history.history['val_loss'],\n    label='Validation Loss'\n)\n\nplt.title(\"Loss\")\n\nplt.xlabel(\"Epoch\")\n\nplt.ylabel(\"Loss\")\n\nplt.legend()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:00:55.299838Z","iopub.execute_input":"2026-05-20T18:00:55.300172Z","iopub.status.idle":"2026-05-20T18:00:55.560158Z","shell.execute_reply.started":"2026-05-20T18:00:55.300148Z","shell.execute_reply":"2026-05-20T18:00:55.559238Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 14. MODEL EVALUATION\n# ============================================\n\npredictions = model.predict(X_test)\n\npredictions = (predictions > 0.5).astype(int)\n\nprint(\n    classification_report(\n        y_test,\n        predictions\n    )\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:00:55.561257Z","iopub.execute_input":"2026-05-20T18:00:55.561595Z","iopub.status.idle":"2026-05-20T18:01:18.815510Z","shell.execute_reply.started":"2026-05-20T18:00:55.561559Z","shell.execute_reply":"2026-05-20T18:01:18.814344Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 15. CONFUSION MATRIX\n# ============================================\n\ncm = confusion_matrix(\n    y_test,\n    predictions\n)\n\nplt.figure(figsize=(6,5))\n\nsns.heatmap(\n    cm,\n    annot=True,\n    fmt='d',\n    cmap='Blues',\n    xticklabels=['Healthy', 'Diseased'],\n    yticklabels=['Healthy', 'Diseased']\n)\n\nplt.xlabel(\"Predicted\")\n\nplt.ylabel(\"Actual\")\n\nplt.title(\"MobileNetV2 Confusion Matrix\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:15:08.775738Z","iopub.execute_input":"2026-05-20T18:15:08.776251Z","iopub.status.idle":"2026-05-20T18:15:08.913180Z","shell.execute_reply.started":"2026-05-20T18:15:08.776218Z","shell.execute_reply":"2026-05-20T18:15:08.912491Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 16. SAVE MODEL\n# ============================================\n\nmodel.save(\"retina_model.keras\")\n\nprint(\"Model Saved Successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:01:18.947517Z","iopub.execute_input":"2026-05-20T18:01:18.947810Z","iopub.status.idle":"2026-05-20T18:01:19.396307Z","shell.execute_reply.started":"2026-05-20T18:01:18.947778Z","shell.execute_reply":"2026-05-20T18:01:19.395615Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 17. GRAD-CAM SETUP\n# ============================================\n\nlast_conv_layer_name = \"Conv1\"\n\ngrad_model = tf.keras.models.Model(\n    inputs=model.inputs,\n    outputs=[\n        model.get_layer(last_conv_layer_name).output,\n        model.output\n    ]\n)\n\ndef make_gradcam_heatmap(img_array):\n\n    img_array = tf.convert_to_tensor(\n        img_array,\n        dtype=tf.float32\n    )\n\n    with tf.GradientTape() as tape:\n\n        conv_outputs, predictions = grad_model(\n            img_array\n        )\n\n        loss = predictions[:, 0]\n\n    grads = tape.gradient(\n        loss,\n        conv_outputs\n    )\n\n    pooled_grads = tf.reduce_mean(\n        grads,\n        axis=(0,1,2)\n    )\n\n    conv_outputs = conv_outputs[0]\n\n    heatmap = tf.reduce_sum(\n        tf.multiply(\n            pooled_grads,\n            conv_outputs\n        ),\n        axis=-1\n    )\n\n    heatmap = tf.maximum(\n        heatmap,\n        0\n    )\n\n    heatmap = heatmap / (\n        tf.reduce_max(heatmap) + 1e-8\n    )\n\n    return heatmap.numpy()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:01:19.397260Z","iopub.execute_input":"2026-05-20T18:01:19.397552Z","iopub.status.idle":"2026-05-20T18:01:19.411437Z","shell.execute_reply.started":"2026-05-20T18:01:19.397520Z","shell.execute_reply":"2026-05-20T18:01:19.410743Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================\n# 18. GENERATE HEALTHY + DISEASED GRAD-CAM\n# ============================================\n\nplt.figure(figsize=(15,18))\n\ncount = 0\n\nhealthy_found = 0\ndiseased_found = 0\n\nfor i in range(len(X_test)):\n\n    sample_image = X_test[i]\n\n    img_array = np.expand_dims(\n        sample_image,\n        axis=0\n    )\n\n    # Prediction\n    prediction = model.predict(\n        img_array,\n        verbose=0\n    )[0][0]\n\n    # 1. Adım: Yeni klinik etiketlerimizi rapordaki gibi tanımlıyoruz\n    if prediction > 0.5:\n        predicted_label = \"Advanced Stage (Evre 2-4)\"  # İleri evre\n    else:\n        predicted_label = \"Early Stage / Healthy (Evre 0-1)\"  # Erken evre veya sağlıklı\n\n    # 2. Adım: Döngünün takıldığı filtre kısmını yeni etiket isimleriyle güncelliyoruz!\n    # 2 adet Erken Evre/Sağlıklı örnek seç\n    if predicted_label == \"Early Stage / Healthy (Evre 0-1)\" and healthy_found < 2:\n        healthy_found += 1\n\n    # 1 adet İleri Evre örnek seç\n    elif predicted_label == \"Advanced Stage (Evre 2-4)\" and diseased_found < 1:\n        diseased_found += 1\n\n    else:\n        continue\n\n    # Generate heatmap\n    heatmap = make_gradcam_heatmap(\n        img_array\n    )\n\n    # Resize heatmap\n    heatmap = cv2.resize(\n        heatmap,\n        (224,224)\n    )\n\n    # Convert heatmap\n    heatmap = np.uint8(\n        255 * heatmap\n    )\n\n    heatmap = cv2.applyColorMap(\n        heatmap,\n        cv2.COLORMAP_JET\n    )\n\n    # Overlay heatmap\n    superimposed_img = (\n        heatmap * 0.7 +\n        (sample_image * 255)\n    )\n\n    superimposed_img = np.clip(\n        superimposed_img,\n        0,\n        255\n    ).astype(\"uint8\")\n\n    # ORIGINAL IMAGE\n    plt.subplot(\n        3,\n        2,\n        count*2 + 1\n    )\n\n    plt.imshow(sample_image)\n\n    plt.title(\n        f\"Original Retina\\nPrediction: {predicted_label}\"\n    )\n\n    plt.axis(\"off\")\n\n    # GRAD-CAM IMAGE\n    plt.subplot(\n        3,\n        2,\n        count*2 + 2\n    )\n\n    plt.imshow(superimposed_img)\n\n    plt.title(\"Grad-CAM Heatmap\")\n\n    plt.axis(\"off\")\n\n    count += 1\n\n    # Stop after 3 samples\n    if count == 3:\n        break\n\nplt.tight_layout()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:01:19.412441Z","iopub.execute_input":"2026-05-20T18:01:19.412711Z","iopub.status.idle":"2026-05-20T18:01:32.977252Z","shell.execute_reply.started":"2026-05-20T18:01:19.412688Z","shell.execute_reply":"2026-05-20T18:01:32.976315Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\n\n# ===================================================\n# # 11. BUILD RESNET50 TRANSFER LEARNING MODEL\n# ===================================================\n\n# Önceden eğitilmiş ResNet50 modelini yükleme (Üst katmanlar hariç)\nresnet_base_model = ResNet50(\n    weights='imagenet',\n    include_top=False,\n    input_shape=(224, 224, 3)\n)\n\n# ResNet50 ağırlıklarını donduruyoruz (Eğitilmeyecek)\nresnet_base_model.trainable = False\n\n# Yeni sınıflandırma başlığını ekleme (MobileNetV2 ile birebir aynı yapı)\nx = resnet_base_model.output\nx = GlobalAveragePooling2D()(x)\nx = Dense(128, activation='relu')(x)\nx = Dropout(0.3)(x)\nresnet_output = Dense(1, activation='sigmoid')(x)\n\n# Nihai modeli oluşturma\nresnet_model = Model(inputs=resnet_base_model.input, outputs=resnet_output)\n\n# Modeli derleme (Aynı optimizer, loss ve learning rate)\nresnet_model.compile(\n    optimizer=Adam(learning_rate=0.0001),\n    loss='binary_crossentropy',\n    metrics=['accuracy']\n)\n\n# Model özetini yazdırma (Buradan parametre sayılarını rapora alabilirsin)\nresnet_model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:01:33.151259Z","iopub.execute_input":"2026-05-20T18:01:33.151575Z","iopub.status.idle":"2026-05-20T18:01:34.385505Z","shell.execute_reply.started":"2026-05-20T18:01:33.151542Z","shell.execute_reply":"2026-05-20T18:01:34.384725Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history_resnet = resnet_model.fit(\n    X_train, y_train,\n    validation_data=(X_test, y_test), # X_val yerine test setini verdik\n    epochs=3,\n    batch_size=16\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:03:05.390731Z","iopub.execute_input":"2026-05-20T18:03:05.391686Z","iopub.status.idle":"2026-05-20T18:03:26.181107Z","shell.execute_reply.started":"2026-05-20T18:03:05.391655Z","shell.execute_reply":"2026-05-20T18:03:26.180156Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import classification_report, confusion_matrix\n\n# ===================================================\n# # 14. RESNET50 MODEL EVALUATION\n# ===================================================\n\n# Test seti üzerinden tahminlerin alınması\nresnet_predictions = resnet_model.predict(X_test)\n\n# Olasılık değerlerini (0.5 eşiğine göre) 0 veya 1'e dönüştürme\nresnet_predictions = (resnet_predictions > 0.5).astype(int)\n\n# Sınıflandırma raporunu ekrana yazdırma\nprint(\"--- RESNET50 SINIFLANDIRMA RAPORU ---\")\nprint(\n    classification_report(\n        y_test,\n        resnet_predictions\n    )\n)\n\n# Karışıklık matrisini yazdırma\nprint(\"--- RESNET50 KARIŞIKLIK MATRİSİ ---\")\nprint(confusion_matrix(y_test, resnet_predictions))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:03:34.739755Z","iopub.execute_input":"2026-05-20T18:03:34.740364Z","iopub.status.idle":"2026-05-20T18:03:46.667170Z","shell.execute_reply.started":"2026-05-20T18:03:34.740334Z","shell.execute_reply":"2026-05-20T18:03:46.666346Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.figure(figsize=(12, 5))\n\n# --- 1. Accuracy Grafiği ---\nplt.subplot(1, 2, 1)\nplt.plot(history_resnet.history['accuracy'], label='Train Accuracy')\nplt.plot(history_resnet.history['val_accuracy'], label='Validation Accuracy')\nplt.title(\"ResNet50 - Accuracy\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend()\n\n# --- 2. Loss Grafiği ---\nplt.subplot(1, 2, 2)\nplt.plot(history_resnet.history['loss'], label='Train Loss')\nplt.plot(history_resnet.history['val_loss'], label='Validation Loss')\nplt.title(\"ResNet50 - Loss\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Loss\")\nplt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:32:03.771634Z","iopub.execute_input":"2026-05-20T18:32:03.772010Z","iopub.status.idle":"2026-05-20T18:32:04.090298Z","shell.execute_reply.started":"2026-05-20T18:32:03.771959Z","shell.execute_reply":"2026-05-20T18:32:04.089739Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\n\n# ResNet50'nin tahminleri ve gerçek değerlerle matrisi oluşturma\ncm_resnet = confusion_matrix(y_test, resnet_predictions)\n\n# Grafiğin boyutunu ayarlama\nplt.figure(figsize=(8, 6))\n\n# Seaborn kütüphanesi ile ısı haritası (heatmap) şeklinde matrisi çizme\nsns.heatmap(cm_resnet, annot=True, fmt='d', cmap='Blues', \n            xticklabels=['Healthy', 'Diseased'], \n            yticklabels=['Healthy', 'Diseased'],\n            cbar_kws={'label': 'Görüntü Sayısı'})\n\n# Başlık ve eksen isimlerini ekleme\nplt.title('ResNet50 Confusion Matrix')\nplt.ylabel('Actual (Gerçek Sınıf)')\nplt.xlabel('Predicted (Tahmin Edilen Sınıf)')\n\n# Grafiği gösterme\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:07:30.548530Z","iopub.execute_input":"2026-05-20T18:07:30.549495Z","iopub.status.idle":"2026-05-20T18:07:30.700015Z","shell.execute_reply.started":"2026-05-20T18:07:30.549461Z","shell.execute_reply":"2026-05-20T18:07:30.699159Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\n\n# Model isimleri ve yeni performans metrikleri (Güncel değerler)\nmodels = ['MobileNetV2', 'ResNet50']\naccuracy_scores = [0.90, 0.50]\nf1_scores = [0.90, 0.33]\n\n# Çubukların genişliği ve X eksenindeki konumları\nx = np.arange(len(models))\nwidth = 0.35\n\n# Grafik figürünü oluşturma\nfig, ax = plt.subplots(figsize=(8, 6))\nrects1 = ax.bar(x - width/2, accuracy_scores, width, label='Accuracy')\nrects2 = ax.bar(x + width/2, f1_scores, width, label='F1-Score')\n\n# Eksen etiketleri, başlık ve isimlendirmeler\nax.set_ylabel('Scores')\nax.set_title('Model Performance Comparison (MobileNetV2 vs ResNet50)')\nax.set_xticks(x)\nax.set_xticklabels(models)\nax.set_ylim(0, 1.1)  # Değerlerin grafiğin en tepesine yapışmaması için limiti 1.1 yaptık\nax.legend(loc='lower center')\n\n# Arka plana yatay ızgara (grid) ekleme\nax.yaxis.grid(True, linestyle='--', alpha=0.6)\n\n# Çubukların tam tepe noktasına değerleri yazdıran fonksiyon\ndef autolabel(rects):\n    for rect in rects:\n        height = rect.get_height()\n        ax.annotate(f'{height:.2f}',\n                    xy=(rect.get_x() + rect.get_width() / 2, height),\n                    xytext=(0, 3),  # Yazıyı 3 birim yukarı ötele\n                    textcoords=\"offset points\",\n                    ha='center', va='bottom')\n\n# Fonksiyonu her iki çubuk grubu için çağırma\nautolabel(rects1)\nautolabel(rects2)\n\n# Grafiği ekrana basma\nfig.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T18:09:12.569590Z","iopub.execute_input":"2026-05-20T18:09:12.570193Z","iopub.status.idle":"2026-05-20T18:09:12.722938Z","shell.execute_reply.started":"2026-05-20T18:09:12.570161Z","shell.execute_reply":"2026-05-20T18:09:12.722271Z"}},"outputs":[],"execution_count":null}]}