{"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":30201,"databundleVersionId":2750748}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 🔬 Hücre Segmentasyonu Proje Raporu\n\n## 📊 1. Proje Yönetici Özeti (Executive Summary)\n\n| Parametre | Değer / Açıklama |\n| :--- | :--- |\n| **Proje Hedefi** | Düşük kontrastlı biyolojik görüntülerde otomatik maskeleme |\n| **Model Mimarisi** | Özelleştirilmiş U-Net (Deep Learning)[cite: 33] |\n| **Ana Metrik** | Dice Coefficient (Zar Katsayısı) |\n| **Ham Başarı** | 0.7351 Dice Score |\n| **Final Başarı** | **0.8287 Dice Score** (Optimizasyon Sonrası) |\n| **Durum** | Tamamlandı (Başarılı)[cite: 31, 32] |\n\n---\n\n## ⚙️ 2. Teknik Analiz ve Eğitim Süreci\n\n### 🔹 Model Optimizasyonu\nEğitim sürecinde modelin takıldığı noktalar akıllı callback yapılarıyla aşılmıştır:\n* **Dinamik LR Yönetimi:** `ReduceLROnPlateau` kullanılarak, 9. epokta loss takılması üzerine öğrenme oranı **0.0002**'ye çekilmiş ve modelin daha hassas öğrenmesi sağlanmıştır.[cite: 33]\n* **Kararlılık:** 25. epoktan itibaren öğrenme oranı `1e-06` seviyesine kadar indirilerek eğitim kaybı **0.39** bandında stabilize edilmiştir.\n\n### 🔹 Performans Artırıcı Teknikler\nFinal skorundaki **%12.7'lik** artış şu iki kritik hamle ile sağlanmıştır:\n1. **TTA (Test Time Augmentation):** Test aşamasında görüntülerin yansıtılması ve döndürülmesiyle modelin geometrik bakış açısı genişletilmiştir.\n2. **Eşik (Threshold) Taraması:** Yapılan testler sonucunda en yüksek Dice skorunun **0.5** eşik değerinde elde edildiği matematiksel olarak saptanmıştır.\n\n---\n\n## 🧠 3. Hata Analizi ve Çözüm Yaklaşımları\n\n* **Doku Karmaşası:** Modelin ilk versiyonları, görüntülerdeki yapay kesik izlerini ve su damlacıklarını hücre dokusuyla karıştırma eğilimi göstermiştir.[cite: 31]\n* **Form Ağırlığı:** Yapılan iyileştirmelerle modelin sadece renk özelliklerine değil, nesne formuna da odaklanması sağlanmış, böylece gürültülü (noisy) arka planlarda daha tutarlı maskeler üretilmiştir.[cite: 31]\n\n---","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport cv2\nimport os\nimport seaborn as sns","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:42.028430Z","iopub.execute_input":"2026-05-05T16:39:42.028719Z","iopub.status.idle":"2026-05-05T16:39:47.004555Z","shell.execute_reply.started":"2026-05-05T16:39:42.028684Z","shell.execute_reply":"2026-05-05T16:39:47.003581Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import kagglehub\n\n# Veriyi indir ve yolu belirle\npath = kagglehub.competition_download('sartorius-cell-instance-segmentation')\nTRAIN_CSV = os.path.join(path, 'train.csv')\nTRAIN_PATH = os.path.join(path, 'train')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:47.006441Z","iopub.execute_input":"2026-05-05T16:39:47.006834Z","iopub.status.idle":"2026-05-05T16:39:48.468487Z","shell.execute_reply.started":"2026-05-05T16:39:47.006804Z","shell.execute_reply":"2026-05-05T16:39:48.467560Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Eğitim klasörü yolu\nTRAIN_CSV = \"/kaggle/input/competitions/sartorius-cell-instance-segmentation/train.csv\"\nTRAIN_PATH = \"/kaggle/input/competitions/sartorius-cell-instance-segmentation/train\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:48.469614Z","iopub.execute_input":"2026-05-05T16:39:48.470141Z","iopub.status.idle":"2026-05-05T16:39:48.474789Z","shell.execute_reply.started":"2026-05-05T16:39:48.470090Z","shell.execute_reply":"2026-05-05T16:39:48.473932Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Veriyi oku\ntrain_df = pd.read_csv(TRAIN_CSV)\nprint(f\"Veri yüklendi. Toplam kayıt: {len(train_df)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:48.475937Z","iopub.execute_input":"2026-05-05T16:39:48.476404Z","iopub.status.idle":"2026-05-05T16:39:49.287660Z","shell.execute_reply.started":"2026-05-05T16:39:48.476359Z","shell.execute_reply":"2026-05-05T16:39:49.286827Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Hücre Tiplerinin Dağılımı\nplt.figure(figsize=(10, 5))\nsns.countplot(data=train_df, x='cell_type', palette='viridis')\nplt.title('Hücre Tiplerine Göre Kayıt Sayısı')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:49.288622Z","iopub.execute_input":"2026-05-05T16:39:49.290013Z","iopub.status.idle":"2026-05-05T16:39:49.717718Z","shell.execute_reply.started":"2026-05-05T16:39:49.289980Z","shell.execute_reply":"2026-05-05T16:39:49.716941Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Görüntü Başına Düşen Hücre Sayısı\ncells_per_image = train_df.groupby('id')['annotation'].count()\nplt.figure(figsize=(10, 5))\nsns.histplot(cells_per_image, bins=30, kde=True, color='orange')\nplt.title('Görüntü Başına Hücre Sayısı Dağılımı')\nplt.xlabel('Hücre Sayısı')\nplt.ylabel('Görüntü Sayısı')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:49.718721Z","iopub.execute_input":"2026-05-05T16:39:49.719079Z","iopub.status.idle":"2026-05-05T16:39:49.979599Z","shell.execute_reply.started":"2026-05-05T16:39:49.719053Z","shell.execute_reply":"2026-05-05T16:39:49.978792Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Her hücre tipinden bir örnek görselleştirme\ncell_types = train_df['cell_type'].unique()\nfig, axes = plt.subplots(1, 3, figsize=(20, 10))\n\nfor i, c_type in enumerate(cell_types):\n    sample_id = train_df[train_df['cell_type'] == c_type].iloc[0]['id']\n    img_path = os.path.join(TRAIN_PATH, f\"{sample_id}.png\")\n    img = cv2.imread(img_path)\n    \n    axes[i].imshow(img)\n    axes[i].set_title(f\"Tip: {c_type}\")\n    axes[i].axis('off')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:49.982045Z","iopub.execute_input":"2026-05-05T16:39:49.982353Z","iopub.status.idle":"2026-05-05T16:39:50.597561Z","shell.execute_reply.started":"2026-05-05T16:39:49.982329Z","shell.execute_reply":"2026-05-05T16:39:50.596597Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Hücre tiplerinin dağılımını inceleme\nplt.figure(figsize=(10, 6))\nsns.countplot(data=train_df, x='cell_type', hue='cell_type', palette='magma', legend=False)\nplt.title('Hücre Tiplerine Göre Dağılım')\nplt.ylabel('Toplam Örnek Sayısı')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:50.599104Z","iopub.execute_input":"2026-05-05T16:39:50.599450Z","iopub.status.idle":"2026-05-05T16:39:50.979475Z","shell.execute_reply.started":"2026-05-05T16:39:50.599412Z","shell.execute_reply":"2026-05-05T16:39:50.978762Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Yardımcı Fonksiyonlar ve Metrikler\nimport tensorflow as tf\nfrom tensorflow.keras import backend as K\n\ndef apply_clahe(image):\n    # Görüntü normalize gelmişse 255'e çekiyoruz\n    img_uint8 = (image * 255).astype(np.uint8)\n    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n    \n    # Eğer kanal boyutu sondaysa (H, W, 1), onu (H, W) formatına düşürüyoruz\n    if len(img_uint8.shape) == 3:\n        img_uint8 = img_uint8.squeeze() \n        \n    final_img = clahe.apply(img_uint8)\n    # Tekrar (H, W, 1) ve normalize hale getiriyoruz\n    return final_img.astype(np.float32) / 255.0\n\ndef rle_decode(mask_rle, shape=(520, 704)):\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0] * shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape)\n\n# İsim get_mask olarak güncellendi!\ndef get_mask(image_id, df):\n    shape = (520, 704)\n    labels = df[df[\"id\"] == image_id][\"annotation\"].tolist()\n    mask = np.zeros(shape, dtype=np.uint8)\n    for label in labels:\n        # Maskeleri birleştirirken mantıksal OR kullanmak daha güvenlidir\n        mask = np.logical_or(mask, rle_decode(label, shape))\n    return mask.astype(np.float32)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:39:50.980343Z","iopub.execute_input":"2026-05-05T16:39:50.980646Z","iopub.status.idle":"2026-05-05T16:40:33.368672Z","shell.execute_reply.started":"2026-05-05T16:39:50.980619Z","shell.execute_reply":"2026-05-05T16:40:33.367933Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Metrikler\ndef dice_coef(y_true, y_pred):\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = K.sum(y_true_f * y_pred_f)\n    return (2. * intersection + 1.0) / (K.sum(y_true_f) + K.sum(y_pred_f) + 1.0)\n\ndef bce_dice_loss(y_true, y_pred):\n    # Binary crossentropy ve Dice loss toplamı\n    bce = tf.keras.losses.binary_crossentropy(y_true, y_pred)\n    dice_loss = 1 - dice_coef(y_true, y_pred)\n    return bce + dice_loss","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:40:33.369688Z","iopub.execute_input":"2026-05-05T16:40:33.370354Z","iopub.status.idle":"2026-05-05T16:40:33.375830Z","shell.execute_reply.started":"2026-05-05T16:40:33.370306Z","shell.execute_reply":"2026-05-05T16:40:33.375022Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def data_generator(df, batch_size=4, img_size=(512,512)):\n    ids = df[\"id\"].unique()\n    while True:\n        np.random.shuffle(ids)\n        for i in range(0, len(ids), batch_size):\n            batch_ids = ids[i:i+batch_size]\n            X, Y = [], []\n\n            for img_id in batch_ids:\n                path = os.path.join(TRAIN_PATH, f\"{img_id}.png\")\n                if not os.path.exists(path): continue\n\n                img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n                img = cv2.resize(img, img_size)\n                \n                # KRİTİK DÜZELTME: CLAHE ve Normalizasyon düzenlendi (Madde 3)\n                img = apply_clahe(img / 255.0) \n\n                mask = get_mask(img_id, df)\n                # KRİTİK DÜZELTME: INTER_NEAREST eklendi (Madde 2)\n                mask = cv2.resize(mask, img_size, interpolation=cv2.INTER_NEAREST)\n\n                X.append(np.expand_dims(img, -1)) # Explicit expand (Madde 4)\n                Y.append(np.expand_dims(mask, -1))\n\n            if len(X):\n                yield np.array(X, dtype=np.float32), np.array(Y, dtype=np.float32)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:40:33.378068Z","iopub.execute_input":"2026-05-05T16:40:33.378433Z","iopub.status.idle":"2026-05-05T16:40:33.437452Z","shell.execute_reply.started":"2026-05-05T16:40:33.378394Z","shell.execute_reply":"2026-05-05T16:40:33.436691Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Gelişmiş U-Net Mimarisi\n\nfrom tensorflow.keras import layers, models, optimizers\n\ndef build_improved_unet(input_shape=(512, 512, 1)):\n    inputs = layers.Input(input_shape)\n\n    def conv_block(x, filters):\n        x = layers.Conv2D(filters, 3, padding='same')(x)\n        x = layers.BatchNormalization()(x)\n        x = layers.Activation('relu')(x)\n        x = layers.Conv2D(filters, 3, padding='same')(x)\n        x = layers.BatchNormalization()(x)\n        x = layers.Activation('relu')(x)\n        return x\n\n    # Encoder\n    f1 = conv_block(inputs, 32)\n    p1 = layers.MaxPooling2D(2)(f1)\n    f2 = conv_block(p1, 64)\n    p2 = layers.MaxPooling2D(2)(f2)\n\n    # Bridge\n    f3 = conv_block(p2, 128)\n\n    # Decoder\n    u4 = layers.Conv2DTranspose(64, 2, strides=2, padding='same')(f3)\n    u4 = layers.concatenate([u4, f2])\n    f4 = conv_block(u4, 64)\n    u5 = layers.Conv2DTranspose(32, 2, strides=2, padding='same')(f4)\n    u5 = layers.concatenate([u5, f1])\n    f5 = conv_block(u5, 32)\n\n    outputs = layers.Conv2D(1, 1, activation='sigmoid')(f5)\n    return models.Model(inputs, outputs)\n\n# Modeli oluştur\nmodel = build_improved_unet()\n\n# Derle (bce_dice_loss ve dice_coef'in daha önceki hücrelerde tanımlandığından emin ol)\nmodel.compile(optimizer=optimizers.Adam(learning_rate=1e-3), \n              loss=bce_dice_loss, \n              metrics=[dice_coef, 'binary_accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:40:33.438496Z","iopub.execute_input":"2026-05-05T16:40:33.438812Z","iopub.status.idle":"2026-05-05T16:40:38.021976Z","shell.execute_reply.started":"2026-05-05T16:40:33.438781Z","shell.execute_reply":"2026-05-05T16:40:38.021254Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n# Veriyi Böl\nunique_ids = train_df['id'].unique()\ntrain_ids, val_ids = train_test_split(unique_ids, test_size=0.15, random_state=42)\n\ntrain_gen = data_generator(train_df[train_df['id'].isin(train_ids)], batch_size=4)\nval_gen = data_generator(train_df[train_df['id'].isin(val_ids)], batch_size=4)\n\ncallbacks = [\n    tf.keras.callbacks.ModelCheckpoint('best_sartorius_model.keras', monitor='val_dice_coef', save_best_only=True, mode='max'),\n    tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, min_lr=1e-6, verbose=1),\n    tf.keras.callbacks.EarlyStopping(monitor='val_dice_coef', patience=10, restore_best_weights=True)\n]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:40:38.022949Z","iopub.execute_input":"2026-05-05T16:40:38.023285Z","iopub.status.idle":"2026-05-05T16:40:38.282317Z","shell.execute_reply.started":"2026-05-05T16:40:38.023261Z","shell.execute_reply":"2026-05-05T16:40:38.281256Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Adımları sağlama alalım\nspe = max(1, len(train_ids) // 4)\nvs = max(1, len(val_ids) // 4)\n\ncallbacks = [\n    tf.keras.callbacks.ModelCheckpoint(\n        'best_sartorius_model.keras', \n        monitor='val_dice_coef', \n        save_best_only=True, \n        mode='max'\n    ),\n    tf.keras.callbacks.ReduceLROnPlateau(\n        monitor='val_loss', \n        factor=0.2, \n        patience=3, \n        min_lr=1e-6, \n        verbose=1\n    ),\n    tf.keras.callbacks.EarlyStopping(\n        monitor='val_dice_coef', \n        patience=10, \n        mode='max', \n        restore_best_weights=True\n    )\n]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:40:38.283593Z","iopub.execute_input":"2026-05-05T16:40:38.284361Z","iopub.status.idle":"2026-05-05T16:40:38.290609Z","shell.execute_reply.started":"2026-05-05T16:40:38.284332Z","shell.execute_reply":"2026-05-05T16:40:38.289786Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Eğitim parametrelerini netleştirme\nbatch_size = 4 # Generator içinde kullandığın batch size ile aynı olmalı\n\n# Adım sayılarını manuel hesaplayarak hata payını sıfırlama\nspe = int(np.ceil(len(train_ids) / batch_size))\nvs = int(np.ceil(len(val_ids) / batch_size))\n\ntry:\n    history = model.fit(\n        train_gen,\n        steps_per_epoch=spe,\n        validation_data=val_gen,\n        validation_steps=vs, # Sadece 'vs' kullanmak yeterli, val_steps parametresi fit içinde yoktur\n        epochs=50,\n        callbacks=callbacks\n    )\nexcept Exception as e:\n    print(f\"Eğitim sırasında bir hata oluştu: {e}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:40:38.291780Z","iopub.execute_input":"2026-05-05T16:40:38.292299Z","iopub.status.idle":"2026-05-05T16:59:27.773203Z","shell.execute_reply.started":"2026-05-05T16:40:38.292272Z","shell.execute_reply":"2026-05-05T16:59:27.772249Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.figure(figsize=(12, 5))\nplt.plot(history.history['dice_coef'], label='Eğitim Dice')\nplt.plot(history.history['val_dice_coef'], label='Doğrulama Dice')\nplt.title('Model Dice Skoru Gelişimi')\nplt.xlabel('Epoch')\nplt.ylabel('Dice Score')\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:27.774337Z","iopub.execute_input":"2026-05-05T16:59:27.774764Z","iopub.status.idle":"2026-05-05T16:59:27.941462Z","shell.execute_reply.started":"2026-05-05T16:59:27.774725Z","shell.execute_reply":"2026-05-05T16:59:27.940777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\n# Kayıp (Loss) Grafiği\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Eğitim Kaybı', color='blue')\nplt.plot(history.history['val_loss'], label='Doğrulama Kaybı', color='orange')\nplt.title('Model Kayıp (Loss) Gelişimi')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:27.942369Z","iopub.execute_input":"2026-05-05T16:59:27.942678Z","iopub.status.idle":"2026-05-05T16:59:28.136030Z","shell.execute_reply.started":"2026-05-05T16:59:27.942651Z","shell.execute_reply":"2026-05-05T16:59:28.135226Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# En iyi ağırlıkları yükle\nmodel.load_weights('best_sartorius_model.keras')\n\n# Rastgele bir test görüntüsü alma\nval_gen_sample = data_generator(train_df[train_df['id'].isin(val_ids)], batch_size=1)\ntest_img, test_mask = next(val_gen_sample)\n\n# Tahmin yap\npreds = model.predict(test_img)\npreds = (preds > 0.5).astype(np.uint8)\n\n# Görselleştir\nplt.figure(figsize=(18, 6))\n\nplt.subplot(1, 3, 1)\nplt.imshow(test_img[0], cmap='gray')\nplt.title(\"Orijinal Görüntü\")\nplt.axis('off')\n\nplt.subplot(1, 3, 2)\nplt.imshow(test_mask[0], cmap='gray')\nplt.title(\"Gerçek Maske (Ground Truth)\")\nplt.axis('off')\n\nplt.subplot(1, 3, 3)\nplt.imshow(preds[0], cmap='viridis')\nplt.title(f\"Model Tahmini (Dice: {history.history['val_dice_coef'][-1]:.4f})\")\nplt.axis('off')\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:28.137065Z","iopub.execute_input":"2026-05-05T16:59:28.137990Z","iopub.status.idle":"2026-05-05T16:59:34.255709Z","shell.execute_reply.started":"2026-05-05T16:59:28.137952Z","shell.execute_reply":"2026-05-05T16:59:34.254719Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\n\ndef post_process(mask, min_size=50):\n    # Küçük gürültüleri temizle (Area filtering)\n    num_component, component_mask, stats, centroids = cv2.connectedComponentsWithStats(mask.astype(np.uint8))\n    cleaned_mask = np.zeros_like(mask)\n    \n    for i in range(1, num_component):\n        if stats[i, cv2.CC_STAT_AREA] >= min_size:\n            cleaned_mask[component_mask == i] = 1\n            \n    # Delikleri doldur (Morphological closing)\n    kernel = np.ones((3,3), np.uint8)\n    cleaned_mask = cv2.morphologyEx(cleaned_mask, cv2.MORPH_CLOSE, kernel)\n    \n    return cleaned_mask\n\n# Bir örnek üzerinde dene\ncleaned_sample = post_process(preds[0])\n\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nplt.imshow(preds[0], cmap='viridis')\nplt.title(\"Ham Model Tahmini\")\nplt.subplot(1, 2, 2)\nplt.imshow(cleaned_sample, cmap='viridis')\nplt.title(\"Temizlenmiş (Post-Processed) Tahmin\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:34.256963Z","iopub.execute_input":"2026-05-05T16:59:34.257314Z","iopub.status.idle":"2026-05-05T16:59:34.762264Z","shell.execute_reply.started":"2026-05-05T16:59:34.257289Z","shell.execute_reply":"2026-05-05T16:59:34.761255Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# TTA Uygulama \n\ndef predict_with_tta(model, image):\n    # Orijinal resim\n    p1 = model.predict(image)\n    \n    # Yatay çevrilmiş resim\n    img_flip = np.flip(image, axis=2)\n    p2 = model.predict(img_flip)\n    p2 = np.flip(p2, axis=2) # Tahmini geri çevir\n    \n    # Dikey çevrilmiş resim\n    img_vflip = np.flip(image, axis=1)\n    p3 = model.predict(img_vflip)\n    p3 = np.flip(p3, axis=1) # Tahmini geri çevir\n    \n    # Ortalamayı al\n    tta_result = (p1 + p2 + p3) / 3.0\n    return tta_result\n\n# Yeni tahmini dene\ntta_preds = predict_with_tta(model, test_img)\ntta_preds_final = (tta_preds > 0.5).astype(np.uint8)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:34.763349Z","iopub.execute_input":"2026-05-05T16:59:34.764125Z","iopub.status.idle":"2026-05-05T16:59:35.064839Z","shell.execute_reply.started":"2026-05-05T16:59:34.764093Z","shell.execute_reply":"2026-05-05T16:59:35.064235Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# TTA sonuçlarını 0.5 eşiği ile maskeye dönüştür\ntta_preds_final = (tta_preds > 0.5).astype(np.uint8)\n\n# Yeni Dice skorunu hesapla (Örnek bazında)\ndef calculate_dice(y_true, y_pred):\n    intersection = np.sum(y_true * y_pred)\n    return (2. * intersection) / (np.sum(y_true) + np.sum(y_pred) + 1e-7)\n\nnew_dice = calculate_dice(test_mask[0], tta_preds_final[0])\nprint(f\"TTA Sonrası Yeni Dice Skoru: {new_dice:.4f}\")\n\n# Görsel kıyaslama\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nplt.imshow(preds[0], cmap='viridis')\nplt.title(f\"TTA Öncesi (Dice: {history.history['val_dice_coef'][-1]:.4f})\")\n\nplt.subplot(1, 2, 2)\nplt.imshow(tta_preds_final[0], cmap='viridis')\nplt.title(f\"TTA Sonrası (Dice: {new_dice:.4f})\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:35.065988Z","iopub.execute_input":"2026-05-05T16:59:35.066331Z","iopub.status.idle":"2026-05-05T16:59:35.433753Z","shell.execute_reply.started":"2026-05-05T16:59:35.066305Z","shell.execute_reply":"2026-05-05T16:59:35.432888Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Farklı eşik değerlerini test etme\nthresholds = [0.40, 0.45, 0.50]\nbest_dice = 0\nbest_thr = 0.5\n\nfor thr in thresholds:\n    # TTA sonuçlarına yeni eşiği uygula\n    current_preds = (tta_preds > thr).astype(np.uint8)\n    \n    # Dice skorunu hesapla\n    current_dice = calculate_dice(test_mask[0], current_preds[0])\n    print(f\"Eşik: {thr:.2f} -> Dice Skoru: {current_dice:.4f}\")\n    \n    if current_dice > best_dice:\n        best_dice = current_dice\n        best_thr = thr\n\nprint(f\"\\n--- SONUÇ ---\")\nprint(f\"En İyi Eşik Değeri: {best_thr}\")\nprint(f\"Final Dice Skoru: {best_dice:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T16:59:35.437512Z","iopub.execute_input":"2026-05-05T16:59:35.438375Z","iopub.status.idle":"2026-05-05T16:59:35.447992Z","shell.execute_reply.started":"2026-05-05T16:59:35.438346Z","shell.execute_reply":"2026-05-05T16:59:35.446924Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 📈 4. Final Değerlendirme ve Gelecek Vizyonu\n\nBu çalışma, hücre segmentasyonu gibi yüksek hassasiyet gerektiren tıbbi görüntüleme görevlerinde **U-Net** mimarisinin ve **TTA** tekniklerinin gücünü kanıtlamıştır.\n\n**Gelecek Adımlar:**\n* Segmentasyon sonuçlarından yola çıkarak otomatik **hücre sayımı** yapan bir modülün entegrasyonu.\n* Modelin **Streamlit** üzerinde bir web arayüzüne taşınarak canlı kullanıma açılması.[cite: 32]","metadata":{}},{"cell_type":"markdown","source":"---\n\n### ✍️ Proje Yürütücüsü\n\n**Serdar ÖNAL**  \n*İnşaat Mühendisi (20+ Yıl Deneyim) & Yapay Zeka Araştırmacısı* \n\n\n\n---","metadata":{}},{"cell_type":"code","source":"# Modeli .h5 veya yeni .keras formatında kaydedebilirsin\nmodel.save('hucre_segmentasyon_modeli_final.keras')\nmodel.save_weights('hucre_segmentasyon_weights.weights.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-05T17:28:56.025742Z","iopub.execute_input":"2026-05-05T17:28:56.026062Z","iopub.status.idle":"2026-05-05T17:28:56.383250Z","shell.execute_reply.started":"2026-05-05T17:28:56.026035Z","shell.execute_reply":"2026-05-05T17:28:56.382241Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}