{"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":13451,"datasetId":654585,"databundleVersionId":1188070}],"dockerImageVersionId":31328,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# RSNA Intracranial Hemorrhage Detection","metadata":{}},{"cell_type":"markdown","source":"### Link: https://www.kaggle.com/competitions/rsna-intracranial-hemorrhage-detection","metadata":{}},{"cell_type":"markdown","source":"### 🔬 Radiological Preprocessing: Mapping DICOM Windows (HU) to RGB Channels\nUnlike standard computer vision algorithms, medical pixel fidelity is preserved by mapping the high dynamic range CT data into a 3-channel RGB format utilizing medically validated Hounsfield Unit (HU) windows: **Brain Window (Red), Subdural Window (Green), and Bone Window (Blue)**. This radiological intervention maximizes the contrast of hemorrhage textures for the Convolutional Neural Network (CNN).","metadata":{}},{"cell_type":"code","source":"import pydicom\nimport glob\nimport numpy as np\nimport matplotlib.pyplot as plt\n\narama_yolu = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/*.dcm\"\ndosyalar = glob.glob(arama_yolu)\n\nif len(dosyalar) > 0:\n    hedef_dosya = dosyalar[0]\n    print(\"Kilit kırıldı, dosya negatif HU taramasıyla işleniyor:\", hedef_dosya)\n    \n    # --- Tıbbi Pencereleme Fonksiyonlarımız ---\n    def get_first(x):\n        if type(x) == pydicom.multival.MultiValue: return int(x[0])\n        return int(x)\n\n    def window_image(img, center, width, intercept, slope):\n        img = (img * slope + intercept)\n        img_min = center - (width // 2)\n        img_max = center + (width // 2)\n        img[img < img_min] = img_min\n        img[img > img_max] = img_max\n        return (img - img_min) / (img_max - img_min)\n\n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n    _, _, inter, slope = [get_first(x) for x in fields]\n    \n    # İŞTE HAYAT KURTARAN TIP MÜHENDİSLİĞİ DOKUNUŞU:\n    # \"Negatif Doku yoğunluklarına (Hava = -1024) izin ver\"\n    img = dataset.pixel_array.astype(float)\n    \n    red = window_image(img.copy(), 40, 80, inter, slope)       # Brain / Beyin Dokusu (Kırmızı)\n    green = window_image(img.copy(), 80, 200, inter, slope)    # Subdural Bölge (Yeşil)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)   # Bone / Kafatası (Mavi)\n    \n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n    \n    # --- Ekrana Çizdirme ---\n    plt.figure(figsize=(10,10))\n    plt.imshow(rgb)\n    plt.title(\"RSNA Brain - Subdural - Bone CT Window\")\n    plt.axis('off')\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:27:05.098948Z","iopub.execute_input":"2026-04-25T08:27:05.099138Z","iopub.status.idle":"2026-04-25T08:27:22.706929Z","shell.execute_reply.started":"2026-04-25T08:27:05.099116Z","shell.execute_reply":"2026-04-25T08:27:22.706152Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\n# Cevap anahtarının tam klasör yolu\ncsv_yolu = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train.csv\"\n\nprint(\"Cevap anahtarı okunuyor... (Bu tablo biraz büyük, saniyeler sürebilir)\")\ntanilar_tablosu = pd.read_csv(csv_yolu)\n\nprint(\"Klinik Tablo Yüklendi! Toplam Kayıt Sayısı:\", len(tanilar_tablosu))\n\n# Tablonun en üstündeki ilk 10 radyoloji raporunu görelim:\ntanilar_tablosu.head(10)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:27:22.708745Z","iopub.execute_input":"2026-04-25T08:27:22.709186Z","iopub.status.idle":"2026-04-25T08:27:27.755308Z","shell.execute_reply.started":"2026-04-25T08:27:22.709161Z","shell.execute_reply":"2026-04-25T08:27:27.75441Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Veriler tıbbi hasta dosyası matrisine (Pivot) dönüştürülüyor. Bu işlem yaklaşık 10-15 saniye sürebilir...\")\n\n# 1. Aynı dosyadan mükerrer girmeler yapılmışsa onları silelim (Kaggle verisinde bu hata çok olur)\ntanilar_tablosu = tanilar_tablosu.drop_duplicates(subset=['ID']).copy()\n\n# 2. 'ID' sütunundaki \"_\" işaretinden bölerek \"Hasta_ID\" ve \"Kanama_Tipi\" olarak ikiye ayıralım\ntanilar_tablosu[['Slice_ID', 'Hemorrhage_Type']] = tanilar_tablosu['ID'].str.rsplit('_', n=1, expand=True)\n\n# 3. Pivot Yapalım: Herkesin tek bir satırı olsun, Kanama tipleri yanına sütun olarak dizilsin\nhasta_matrisi = tanilar_tablosu.pivot(index='Slice_ID', columns='Hemorrhage_Type', values='Label')\n\n# Kafa karışıklığını önlemek için sadece kanama sütunlarını öne alalım\nhasta_matrisi = hasta_matrisi[['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']]\n\nprint(\"İşlem Başarılı! İşte Yapay Zekanın Aşık Olacağı O Harika Tıbbi Format:\")\nhasta_matrisi.head(10)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:27:27.75715Z","iopub.execute_input":"2026-04-25T08:27:27.757447Z","iopub.status.idle":"2026-04-25T08:27:42.62269Z","shell.execute_reply.started":"2026-04-25T08:27:27.757423Z","shell.execute_reply":"2026-04-25T08:27:42.621906Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# matriste herhangi bir kanaması (any == 1) olan hastaları filtreleyelim\nkanamali_hastalar = hasta_matrisi[hasta_matrisi['any'] == 1]\n\n# Kanaması olan İLK hastanın numarasını alalım (Örn: ID_xxxxxx)\nkanamali_hasta_id = kanamali_hastalar.index[0]\n\nprint(\"🚨 DİKKAT: Kanamalı Hasta Bulundu!\")\nprint(\"Hasta Numarası:\", kanamali_hasta_id)\nprint(\"\\nUzmanların Koyduğu Teşhis Tablosu:\")\nprint(kanamali_hastalar.loc[kanamali_hasta_id])\n\n# Şimdi adresini bulup resmini de ekrana basalım\nhedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{kanamali_hasta_id}.dcm\"\n\n# Önceki kodumuzda kullandığımız pencereleri aynen çalıştırıyoruz\ndataset = pydicom.dcmread(hedef_dosya)\nfields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n_, _, inter, slope = [get_first(x) for x in fields]\n\nimg = dataset.pixel_array.astype(float)\nred = window_image(img.copy(), 40, 80, inter, slope)       \ngreen = window_image(img.copy(), 80, 200, inter, slope)    \nblue = window_image(img.copy(), 600, 2800, inter, slope)   \n\nrgb = np.zeros((img.shape[0], img.shape[1], 3))\nrgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\nplt.figure(figsize=(10,10))\nplt.imshow(rgb)\nplt.title(f\"Pozitif Kanama Tespiti: {kanamali_hasta_id}\")\nplt.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:27:42.623719Z","iopub.execute_input":"2026-04-25T08:27:42.624566Z","iopub.status.idle":"2026-04-25T08:27:43.218432Z","shell.execute_reply.started":"2026-04-25T08:27:42.624529Z","shell.execute_reply":"2026-04-25T08:27:43.217631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import math\nimport cv2\nimport tensorflow as tf\nfrom tensorflow.keras.utils import Sequence\n\nprint(\"Taşıyıcı Bant Sistemi (Data Generator) İnşa Ediliyor...\")\n\n# Bandın Ana Mekanizması\nclass RSNADataset(Sequence):\n    def __init__(self, hasta_listesi, etiket_matrisi, batch_size=32, img_size=(256, 256)):\n        self.hasta_listesi = hasta_listesi\n        self.etiket_matrisi = etiket_matrisi\n        self.batch_size = batch_size\n        self.img_size = img_size\n        self.dcm_dir = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\"\n        \n    def __len__(self):\n        # Tüm hastaların kaç koliye sığacağını hesaplar\n        return math.ceil(len(self.hasta_listesi) / self.batch_size)\n    \n    def __getitem__(self, idx):\n        # Yapay zeka ne zaman \"Sıradaki koli gelsin!\" dese bu kısım çalışır\n        batch_ids = self.hasta_listesi[idx * self.batch_size : (idx + 1) * self.batch_size]\n        \n        # X: Görüntülerin yerleştirileceği kutu (Koli boyutu, En, Boy, 3 Renk kanalı)\n        X = np.zeros((len(batch_ids), self.img_size[0], self.img_size[1], 3)) \n        # Y: Tıbbi teşhislerin listesi (Koli boyutu, 6 Farklı hastalık sütunu)\n        Y = np.zeros((len(batch_ids), 6))\n        \n        for i, p_id in enumerate(batch_ids):\n            dcm_path = self.dcm_dir + str(p_id) + \".dcm\"\n            try:\n                # Tomografiyi okuyoruz\n                dataset = pydicom.dcmread(dcm_path)\n                fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n                _, _, inter, slope = [get_first(x) for x in fields]\n                \n                img = dataset.pixel_array.astype(float)\n                \n                # 3 Tıbbi Pencereden geçiriyoruz (Sizin uzmanlığınız olan adım)\n                red = window_image(img.copy(), 40, 80, inter, slope)\n                green = window_image(img.copy(), 80, 200, inter, slope)\n                blue = window_image(img.copy(), 600, 2800, inter, slope)\n                \n                rgb = np.zeros((img.shape[0], img.shape[1], 3))\n                rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n                \n                # CT Görüntüleri normalde çok büyüktür (512x512). Yapay zeka hızlansın diye 256x256 yapıyoruz.\n                rgb_resized = cv2.resize(rgb, self.img_size)\n                \n                X[i,] = rgb_resized\n                Y[i,] = self.etiket_matrisi.loc[p_id].values\n                \n            except Exception as e:\n                # Eğer Kaggle depolarında dosyası bozuk bir hasta varsa sistemi çökertmemek için görmezden gelir\n                pass \n                \n        return X, Y\n\nprint(\"✅ Fabrika İnşa Edildi!\")\n\n# ----------------- SİSTEM TESTİ -----------------\n# Tablomuzdaki tüm hastaların numara listesini alalım\ntam_hasta_listesi = hasta_matrisi.index.tolist()\n\n# Bandı test edelim: Bir koliye sadece 8 hasta sığsın\ntest_bandi = RSNADataset(tam_hasta_listesi, hasta_matrisi, batch_size=8)\n\n# Düğmeye basıp banttan sıradaki İLK koliyi alalım:\nornek_resimler, ornek_teşhisler = test_bandi[0]\n\nprint(\"\\n--- İlk Koli Teslim Alındı ---\")\nprint(\"Röntgen Paketinin Çapı:\", ornek_resimler.shape)\nprint(\"Teşhis Paketinin Çapı:\", ornek_teşhisler.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:27:43.219396Z","iopub.execute_input":"2026-04-25T08:27:43.219742Z","iopub.status.idle":"2026-04-25T08:28:25.544761Z","shell.execute_reply.started":"2026-04-25T08:27:43.21971Z","shell.execute_reply":"2026-04-25T08:28:25.543945Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 🧱 Stage 1 Training: Addressing Class Imbalance & The 'Amnesia' Trap\nThe overwhelming prevalence of the \"Healthy\" class in the raw dataset often causes the model to take a shortcut, memorizing cranial boundaries instead of learning pathology. To prevent this \"Amnesia Trap\", the clinical dataset was artificially Balanced to a 50/50 ratio. Furthermore, the pre-trained EfficientNet base layers were **Frozen (Frozen Base)**. This forces the model to synthesize generic shape recognition into a specialized hemorrhage decision-lobe rather than simply overfitting to the skull contours.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\nfrom tensorflow.keras.models import Model\n\nprint(\"Uzman Zeka (EfficientNet) Laboratuvara Transfer Ediliyor...\")\n\n# 1. Eski tecrübeli beyni (EfficientNetB0) alıyoruz.\n# include_top=False: Eski karar mekanizmasını (köpek/kedi/araba tanıma kısmı) kesip atar.\n# weights='imagenet': Şekilleri ve kenarları önceden öğrenmiş vizyon tecrübesini korur.\ntemel_beyin = EfficientNetB0(input_shape=(256, 256, 3), include_top=False, weights='imagenet')\n\n# 2. Beynin üzerine kendi karar mekanizmamızı (Hemorrhage) ekliyoruz\nx = temel_beyin.output\nx = GlobalAveragePooling2D()(x) # Trilyonlarca piksel bilgisini hücre seviyesinde özetler ve sıkıştırır\nx = Dropout(0.3)(x)             # Tıpta \"Aşırı ezberlemeyi\" (Overfitting) önlemek çok önemlidir! Sisteme ufacık bir unutkanlık eşiği ekliyoruz.\n\n# 3. Nihai Karar Lobu: 6 farklı hastalık (kanama) tipi için bağımsız 6 adet çıkış vanası!\n# Sigmoid kullanıyoruz ki: Hem Subdural 1, hem Epidural 1 olabilsin. Birbirini engellemesinler.\nkesin_tanilar = Dense(6, activation='sigmoid')(x)\n\n# Vücutla (Temel Beyin) Yeni Kafayı (Nihai Lob) cerrahi olarak birleştiriyoruz\nbizim_model = Model(inputs=temel_beyin.input, outputs=kesin_tanilar)\n\n# 4. Asistanın çalışmaya başlama / öğrenme talimatları\n# tf.keras.optimizers.Adam: Hangi hızla öğreneceğini belirler (çok yavaş olursa vakit biter, çok hızlı olursa dersleri anlamaz)\noptimizer = tf.keras.optimizers.Adam(learning_rate=0.0005) \n\n# Sistemi derleyelim\nbizim_model.compile(optimizer=optimizer, \n                    loss='binary_crossentropy', # Çok seçmeli ve birden fazla cevabı olabilecek sınavlar (Multi-label) için en iyi puanlama yöntemi\n                    metrics=['accuracy', tf.keras.metrics.AUC(multi_label=True)]) # Doğruluk yüzdesi ve AUC skoru çetelesi\n\nprint(\"\\n✅ Ve Asistanımızın Yeni Beyni Cerrahi Olarak Hazırlandı!\")\nprint(\"İşte beynin katmanlarının röntgeni (Özeti):\")\nbizim_model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:28:25.545746Z","iopub.execute_input":"2026-04-25T08:28:25.546331Z","iopub.status.idle":"2026-04-25T08:28:31.408256Z","shell.execute_reply.started":"2026-04-25T08:28:25.546304Z","shell.execute_reply":"2026-04-25T08:28:31.407675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Eğitim Süreci (Asistan Asistanlığı) Başlıyor...\")\n\n# Taşıyıcı bantımızı standart fabrika ayarlarına (Koli başı 32 Hasta) getirelim\norijinal_egitim_bandi = RSNADataset(tam_hasta_listesi, hasta_matrisi, batch_size=32)\n\n# Asistanın derse oturduğu an! \n# Epochs: Kitabı baştan sona kaç kere okuyacağı (1 yeterli)\n# steps_per_epoch: Kitabın tamamını değil de, şimdilik sadece ilk 50 sayfayı (koliyi) okuyup bırakması için.\nhistory = bizim_model.fit(\n    orijinal_egitim_bandi, \n    epochs=1,\n    steps_per_epoch=50,\n    verbose=1\n)\n\nprint(\"\\n🎯 Harika! Asistan 1600 hastayı (50 Koli) dakikalar içinde inceledi ve eğitim aşamasını kavradı.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:28:31.410255Z","iopub.execute_input":"2026-04-25T08:28:31.410575Z","iopub.status.idle":"2026-04-25T08:30:46.287564Z","shell.execute_reply.started":"2026-04-25T08:28:31.410547Z","shell.execute_reply":"2026-04-25T08:30:46.28672Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport cv2\n\n# Daha önce bulduğumuz o kanamalı hastayı (ID_27a354d42) tekrar viziteye çağırıyoruz\nsecili_hasta_id = kanamali_hasta_id  \n\n# Masadaki Gerçek Tıbbi Raporumuz (Cevap Anahtarımız)\ngercek_tanilar = hasta_matrisi.loc[secili_hasta_id]\n\n# Hastanın Tomografisini Arşivden Alalım\nhedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + secili_hasta_id + \".dcm\"\n\n# Hızlıca Pencereleri Çizelim (Asistanın gözlüğünü takalım)\ndataset = pydicom.dcmread(hedef_dosya)\nfields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n_, _, inter, slope = [get_first(x) for x in fields]\n\nimg = dataset.pixel_array.astype(float)\nred = window_image(img.copy(), 40, 80, inter, slope)\ngreen = window_image(img.copy(), 80, 200, inter, slope)\nblue = window_image(img.copy(), 600, 2800, inter, slope)\n\nrgb = np.zeros((img.shape[0], img.shape[1], 3))\nrgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n# Yapay Zeka için yeniden boyutlandırma\nrgb_resized = cv2.resize(rgb, (256, 256))\n\n# Yapay zekaya bu resmi sanki 1 kişilik bir yığınmış (batch) gibi klasöre koyup gönderelim\nyapay_zeka_verisi = np.expand_dims(rgb_resized, axis=0)\n\n# ================================\n# ASİSTANIN FİKRİNİ ALIYORUZ!\ntahminler = bizim_model.predict(yapay_zeka_verisi)\n# ================================\n\nkanama_tipleri = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\nprint(f\"\\n=============================================\")\nprint(f\"   👨‍⚕️ UZMAN DOKTOR VS 🤖 YAPAY ZEKA   \")\nprint(f\"   HASTA: {secili_hasta_id}\")\nprint(f\"=============================================\\n\")\n\nfor i, tip in enumerate(kanama_tiplerizzz):\n    # Eğer cevap anahtarı 1 ise VAR, 0 ise YOK yazalım\n    gercek_sonuc = \"VAR\" if gercek_tanilar[tip] == 1 else \"Yok \"\n    \n    # Asistanın cevabını (0.00 ile 1.00 arası değişen sayıyı) Yüzdeye (%) çevirelim\n    asistan_tahmini = tahminler[0][i] * 100 \n    \n    # Karşılaştırmalı Ekrana Yazdıralım\n    print(f\"🩸 {tip.ljust(16).upper()}   | 👨‍⚕️ UZMAN: {gercek_sonuc.ljust(4)} | 🤖 ASİSTAN: % {asistan_tahmini:.1f} Şüphe\")\n\n# Ve Görsel Olarak Hastayı da Gösterelim\nplt.figure(figsize=(7,7))\nplt.imshow(rgb)\nplt.title(f\"Clinical Audit: {secili_hasta_id}\")\nplt.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:10:20.770423Z","iopub.execute_input":"2026-04-25T09:10:20.771185Z","iopub.status.idle":"2026-04-25T09:10:20.901767Z","shell.execute_reply.started":"2026-04-25T09:10:20.771152Z","shell.execute_reply":"2026-04-25T09:10:20.900842Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nprint(\"Bilimsel Kanıt (Learning Curve) Aşaması Başlıyor...\")\n\n# Asistanın okuyacağı kitap sayısını artırıyoruz. \n# 5 Tur (Epoch) boyunca hastaları tekrar tekrar inceleyecek ve her seferinde kendini düzeltecek.\nGELISMIS_EGITIM_TURU = 5\nGELISMIS_TEST_ADIMI = 50 # Her turda 50 koli tomografi okuyacak\n\n# Asistan ders programına (Fit) geri dönüyor\nhistory = bizim_model.fit(\n    orijinal_egitim_bandi, \n    epochs=GELISMIS_EGITIM_TURU,\n    steps_per_epoch=GELISMIS_TEST_ADIMI,\n    verbose=1\n)\n\n# -----------------------------------------------------\n# EĞİTİM BİTTİ -> ŞİMDİ BUNU KLİNİK GRAFİĞE DÖKÜYORUZ\n# -----------------------------------------------------\nplt.figure(figsize=(14, 5))\n\n# 1. Grafik: Asistanın Hata Payı (Loss) - Zamanla düşmesi beklenir!\nplt.subplot(1, 2, 1)\nplt.plot(history.history['loss'], label='Hata Skoru', color='red', linewidth=2, marker='o')\nplt.title('Asistanın Yanılma Payı (Loss Göstergesi)')\nplt.xlabel('Eğitim Turu (Epochs)')\nplt.ylabel('Hata Miktarı')\nplt.grid(True, linestyle='--', alpha=0.6)\nplt.legend()\n\n# 2. Grafik: Asistanın Teşhis Başarısı (Accuracy ve AUC) - Zamanla yükselmesi beklenir!\nplt.subplot(1, 2, 2)\nplt.plot(history.history['accuracy'], label='Genel Doğruluk', color='green', linewidth=2, marker='s')\nplt.plot(history.history['auc'], label='Klinik Hassasiyet (AUC)', color='blue', linewidth=2, marker='^')\nplt.title('Asistanın Doğru Teşhis Kapasitesi')\nplt.xlabel('Eğitim Turu (Epochs)')\nplt.ylabel('Başarı Yüzdesi (0.0 - 1.0)')\nplt.grid(True, linestyle='--', alpha=0.6)\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n\nprint(\"\\n✅ Mükemmel! Asistanın zaman geçtikçe nasıl uzmanlaştığını bilimsel grafiklerle ispatladınız.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:10:33.045639Z","iopub.execute_input":"2026-04-25T09:10:33.045981Z","iopub.status.idle":"2026-04-25T09:14:51.395305Z","shell.execute_reply.started":"2026-04-25T09:10:33.045957Z","shell.execute_reply":"2026-04-25T09:14:51.394293Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\n\nprint(\"Sınav Kağıtları Hazırlanıyor (Eğitim Dışı Verilerden)...\")\n\n# Asistan sadece ilk 1600 hastayı görmüştü. Biz 2000. sıradan sonrasına gidiyoruz!\nhic_gorulmeden_kalanlar = tam_hasta_listesi[2000:]\n\n# 3 Adet Rastgele Kanamalı Hasta Bulalım\nkanamali_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nkanamali_havuz = kanamali_havuz[kanamali_havuz['any'] == 1].index.tolist()\nsinav_kanamalilar = random.sample(kanamali_havuz, 3)\n\n# 2 Adet Rastgele Sapasağlam Hasta Bulalım\nsaglam_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nsaglam_havuz = saglam_havuz[saglam_havuz['any'] == 0].index.tolist()\nsinav_saglamlar = random.sample(saglam_havuz, 2)\n\n# Sınav Dosyasını Birleştirip Karıştıralım ki Kopya Çekemesin!\nsinav_hastalar = sinav_kanamalilar + sinav_saglamlar\nrandom.shuffle(sinav_hastalar) \n\nprint(\"Sınav Başladı! 5 Hastanın Tomografisi İnceleniyor...\\n\")\n\nkanama_tipleri = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\n# 5 Hastayı yan yana göstermek için geniş bir tablo çiziyoruz\nfig, axes = plt.subplots(1, 5, figsize=(25, 7))\n\nfor i, hasta_id in enumerate(sinav_hastalar):\n    gercek_tanilar = hasta_matrisi.loc[hasta_id]\n    hedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + hasta_id + \".dcm\"\n    \n    # Pencereleri Giydirme\n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n    _, _, inter, slope = [get_first(x) for x in fields]\n\n    img = dataset.pixel_array.astype(float)\n    red = window_image(img.copy(), 40, 80, inter, slope)\n    green = window_image(img.copy(), 80, 200, inter, slope)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n    \n    # 256x256 modele uygun küçültme\n    rgb_resized = cv2.resize(rgb, (256, 256))\n    yapay_zeka_verisi = np.expand_dims(rgb_resized, axis=0)\n    \n    # ================================\n    # ASİSTAN CEVAPLIYOR (Predict)\n    tahmin_yuzdeleri = bizim_model.predict(yapay_zeka_verisi, verbose=0)[0]\n    # ================================\n\n    # Çıktıları Yazdırma\n    ax = axes[i]\n    ax.imshow(rgb)\n    ax.axis('off')\n    \n    gercek_any = \"KANAMA VAR\" if gercek_tanilar['any'] == 1 else \"SAGLIKLI\"\n    \n    # Tıbbi Sınav Raporu\n    rapor = f\"Hasta: {hasta_id[-8:]}\\n\"\n    rapor += f\"👨‍⚕️ UZMAN: {gercek_any}\\n\"\n    rapor += '-'*28 + '\\n'\n    rapor += \"TUR    | UZMAN | ASİSTAN\\n\"\n    \n    for idx, tip in enumerate(kanama_tipleri):\n        g = \"VAR \" if gercek_tanilar[tip] == 1 else \"YOK \"\n        t_yuzde = tahmin_yuzdeleri[idx] * 100\n        # Asistanın kararı %50 üzerindeyse tehlike var demektir\n        t_karar = \"🚨\" if t_yuzde > 50 else \"✅\"\n        \n        rapor += f\"{tip[:6].upper().ljust(6)} | {g}  | %{t_yuzde:02.0f} {t_karar}\\n\"\n        \n    ax.set_title(rapor, loc='left', fontsize=12, fontfamily='monospace')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:14:55.434021Z","iopub.execute_input":"2026-04-25T09:14:55.434533Z","iopub.status.idle":"2026-04-25T09:14:59.343988Z","shell.execute_reply.started":"2026-04-25T09:14:55.434507Z","shell.execute_reply":"2026-04-25T09:14:59.343184Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\n\nprint(\"Başhekimin Emriyle Sınıf Dengesizliği (Class Imbalance / Hile) Çözülüyor...\")\n\n# 1. Kanamalı ve Sağlam hastalar havuzunu tamamen ikiye ayıralım\nkanamali_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 1].index.tolist()\nsaglikli_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 0].index.tolist()\n\n# 2. \"Şok Sınavı\" Dosyası (Tam 800 Kanamalı + 800 Sağlıklı = Yarı Yarıya Dağılım)\ndengeli_hastalar = kanamali_havuz_tam[:800] + saglikli_havuz_tam[:800]\n\n# Asistan kalıbı ezberlemesin diye kağıtların sırasını iyice karıştıralım\nrandom.shuffle(dengeli_hastalar)\n\n# 3. Yürüyen Bandı bu \"Torpilsiz ve Dengeli\" listeyle yeniden kuralım\ndengeli_egitim_bandi = RSNADataset(dengeli_hastalar, hasta_matrisi, batch_size=32)\n\nprint(\"\\nKoli İçeriği Düzeltildi! Bantta Artık Yarı Yarıya Hasta Var.\")\nprint(\"Asistanın Beynindeki Eski Temel Tembellikleri Silip, Eğitime Alıyoruz...\")\n\n# ----- YENİ VE TEMİZ BİR BEYİN -----\nx = temel_beyin.output\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\nx = tf.keras.layers.Dropout(0.3)(x)\nkesin_tanilar = tf.keras.layers.Dense(6, activation='sigmoid')(x)\n\nyeni_asistan = tf.keras.models.Model(inputs=temel_beyin.input, outputs=kesin_tanilar)\nyeni_asistan.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0005), \n                     loss='binary_crossentropy', \n                     metrics=['accuracy', tf.keras.metrics.AUC(multi_label=True)])\n# -----------------------------------\n\n# Şimdi Dengeli Hileyi Kırma Eğitimi Başlasın (Test adımı belirtmiyoruz çünkü listeyi tam 1600 verdik zaten)\nhistory_yeni = yeni_asistan.fit(\n    dengeli_egitim_bandi, \n    epochs=5,\n    verbose=1\n)\n\n# Eğitilen asistanı, asıl modelimizin üstüne kaydedelim ki ısı haritası bu düzelmiş modelle çalışsın\nbizim_model = yeni_asistan\n\nprint(\"\\nModelin tembelliği kırıldı! Asistan mecburen ter dökerek tüm kanamaları ayırt etmeyi çalıştı.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:24:14.512044Z","iopub.execute_input":"2026-04-25T09:24:14.512622Z","iopub.status.idle":"2026-04-25T09:27:31.565422Z","shell.execute_reply.started":"2026-04-25T09:24:14.512583Z","shell.execute_reply":"2026-04-25T09:27:31.56483Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport cv2\nimport pydicom\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nprint(\"Şok Eğitiminden Çıkmış Asistanın Yeni '5 Hastalık Sınavı' Başlıyor...\")\n\n# Asistanın yeni dengeli eğitimde de görmediği havuzdan rastgele 5 yeni kişi (Unseen)\nhic_gorulmeden_kalanlar = tam_hasta_listesi[2000:]\n\nkanamali_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nkanamali_havuz = kanamali_havuz[kanamali_havuz['any'] == 1].index.tolist()\nsinav_kanamalilar = random.sample(kanamali_havuz, 3) # 3 Kanamalı Hasta\n\nsaglam_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nsaglam_havuz = saglam_havuz[saglam_havuz['any'] == 0].index.tolist()\nsinav_saglamlar = random.sample(saglam_havuz, 2) # 2 Sağlıklı Hasta\n\n# Sınav Dosyasını Karıştır (Asistan kaç kişi sağlıklı bilmiyor)\nsinav_hastalar = sinav_kanamalilar + sinav_saglamlar\nrandom.shuffle(sinav_hastalar) \n\nkanama_tipleri = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\nfig, axes = plt.subplots(1, 5, figsize=(25, 7))\n\nfor i, hasta_id in enumerate(sinav_hastalar):\n    gercek_tanilar = hasta_matrisi.loc[hasta_id]\n    hedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + hasta_id + \".dcm\"\n    \n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n    \n    def get_first_local(x):\n        if type(x) == pydicom.multival.MultiValue: return int(x[0])\n        return int(x)\n\n    _, _, inter, slope = [get_first_local(x) for x in fields]\n\n    img = dataset.pixel_array.astype(float)\n    red = window_image(img.copy(), 40, 80, inter, slope)\n    green = window_image(img.copy(), 80, 200, inter, slope)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n    \n    rgb_resized = cv2.resize(rgb, (256, 256))\n    yapay_zeka_verisi = np.expand_dims(rgb_resized, axis=0)\n    \n    # ====================================================\n    # YENİ (DENGELİ) MODEL İLE TAHMİN\n    tahmin_yuzdeleri = bizim_model.predict(yapay_zeka_verisi, verbose=0)[0]\n    # ====================================================\n    \n    ax = axes[i]\n    ax.imshow(rgb)\n    ax.axis('off')\n    \n    gercek_any = \"KANAMALI\" if gercek_tanilar['any'] == 1 else \"SAGLIKLI\"\n    \n    rapor = f\"Hasta: {hasta_id[-8:]}\\n\"\n    rapor += f\"👨‍⚕️ UZMAN: {gercek_any}\\n\"\n    rapor += '-'*28 + '\\n'\n    rapor += \"TUR    | UZMAN | ASİSTAN\\n\"\n    \n    for idx, tip in enumerate(kanama_tipleri):\n        g = \"VAR \" if gercek_tanilar[tip] == 1 else \"YOK \"\n        t_yuzde = tahmin_yuzdeleri[idx] * 100\n        \n        # EĞER ASİSTAN %50'DEN ŞÜPHELİYSE ALARM (🚨), EMİNSE (✅) VERSİN\n        t_karar = \"🚨\" if t_yuzde >= 50 else \"✅\"\n        \n        rapor += f\"{tip[:6].upper().ljust(6)} | {g}  | %{t_yuzde:02.0f} {t_karar}\\n\"\n        \n    ax.set_title(rapor, loc='left', fontsize=12, fontfamily='monospace')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:28:01.555045Z","iopub.execute_input":"2026-04-25T09:28:01.555694Z","iopub.status.idle":"2026-04-25T09:28:12.644483Z","shell.execute_reply.started":"2026-04-25T09:28:01.555624Z","shell.execute_reply":"2026-04-25T09:28:12.643515Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pydicom\n\nprint(\"Tıbbi Anatomik (Isı Haritası / Grad-CAM) Analizi Başlıyor...\\n\")\n\n# Keras 3'ün otomatik arama bug'ına takılmamak için, \n# EfficientNet'in vizyon merkezinin adını doğrudan sisteme kilitliyoruz.\nson_gorsel_katman_adi = \"top_activation\"\n\nprint(f\"Asistanın Göz Sinir Uçları Manuel Olarak Kilitlendi: {son_gorsel_katman_adi}\")\n\ndef isi_haritasi_cikar(img_array, model, last_conv_layer_name):\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    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\n        # Karar verilen en güçlü hastalık skorunu hedef al\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    \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\n# Test için meşhur kanamalı hastamızı alalım\nornek_hasta_id = kanamali_hastalar.index[0]\nhedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + ornek_hasta_id + \".dcm\"\n\n# Görüntüyü Sizin Profesyonel Pencerelerinizden Geçirelim\ndataset = pydicom.dcmread(hedef_dosya)\nfields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n\ndef get_first_local(x):\n    if type(x) == pydicom.multival.MultiValue: return int(x[0])\n    return int(x)\n\n_, _, inter, slope = [get_first_local(x) for x in fields]\n\nimg = dataset.pixel_array.astype(float)\nred = window_image(img.copy(), 40, 80, inter, slope)\ngreen = window_image(img.copy(), 80, 200, inter, slope)\nblue = window_image(img.copy(), 600, 2800, inter, slope)\n\nrgb = np.zeros((img.shape[0], img.shape[1], 3))\nrgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\nrgb_resized = cv2.resize(rgb, (256, 256))\nimg_array = np.expand_dims(rgb_resized, axis=0)\n\n# ---------------------------------------------\n# İŞTE MUCİZE BURADA: Asistanı Isı Haritasına Zorla!\nheatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n# ---------------------------------------------\n\n# Haritayı Çizilebilir Formata Getirme (Kırmızı\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:42:25.580412Z","iopub.execute_input":"2026-04-25T09:42:25.580881Z","iopub.status.idle":"2026-04-25T09:42:27.775349Z","shell.execute_reply.started":"2026-04-25T09:42:25.58085Z","shell.execute_reply":"2026-04-25T09:42:27.774712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pydicom\n\nprint(\"Tıbbi Anatomik (Isı Haritası / Grad-CAM) Analizi Başlıyor...\\n\")\n\n# Arama işlemini iptal edip, Asistanın şüpheyi oluşturduğu asıl Göz Sinirini (top_activation) doğrudan veriyoruz:\nson_gorsel_katman_adi = \"top_activation\"\n\ndef isi_haritasi_cikar(img_array, model, last_conv_layer_name):\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    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\n        # Asistanın en çok şüphelendiği (Örn: Subdural) noktaya odaklan!\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    \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\n# ---------------------------------------------\n# Test edilecek Kanamalı Hastamız\nornek_hasta_id = kanamali_hastalar.index[0]\nhedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + ornek_hasta_id + \".dcm\"\n\n# 1. CT Görüntüsünü Tıbbi Pencerelere Ayır\ndataset = pydicom.dcmread(hedef_dosya)\nfields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n\ndef get_first_local(x):\n    if type(x) == pydicom.multival.MultiValue: return int(x[0])\n    return int(x)\n\n_, _, inter, slope = [get_first_local(x) for x in fields]\n\nimg = dataset.pixel_array.astype(float)\nred = window_image(img.copy(), 40, 80, inter, slope)\ngreen = window_image(img.copy(), 80, 200, inter, slope)\nblue = window_image(img.copy(), 600, 2800, inter, slope)\n\nrgb = np.zeros((img.shape[0], img.shape[1], 3))\nrgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\nrgb_resized = cv2.resize(rgb, (256, 256))\nimg_array = np.expand_dims(rgb_resized, axis=0)\n\n# 2. Isı Haritasını Çıkar\nheatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n\n# 3. YZ Odak Bölgesini Normal Görüntüye \"Alev (Jet)\" Renginde Monte Et\nheatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\nheatmap_resized = np.uint8(255 * heatmap_resized)\njet = plt.colormaps.get_cmap(\"jet\")\njet_colors = jet(np.arange(256))[:, :3]\njet_heatmap = jet_colors[heatmap_resized]\n\nsuperimposed_img = jet_heatmap * 0.4 + rgb\nsuperimposed_img = np.clip(superimposed_img, 0, 1)\n\n# Ekrana Çiz!\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nplt.imshow(rgb)\nplt.title(f\"A) {ornek_hasta_id} ORİJİNAL KESİT (UZMAN)\")\nplt.axis('off')\n\nplt.subplot(1, 2, 2)\nplt.imshow(superimposed_img)\nplt.title(\"B) ASİSTANIN KANAMA ŞÜPHESİ İÇİN BAKTIĞI DOKU (Grad-CAM)\")\nplt.axis('off')\n\nplt.tight_layout()\nplt.show()\n\nprint(\"\\n🚀 Başhekimim (Clinical Lead), sağdaki görüntüde yapay zeka anatomi olarak kafa derisine mi yığılmış yoksa kanama bölgesine mi bakıyor?\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:42:55.698273Z","iopub.execute_input":"2026-04-25T09:42:55.698872Z","iopub.status.idle":"2026-04-25T09:42:56.68698Z","shell.execute_reply.started":"2026-04-25T09:42:55.698832Z","shell.execute_reply":"2026-04-25T09:42:56.686079Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Müdahale Başlıyor: Asistanın Görsel Korteksi Kilitleniyor (Freezing)...\")\n\n# 1. Asistanın şekilleri ezberlemesini önlemek için temel beynini KİLİTLİYORUZ!\n# Artık kafatasını ezberleyemez, sadece teşhis koymayı öğrenmek ZORUNDA.\ntemel_beyin.trainable = False\n\n# 2. Üzerine yepyeni, tertemiz bir Karar Lobu ekleyelim\nx_yeni = temel_beyin.output\nx_yeni = tf.keras.layers.GlobalAveragePooling2D()(x_yeni)\nx_yeni = tf.keras.layers.Dropout(0.4)(x_yeni) # Kafası karışmasın diye unutma/eleme oranını %40'a çıkardık\nkesin_tanilar_yeni = tf.keras.layers.Dense(6, activation='sigmoid')(x_yeni)\n\n# Cerrah işlemi tamam\niyilestirilmis_model = tf.keras.models.Model(inputs=temel_beyin.input, outputs=kesin_tanilar_yeni)\n\n# Sistemi Derleyelim (Öğrenme hızını normal standartlara aldık)\niyilestirilmis_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), \n                             loss='binary_crossentropy', \n                             metrics=['accuracy', tf.keras.metrics.AUC(multi_label=True)])\n\nprint(\"🧠 Beyin Donduruldu! Asistan çok daha zorlu ve kopyasız bir eğitime alınıyor...\")\n\n# Öğrenme süreci (Beyin kilitli olduğu için GPU çok hızlı işleyecek)\nhistory_iyilestirilmis = iyilestirilmis_model.fit(\n    dengeli_egitim_bandi, \n    epochs=10,\n    verbose=1\n)\n\n# Eğitilen iyileştirilmiş asistanı asıl modelimize eşitleyelim \nbizim_model = iyilestirilmis_model\n\nprint(\"\\n🎯 Tedavi (İyileştirme) Tamamlandı! Artık ısı haritasını tekrar test edebiliriz.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:44:42.436223Z","iopub.execute_input":"2026-04-25T09:44:42.437095Z","iopub.status.idle":"2026-04-25T09:48:23.25901Z","shell.execute_reply.started":"2026-04-25T09:44:42.437061Z","shell.execute_reply":"2026-04-25T09:48:23.25838Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport cv2\nimport pydicom\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nprint(\"🧠 Dondurulmuş ve İyileştirilmiş Asistanın 'Yeni 5 Hastalık Çapraz Sorgusu' Başlıyor...\\n\")\n\n# Şüphe kalmasın diye yine tamamen YEPYENİ 5 kişi (Unseen) rastgele çağrılıyor\nhic_gorulmeden_kalanlar = tam_hasta_listesi[2000:]\n\nkanamali_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nkanamali_havuz = kanamali_havuz[kanamali_havuz['any'] == 1].index.tolist()\nsinav_kanamalilar = random.sample(kanamali_havuz, 3) \n\nsaglam_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nsaglam_havuz = saglam_havuz[saglam_havuz['any'] == 0].index.tolist()\nsinav_saglamlar = random.sample(saglam_havuz, 2) \n\nsinav_hastalar = sinav_kanamalilar + sinav_saglamlar\nrandom.shuffle(sinav_hastalar) \n\nkanama_tipleri = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\nfig, axes = plt.subplots(1, 5, figsize=(25, 7))\n\nfor i, hasta_id in enumerate(sinav_hastalar):\n    gercek_tanilar = hasta_matrisi.loc[hasta_id]\n    hedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + hasta_id + \".dcm\"\n    \n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n    \n    def get_first_local(x):\n        if type(x) == pydicom.multival.MultiValue: return int(x[0])\n        return int(x)\n\n    _, _, inter, slope = [get_first_local(x) for x in fields]\n\n    img = dataset.pixel_array.astype(float)\n    red = window_image(img.copy(), 40, 80, inter, slope)\n    green = window_image(img.copy(), 80, 200, inter, slope)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n    \n    rgb_resized = cv2.resize(rgb, (256, 256))\n    yapay_zeka_verisi = np.expand_dims(rgb_resized, axis=0)\n    \n    # ====================================================\n    # BEYNİ DONDURULMUŞ YENİ MODEL İLE TAHMİN\n    tahmin_yuzdeleri = bizim_model.predict(yapay_zeka_verisi, verbose=0)[0]\n    # ====================================================\n    \n    ax = axes[i]\n    ax.imshow(rgb)\n    ax.axis('off')\n    \n    gercek_any = \"KANAMALI\" if gercek_tanilar['any'] == 1 else \"SAGLIKLI\"\n    \n    rapor = f\"Hasta: {hasta_id[-8:]}\\n\"\n    rapor += f\"👨‍⚕️ UZMAN: {gercek_any}\\n\"\n    rapor += '-'*28 + '\\n'\n    rapor += \"TUR    | UZMAN | ASİSTAN\\n\"\n    \n    for idx, tip in enumerate(kanama_tipleri):\n        g = \"VAR \" if gercek_tanilar[tip] == 1 else \"YOK \"\n        t_yuzde = tahmin_yuzdeleri[idx] * 100\n        \n        # Asistan artık en az %40 şüphe duyarsa uyarı mekanizmasını tetiklesin\n        t_karar = \"🚨\" if t_yuzde >= 40 else \"✅\"  \n        \n        rapor += f\"{tip[:6].upper().ljust(6)} | {g}  | %{t_yuzde:02.0f} {t_karar}\\n\"\n        \n    ax.set_title(rapor, loc='left', fontsize=12, fontfamily='monospace')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:48:46.762031Z","iopub.execute_input":"2026-04-25T09:48:46.762774Z","iopub.status.idle":"2026-04-25T09:48:56.870584Z","shell.execute_reply.started":"2026-04-25T09:48:46.762742Z","shell.execute_reply":"2026-04-25T09:48:56.86977Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\n\nprint(\"🏥 Veri Havuzu Genişletiliyor (1.600 Hastadan -> 8.000 Hastaya Çıkış)...\\n\")\n\n# Kanamalı ve Sağlam hastalar havuzu\nkanamali_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 1].index.tolist()\nsaglikli_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 0].index.tolist()\n\n# 4000 Kanamalı ve 4000 Sağlıklı olmak üzere veri setini tam 5 KAT BÜYÜTÜYORUZ!\ndev_dengeli_hastalar = kanamali_havuz_tam[:4000] + saglikli_havuz_tam[:4000]\n\n# Tembellik yapıp sırayı ezberlemesin diye listeyi iyice karıştırıyoruz\nrandom.shuffle(dev_dengeli_hastalar)\n\n# Yeni \"Büyük Kapasiteli\" Yürüyen Bant\ndev_egitim_bandi = RSNADataset(dev_dengeli_hastalar, hasta_matrisi, batch_size=32)\n\nprint(\"Kapasite Artırıldı! Asistan bu 8.000 hastalık dev arşivi incelemeye başlıyor...\")\n\n# Zaten önceki adımda Dondurduğumuz modelimizi (iyilestirilmis_model) \n# bu devasa veri yığınıyla eğitiyoruz (Bu kez tur sayısı uzun süreceği için sadece 5 Tur dönüyoruz)\nhistory_dev = iyilestirilmis_model.fit(\n    dev_egitim_bandi, \n    epochs=5,\n    verbose=1\n)\n\n# Sistemimizi güncelleyelim\nbizim_model = iyilestirilmis_model\n\nprint(\"\\n✅ Harika! Asistan artık 1.600 değil, 8.000 hastanın paha biçilemez tecrübesine sahip!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T09:50:34.970052Z","iopub.execute_input":"2026-04-25T09:50:34.970877Z","iopub.status.idle":"2026-04-25T10:00:51.791518Z","shell.execute_reply.started":"2026-04-25T09:50:34.970844Z","shell.execute_reply":"2026-04-25T10:00:51.790926Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport cv2\nimport pydicom\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nprint(\"📊 8.000 Hastalık Tecrübeye Çıkan Asistanın 5 Hastalık Çapraz Sorgusu Başlıyor...\\n\")\n\n# Şüphe kalmasın diye yine tamamen YEPYENİ 5 kişi (Unseen) rastgele çağrılıyor\n# Asistanın eğitimde denk gelmiş olma ihtimaline karşı testi listenin çok daha ilerisinden alıyoruz (5000'den sonrası)\nhic_gorulmeden_kalanlar = tam_hasta_listesi[5000:]\n\nkanamali_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nkanamali_havuz = kanamali_havuz[kanamali_havuz['any'] == 1].index.tolist()\nsinav_kanamalilar = random.sample(kanamali_havuz, 3) \n\nsaglam_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nsaglam_havuz = saglam_havuz[saglam_havuz['any'] == 0].index.tolist()\nsinav_saglamlar = random.sample(saglam_havuz, 2) \n\nsinav_hastalar = sinav_kanamalilar + sinav_saglamlar\nrandom.shuffle(sinav_hastalar) \n\nkanama_tipleri = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\nfig, axes = plt.subplots(1, 5, figsize=(25, 7))\n\nfor i, hasta_id in enumerate(sinav_hastalar):\n    gercek_tanilar = hasta_matrisi.loc[hasta_id]\n    hedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + hasta_id + \".dcm\"\n    \n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n    \n    def get_first_local(x):\n        if type(x) == pydicom.multival.MultiValue: return int(x[0])\n        return int(x)\n\n    _, _, inter, slope = [get_first_local(x) for x in fields]\n\n    img = dataset.pixel_array.astype(float)\n    red = window_image(img.copy(), 40, 80, inter, slope)\n    green = window_image(img.copy(), 80, 200, inter, slope)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n    \n    rgb_resized = cv2.resize(rgb, (256, 256))\n    yapay_zeka_verisi = np.expand_dims(rgb_resized, axis=0)\n    \n    # ====================================================\n    # SADECE VERİSİ 8.000'E ÇIKARTILMIŞ MODEL İLE TAHMİN\n    tahmin_yuzdeleri = bizim_model.predict(yapay_zeka_verisi, verbose=0)[0]\n    # ====================================================\n    \n    ax = axes[i]\n    ax.imshow(rgb)\n    ax.axis('off')\n    \n    gercek_any = \"KANAMALI\" if gercek_tanilar['any'] == 1 else \"SAGLIKLI\"\n    \n    rapor = f\"Hasta: {hasta_id[-8:]}\\n\"\n    rapor += f\"👨‍⚕️ UZMAN: {gercek_any}\\n\"\n    rapor += '-'*28 + '\\n'\n    rapor += \"TUR    | UZMAN | ASİSTAN\\n\"\n    \n    for idx, tip in enumerate(kanama_tipleri):\n        g = \"VAR \" if gercek_tanilar[tip] == 1 else \"YOK \"\n        t_yuzde = tahmin_yuzdeleri[idx] * 100\n        \n        # Asistan artık en az %40 şüphe duyarsa alarmı (🚨) tetikleyecek\n        t_karar = \"🚨\" if t_yuzde >= 40 else \"✅\"  \n        \n        rapor += f\"{tip[:6].upper().ljust(6)} | {g}  | %{t_yuzde:02.0f} {t_karar}\\n\"\n        \n    ax.set_title(rapor, loc='left', fontsize=12, fontfamily='monospace')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T10:02:53.755356Z","iopub.execute_input":"2026-04-25T10:02:53.756255Z","iopub.status.idle":"2026-04-25T10:02:57.854793Z","shell.execute_reply.started":"2026-04-25T10:02:53.756222Z","shell.execute_reply":"2026-04-25T10:02:57.853862Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\n\nprint(\"📈 Veri Havuzu Zirveye Çıkıyor (8.000 Hastadan -> 20.000 Hastaya)...\\n\")\n\n# Kanamalı ve Sağlam hastalar havuzumuzu yeniden alıyoruz\nkanamali_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 1].index.tolist()\nsaglikli_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 0].index.tolist()\n\n# 10.000 Kanamalı + 10.000 Sağlıklı = 20.000 Hastalık MEGA Veri Seti!\n# Asistanın görüş açısını inanılmaz düzeyde artırıyoruz.\nmega_dengeli_hastalar = kanamali_havuz_tam[:10000] + saglikli_havuz_tam[:10000]\n\nrandom.shuffle(mega_dengeli_hastalar)\n\n# Yeni \"Mega Kapasiteli\" Yürüyen Bant\nmega_egitim_bandi = RSNADataset(mega_dengeli_hastalar, hasta_matrisi, batch_size=32)\n\nprint(\"20.000 Hastalık Mega Veri Bandı Kuruldu!\")\nprint(\"Sabrınızın karşılığını alacaksınız... Kutu sayısı çok arttığı için bu aşama biraz vakit alacaktır.\")\n\n# Zaten donuk olan (sadece karar lobu açık) iyilestirilmis_modelimizi bu dev yığınla eğitiyoruz\nhistory_mega = iyilestirilmis_model.fit(\n    mega_egitim_bandi, \n    epochs=5,\n    verbose=1\n)\n\n# Başarılarımızı asıl sisteme kaydedelim\nbizim_model = iyilestirilmis_model\n\nprint(\"\\n🏆 İnanılmaz! Asistan şu an 20.000 farklı hastanın tomografisini incelemiş gerçek bir 'Uzman Adayı' (Fellow) seviyesine çıktı! \\nO beklettiğiniz 5'li görsel taramayı tekrar yapıp farkı görebilirsiniz.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T10:03:12.645412Z","iopub.execute_input":"2026-04-25T10:03:12.646126Z","iopub.status.idle":"2026-04-25T10:28:21.605596Z","shell.execute_reply.started":"2026-04-25T10:03:12.646094Z","shell.execute_reply":"2026-04-25T10:28:21.604713Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 🎯 Stage 2 Training: Fine-Tuning for Microscopic Textural Vision\nAfter processing 20,000 cases, the Frozen model encounters a Representational Bottleneck (plateauing at ~70% AUC). To elevate the machine's predictive power to an Expert level, the top 20 layers of the visual cortex are **Unfrozen**. The learning rate is drastically lowered to `1e-4`, allowing the network to meticulously adapt its weights to the microscopic textures of blood clots without suffering from catastrophic forgetting.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\nprint(\"Mükemmeliyetçi Son Aşama: İnce Ayar (Fine-Tuning) Başlıyor...\\n\")\n\n# 1. Asistanın göz yeteneğindeki prangaları çözüyoruz (Unfreeze)\ntemel_beyin.trainable = True\n\n# 2. Tamamını çözersek bu sefer eski zekasını da kaybeder (Amnesia) diye,\n# SADECE teşhisleri okuyan son 20 sinir ucunu serbest bırakıyoruz.\nfor layer in temel_beyin.layers[:-20]:\n    layer.trainable = False\n\n# 3. Öğrenme hızını İNANILMAZ TÖRPÜLÜYORUZ (0.001 -> 0.0001)\n# Son 20 sinir ucunda \"Mikroskobik\" bir cerrahi ameliyat yapıyoruz, yavaş ve emin adımlarla gidecek.\niyilestirilmis_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), \n                             loss='binary_crossentropy', \n                             metrics=['accuracy', tf.keras.metrics.AUC(multi_label=True)])\n\nprint(\"🧠 Zincirler Kırıldı! Asistan kanın mikroskobik dokusunu (Texture) kavramaya çalışıyor...\")\n\n# Sadece 5 tur ilerliyoruz çünkü ince ayarda fazla gezmek her şeyi bozabilir\nhistory_finetune = iyilestirilmis_model.fit(\n    mega_egitim_bandi, # O yorucu 20.000'lik devasa tesis\n    epochs=5,\n    verbose=1\n)\n\n# Eğitilen şaheseri asıl sistem otomasyonuna bağlayalım\nbizim_model = iyilestirilmis_model\n\nprint(\"\\n🔥 BİLGİSAYARLI GÖRÜNÜN (COMPUTER VISION) ZİRVESİNE ULAŞILDI: FINE-TUNING BİTTİ!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T10:28:21.607221Z","iopub.execute_input":"2026-04-25T10:28:21.607527Z","iopub.status.idle":"2026-04-25T10:50:19.848466Z","shell.execute_reply.started":"2026-04-25T10:28:21.607504Z","shell.execute_reply":"2026-04-25T10:50:19.847868Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 📊 Radiological Board Exam: A Clinical Audit\nRelying solely on mathematical Accuracy metrics can be clinically deceiving. For a robust audit, **10 completely unseen patients** were randomly sampled for a visual 'Board Exam', pitting the AI's deductions against the Ground Truth of an Expert Radiologist. While the AI successfully isolated true hemorrhages, it demonstrated a critical clinical vulnerability: triggering **False Positives** on physiological Choroid Plexus/Pineal calcifications and beam-hardening bone artifacts. This highlights the indispensable necessity of human oversight in Medical AI.","metadata":{}},{"cell_type":"code","source":"import random\nimport cv2\nimport pydicom\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nprint(\"📊 10 Hastalık 'Board Sınavı' (Kapsamlı Test) Başlıyor...\\n\")\n\n# Hile yapamaması için listenin en sonundaki (hiç görmediği) hastalara gidiyoruz\nhic_gorulmeden_kalanlar = tam_hasta_listesi[10000:]\n\nkanamali_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nkanamali_havuz = kanamali_havuz[kanamali_havuz['any'] == 1].index.tolist()\nsinav_kanamalilar = random.sample(kanamali_havuz, 5) # 5 Kanamalı Kesit\n\nsaglam_havuz = hasta_matrisi.loc[hic_gorulmeden_kalanlar]\nsaglam_havuz = saglam_havuz[saglam_havuz['any'] == 0].index.tolist()\nsinav_saglamlar = random.sample(saglam_havuz, 5) # 5 Sağlıklı Kesit\n\nsinav_hastalar = sinav_kanamalilar + sinav_saglamlar\nrandom.shuffle(sinav_hastalar) \n\nkanama_tipleri = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\n# 2 Satır, 5 Sütunculuk dev bir ekran\nfig, axes = plt.subplots(2, 5, figsize=(25, 12))\naxes = axes.flatten()\n\nfor i, hasta_id in enumerate(sinav_hastalar):\n    gercek_tanilar = hasta_matrisi.loc[hasta_id]\n    hedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + hasta_id + \".dcm\"\n    \n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n    \n    def get_first_local(x):\n        if type(x) == pydicom.multival.MultiValue: return int(x[0])\n        return int(x)\n\n    _, _, inter, slope = [get_first_local(x) for x in fields]\n\n    img = dataset.pixel_array.astype(float)\n    red = window_image(img.copy(), 40, 80, inter, slope)\n    green = window_image(img.copy(), 80, 200, inter, slope)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n    \n    rgb_resized = cv2.resize(rgb, (256, 256))\n    yapay_zeka_verisi = np.expand_dims(rgb_resized, axis=0)\n    \n    # NİHAİ (FINE-TUNED) MODEL İLE TAHMİN\n    tahmin_yuzdeleri = bizim_model.predict(yapay_zeka_verisi, verbose=0)[0]\n    \n    ax = axes[i]\n    ax.imshow(rgb)\n    ax.axis('off')\n    \n    gercek_any = \"KANAMALI\" if gercek_tanilar['any'] == 1 else \"SAGLIKLI\"\n    \n    rapor = f\"Hasta: {hasta_id[-8:]}\\n\"\n    rapor += f\"👨‍⚕️ UZMAN: {gercek_any}\\n\"\n    rapor += '-'*25 + '\\n'\n    rapor += \"TUR   | UZ | ASİSTAN\\n\"\n    \n    for idx, tip in enumerate(kanama_tipleri):\n        g = \"VAR\" if gercek_tanilar[tip] == 1 else \"YOK\"\n        t_yuzde = tahmin_yuzdeleri[idx] * 100\n        \n        # Eğer kanama ihtimali %40 ve üzeriyse Kırmızı Alarm (🚨) versin\n        t_karar = \"🚨\" if t_yuzde >= 40 else \"✅\"  \n        \n        # Ekran dar olacağı için yazıları hafif kısalttık\n        rapor += f\"{tip[:5].upper().ljust(5)} | {g} | %{t_yuzde:02.0f} {t_karar}\\n\"\n        \n    ax.set_title(rapor, loc='left', fontsize=11, fontfamily='monospace')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T11:10:31.48816Z","iopub.execute_input":"2026-04-25T11:10:31.488856Z","iopub.status.idle":"2026-04-25T11:10:44.543432Z","shell.execute_reply.started":"2026-04-25T11:10:31.488821Z","shell.execute_reply":"2026-04-25T11:10:44.542302Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 🔪 Surgical Intervention: Skull-Stripping & The \"Domain Shift\" Shock\nTo medically resolve the AI's vulnerability to bone artifacts, the CT images were subjected to a computer vision masking process based on Hounsfield Unit (HU) density thresholds prior to model inference. The skull was completely stripped, leaving only the brain parenchyma.\n**Clinical Finding:** Even with the skull fully removed, the AI could not drop its suspicion to 0%. This confirms a vital machine learning phenomenon: **Domain Shift Shock**. Because the model acquired its 20,000 experiences solely observing \"skulls wrapped around brains\", presenting it with a \"naked skull-stripped\" brain caused spatial disorientation. *This elegantly proves that radiological preprocessing must be integrated during the mass training phase, not just inserted as a band-aid during inference.*","metadata":{}},{"cell_type":"code","source":"import cv2\nimport pydicom\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nprint(\"🧠 RADYOLOJİK CERRAHİ: Kafatası Soyma (Skull-Stripping) İşlemi Başlıyor...\\n\")\n\ndef kafatasi_soy_ct(rgb_resim):\n    # Görüntümüzü [0-255] piksel aralığında sabitleyelim\n    rgb_255 = np.uint8(rgb_resim * 255) if np.max(rgb_resim) <= 1 else np.uint8(rgb_resim)\n    \n    # Brain Window (Beyin Penceresi) RGB sistemimizde Kırmızı (İlk) kanaldadır\n    # Kafatası kemiği bu pencerede en parlak (255) piksellerdir. \n    gray = rgb_255[:,:,0] \n    \n    # 1. Kemiği Kesin Olarak Tespit Et (Çok parlak pikseller)\n    _, kemik_maskesi = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY)\n    \n    # 2. Kemik hattındaki boşlukları kapat (Morfolojik Kapanma / Closing)\n    kernel = np.ones((5,5), np.uint8)\n    kemik_maskesi = cv2.morphologyEx(kemik_maskesi, cv2.MORPH_CLOSE, kernel)\n    \n    # 3. Kafatasının Çember Sınırlarını Bul\n    contours, _ = cv2.findContours(kemik_maskesi, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)\n    \n    beyin_maskesi = np.zeros(gray.shape, dtype=np.uint8)\n    \n    if len(contours) > 0:\n        # En büyük dış sınır kafatasının en dış hattıdır\n        en_buyuk_kontur = max(range(len(contours)), key=lambda i: cv2.contourArea(contours[i]))\n        \n        # O sınırın İÇİNİ (Tüm kafayı) Maskeyle Doldur\n        cv2.drawContours(beyin_maskesi, contours, en_buyuk_kontur, 255, -1)\n        \n        # ŞİMDİ EN KRİTİK NOKTA: Maskeden kemiğin (kafa tası zarının) KENDİSİNİ ÇIKAR!\n        # Böylece sadece beynin iç yumuşak dokusu maskelenmiş kalır.\n        beyin_maskesi = cv2.subtract(beyin_maskesi, kemik_maskesi)\n        \n        # Kemiğin ince kenar / ışın saçılma (Beam Hardening) artefaktlarını temizlemek için maskeyi 2 tur aşındıralım (Erosion)\n        beyin_maskesi = cv2.erode(beyin_maskesi, kernel, iterations=2)\n    \n    # Çıkarılan bu muazzam maskeyi 3-kanallı resme uygulaıp etrafı karanlığa gömelim\n    beyin_maskesi_3d = np.stack([beyin_maskesi, beyin_maskesi, beyin_maskesi], axis=2) / 255.0\n    soyulmus_resim = rgb_resim * beyin_maskesi_3d\n    \n    return soyulmus_resim, beyin_maskesi\n\n# Az önce Asistanın KEMİĞİ kanama sandığı 2. Yalancı Pozitif hastamızı (İndeks 1) getirelim\nhatali_hasta_id = sinav_hastalar[1]\nhedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + hatali_hasta_id + \".dcm\"\n\n# CT Oku ve Pencerele (Standart)\ndataset = pydicom.dcmread(hedef_dosya)\nfields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n\ndef get_first_local(x):\n    if type(x) == pydicom.multival.MultiValue: return int(x[0])\n    return int(x)\n\n_, _, inter, slope = [get_first_local(x) for x in fields]\nimg = dataset.pixel_array.astype(float)\n\nred = window_image(img.copy(), 40, 80, inter, slope)\ngreen = window_image(img.copy(), 80, 200, inter, slope)\nblue = window_image(img.copy(), 600, 2800, inter, slope)\nrgb = np.zeros((img.shape[0], img.shape[1], 3))\nrgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\nrgb_resized = cv2.resize(rgb, (256, 256))\n\n# BÜYÜ MÜDAHALE: Kafatasını Piksellerden Sök\nsoyulmus_rgb, maske = kafatasi_soy_ct(rgb_resized)\n\n# GÖRSELLEŞTİRME\nplt.figure(figsize=(15, 5))\n\nplt.subplot(1, 3, 1)\nplt.imshow(rgb_resized)\nplt.title(\"A) ORİJİNAL KESİT\\n(Sol taraftaki kalın kemik artefaktına dikkat)\")\nplt.axis('off')\n\nplt.subplot(1, 3, 2)\nplt.imshow(maske, cmap='gray')\nplt.title(\"B) MATEMATİKSEL BEYİN MASKESİ\\n(Kafatası silindi)\")\nplt.axis('off')\n\nplt.subplot(1, 3, 3)\nplt.imshow(soyulmus_rgb)\nplt.title(\"C) KAFATASI SOYULMUŞ YENİ RÖNTGEN\\n(Artık sadece kanamaya bakılabilir)\")\nplt.axis('off')\n\nplt.tight_layout()\nplt.show()\n\n# Bakalım asistan \"Kemiksiz\" kalınca aynı yalanı atabilecek mi?\ntemiz_veri = np.expand_dims(soyulmus_rgb, axis=0)\neski_tahmin = bizim_model.predict(np.expand_dims(rgb_resized, axis=0), verbose=0)[0][0] * 100\nyeni_tahmin = bizim_model.predict(temiz_veri, verbose=0)[0][0] * 100\n\nprint(f\"\\n🩺 Asistanın Orijinal Kesitteki Evham Şüphesi: % {eski_tahmin:.1f} 🚨\")\nprint(f\"🩺 TIRAŞLI Kesite Bakınca Asistanın Şüphesi: % {yeni_tahmin:.1f} ✅\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T08:30:57.613359Z","iopub.status.idle":"2026-04-25T08:30:57.61393Z","shell.execute_reply.started":"2026-04-25T08:30:57.613794Z","shell.execute_reply":"2026-04-25T08:30:57.613816Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 🕵️ Medical Autopsy: Anatomical Illusion Map (Error-Focused Grad-CAM)\nIn standard Computer Vision, Heatmaps are typically used to boast correct predictions. In this study, guided by radiological scrutiny, Grad-CAM is utilized as an \"Autopsy\" tool to decipher **where and why the machine failed**. The heatmaps anatomically prove that the model wasn't hallucinating blood out of thin air; rather, it was misled by physiological calcifications and thick asymmetric bone artifacts, establishing a *Spurious Correlation* between high pixel density and pathology.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pydicom\n\nprint(\"🕵️ OTOPSİ BAŞLIYOR: Tıbbi Yanılsama Haritalarının (Error-Focused Grad-CAM) Deşifresi...\\n\")\n\nson_gorsel_katman_adi = \"top_activation\"\n\ndef isi_haritasi_cikar(img_array, model, last_conv_layer_name):\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    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\n        # Asistanın o hatalı kararını verirken \"En çok şüphelendiği\" noktaya kitlen\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    \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\n# Sınavda kandırılan iki sağlıklı hastamızı hafızadan çekiyoruz\n# 2. Hasta (Kemiğe aldanan) -> İndeks 1\n# 4. Hasta (Kireçlenmeye aldanan) -> İndeks 3\ntuzağa_dusenler = [sinav_hastalar[1], sinav_hastalar[3]]\nhata_tipleri = [\"KAFATASI ARTEFAKTI (Kemiğin Parlaması)\", \"KALSİFİKASYON (Kireçlenme)\"]\n\nfig, axes = plt.subplots(2, 2, figsize=(15, 12))\n\nfor i, y_id in enumerate(tuzağa_dusenler):\n    hedef_dosya = \"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/\" + y_id + \".dcm\"\n\n    dataset = pydicom.dcmread(hedef_dosya)\n    fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n              dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n\n    def get_first_local(x):\n        if type(x) == pydicom.multival.MultiValue: return int(x[0])\n        return int(x)\n\n    _, _, inter, slope = [get_first_local(x) for x in fields]\n\n    img = dataset.pixel_array.astype(float)\n    red = window_image(img.copy(), 40, 80, inter, slope)\n    green = window_image(img.copy(), 80, 200, inter, slope)\n    blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n    rgb = np.zeros((img.shape[0], img.shape[1], 3))\n    rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n    rgb_resized = cv2.resize(rgb, (256, 256))\n    img_array = np.expand_dims(rgb_resized, axis=0)\n\n    # ---------------------------------------------\n    # Asistanın o %88 ve %73 uydurma şüphesi nereden geliyor? Isı Haritasını alalım.\n    # ---------------------------------------------\n    heatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n    heatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\n    heatmap_resized = np.uint8(255 * heatmap_resized)\n    jet = plt.colormaps.get_cmap(\"jet\")\n    jet_colors = jet(np.arange(256))[:, :3]\n    jet_heatmap = jet_colors[heatmap_resized]\n\n    superimposed_img = jet_heatmap * 0.4 + rgb\n    superimposed_img = np.clip(superimposed_img, 0, 1)\n\n    tahmin_orani = bizim_model.predict(img_array, verbose=0)[0][0] * 100\n\n    # Sol Sütun: Orijinal Çizim\n    ax_orig = axes[i, 0]\n    ax_orig.imshow(rgb)\n    ax_orig.set_title(f\"A) {y_id} (Gerçek: SAĞLIKLI)\\nYZ'nın Yersiz Şüphesi: % {tahmin_orani:.1f} 🚨\", fontsize=11)\n    ax_orig.axis('off')\n\n    # Sağ Sütun: YZ Yanılsaması (CSI Odak Çizimi)\n    ax_heat = axes[i, 1]\n    ax_heat.imshow(superimposed_img)\n    ax_heat.set_title(f\"B) YZ'NİN YANILDIĞI ODAK (Grad-CAM)\\nTuzağa Düşüren Neden: {hata_tipleri[i]}\", fontsize=11)\n    ax_heat.axis('off')\n\nplt.tight_layout()\nplt.show()\n\nprint(\"\\n👨‍⚕️ OTOPSİ SONUCU: Görsel kanıtlanmıştır! Yapay zekalar beyindeki anatomik tuzaklarda 'Radyolog Yönlendirmesine' muhtaçtır.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T11:44:40.035333Z","iopub.execute_input":"2026-04-25T11:44:40.036107Z","iopub.status.idle":"2026-04-25T11:44:42.08028Z","shell.execute_reply.started":"2026-04-25T11:44:40.036073Z","shell.execute_reply":"2026-04-25T11:44:42.079341Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n# 🕵️‍♂️ Phase 3: Clinical Audit & Error Taxonomy (Grad-CAM Analysis)\n\nFrom a clinical radiologist's perspective, achieving 85% or 90% accuracy is **not sufficient** for safe deployment in a medical setting. In real-world clinical scenarios, answering the question *\"Why did the model fail?\"* is more critical than the accuracy score itself.\n\nTo prevent the model from relying on \"Shortcut Learning\" or \"Feature Biases\" (e.g., confusing skull thickness with hemorrhage), we must systematically audit the cases where the model **failed**. \n\n### 📌 Audit Methodology: Hunting \"False Positives\"\nIn the pipeline below, we scan an unseen dataset of **healthy patients** (Ground Truth = 0). Our goal is to catch instances where the AI panicked and confidently predicted **\"Hemorrhage Detected\"** (Prediction > 50%).\n\nOnce we capture these False Positive cases, we will pass them through an XAI (Explainable AI) tool using **Grad-CAM** heatmaps. This will allow us to visualize whether the AI was deceived by **the skull boundary, physiological calcifications (e.g., choroid plexus), or beam hardening artifacts**, enabling us to build a structured clinical error taxonomy.\n\n*The script below will run until it isolates and visualizes exactly 10 False Positive cases for our clinical review.*\n---\n","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport cv2\nimport pydicom\nimport random\nimport tensorflow as tf\n\nprint(\"🔎 CLINICAL AUDIT RADAR INITIALIZED!\")\nprint(\"Scanning for 'False Positive' cases...\\n\")\n\n# O hata veren \"for\" döngüsünü tamamen sildik. \n# EfficientNet'in görme merkezinin (son evrişim katmanının) adını biz zaten biliyoruz:\nson_gorsel_katman_adi = \"top_activation\"\n\ndef isi_haritasi_cikar(img_array, model, last_conv_layer_name):\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    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\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    \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 get_first_local(x):\n    if type(x) == pydicom.multival.MultiValue: return int(x[0])\n    return int(x)\n\n# Listelerimiz\ntest_patients = tam_hasta_listesi[2000:]\nrandom.shuffle(test_patients)\ncaptured_error_count = 0\nTARGET_ERROR_COUNT = 10 \n\n# Tarama başlıyor\nfor patient_id in test_patients:\n    if captured_error_count >= TARGET_ERROR_COUNT:\n        break \n\n    ground_truth = hasta_matrisi.loc[patient_id]['any']\n    \n    if ground_truth == 0:\n        target_file = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{patient_id}.dcm\"\n        \n        try:\n            dataset = pydicom.dcmread(target_file)\n            fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                      dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n            _, _, inter, slope = [get_first_local(x) for x in fields]\n\n            img = dataset.pixel_array.astype(float)\n            red = window_image(img.copy(), 40, 80, inter, slope)\n            green = window_image(img.copy(), 80, 200, inter, slope)\n            blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n            rgb = np.zeros((img.shape[0], img.shape[1], 3))\n            rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n            rgb_resized = cv2.resize(rgb, (256, 256))\n            img_array = np.expand_dims(rgb_resized, axis=0)\n            \n            predictions = bizim_model.predict(img_array, verbose=0)[0]\n            any_pred_percentage = predictions[0] * 100 \n            \n            if any_pred_percentage > 50.0:\n                captured_error_count += 1\n                print(f\"🚨 FALSE POSITIVE DETECTED: {patient_id} | Ground Truth: Healthy | AI Prediction: {any_pred_percentage:.1f}% Hemorrhage\")\n                \n                heatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n                heatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\n                heatmap_resized = np.uint8(255 * heatmap_resized)\n                jet = plt.colormaps.get_cmap(\"jet\")\n                jet_colors = jet(np.arange(256))[:, :3]\n                jet_heatmap = jet_colors[heatmap_resized]\n\n                superimposed_img = jet_heatmap * 0.4 + rgb\n                superimposed_img = np.clip(superimposed_img, 0, 1)\n                \n                plt.figure(figsize=(12, 5))\n                plt.subplot(1, 2, 1)\n                plt.imshow(rgb)\n                plt.title(f\"({captured_error_count}/{TARGET_ERROR_COUNT}) ORIGINAL CT\")\n                plt.axis('off')\n\n                plt.subplot(1, 2, 2)\n                plt.imshow(superimposed_img)\n                plt.title(\"AI FOCUS MAP (GRAD-CAM)\")\n                plt.axis('off')\n\n                # Görüntüleri Kaggle Output klasörüne kaydet\n                save_path = f\"/kaggle/working/FP_Case_{captured_error_count}_{patient_id}.png\"\n                plt.savefig(save_path, bbox_inches=\"tight\", dpi=150)\n                plt.close() \n                \n        except Exception as e:\n            print(f\"❌ ERROR: {e}\")\n\nprint(\"\\n✅ Radar Scan Complete! 10 Images successfully saved to the Output (/kaggle/working) folder.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T11:45:20.631972Z","iopub.execute_input":"2026-04-25T11:45:20.632253Z","iopub.status.idle":"2026-04-25T11:45:33.855627Z","shell.execute_reply.started":"2026-04-25T11:45:20.63223Z","shell.execute_reply":"2026-04-25T11:45:33.854865Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport cv2\nimport pydicom\nimport random\nimport tensorflow as tf\n\nprint(\"🔎 CALCIFICATION & ERROR SEARCH INITIALIZED!\")\nprint(\"Targeting 50 False Positive cases to hunt for physiological calcification errors...\\n\")\n\nson_gorsel_katman_adi = \"top_activation\"\n\ndef isi_haritasi_cikar(img_array, model, last_conv_layer_name):\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    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\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    \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 get_first_local(x):\n    if type(x) == pydicom.multival.MultiValue: return int(x[0])\n    return int(x)\n\ntest_patients = tam_hasta_listesi[2000:]\nrandom.shuffle(test_patients)\ncaptured_error_count = 0\n\n# Hedefimizi 50 hastaya (yaklaşık 5-6 dakikalık işlem) çıkardık:\nTARGET_ERROR_COUNT = 50 \n\nfor patient_id in test_patients:\n    if captured_error_count >= TARGET_ERROR_COUNT:\n        break \n\n    ground_truth = hasta_matrisi.loc[patient_id]['any']\n    \n    if ground_truth == 0:\n        target_file = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{patient_id}.dcm\"\n        \n        try:\n            dataset = pydicom.dcmread(target_file)\n            fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                      dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n            _, _, inter, slope = [get_first_local(x) for x in fields]\n\n            img = dataset.pixel_array.astype(float)\n            red = window_image(img.copy(), 40, 80, inter, slope)\n            green = window_image(img.copy(), 80, 200, inter, slope)\n            blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n            rgb = np.zeros((img.shape[0], img.shape[1], 3))\n            rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n            rgb_resized = cv2.resize(rgb, (256, 256))\n            img_array = np.expand_dims(rgb_resized, axis=0)\n            \n            predictions = bizim_model.predict(img_array, verbose=0)[0]\n            any_pred_percentage = predictions[0] * 100 \n            \n            if any_pred_percentage > 50.0:\n                captured_error_count += 1\n                \n                heatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n                heatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\n                heatmap_resized = np.uint8(255 * heatmap_resized)\n                jet = plt.colormaps.get_cmap(\"jet\")\n                jet_colors = jet(np.arange(256))[:, :3]\n                jet_heatmap = jet_colors[heatmap_resized]\n\n                superimposed_img = jet_heatmap * 0.4 + rgb\n                superimposed_img = np.clip(superimposed_img, 0, 1)\n                \n                plt.figure(figsize=(12, 5))\n                plt.subplot(1, 2, 1)\n                plt.imshow(rgb)\n                plt.title(f\"({captured_error_count}/{TARGET_ERROR_COUNT}) ORIGINAL CT\")\n                plt.axis('off')\n\n                plt.subplot(1, 2, 2)\n                plt.imshow(superimposed_img)\n                plt.title(\"AI FOCUS MAP (GRAD-CAM)\")\n                plt.axis('off')\n\n                # İsimleri Calc_Search olarak değiştirdik\n                save_path = f\"/kaggle/working/Calc_Search_{captured_error_count}_{patient_id}.png\"\n                plt.savefig(save_path, bbox_inches=\"tight\", dpi=150)\n                plt.close() \n                print(f\"🚨 False Positive #{captured_error_count} -> Saved to Output folder ({patient_id})\")\n                \n        except Exception as e:\n            pass\n\nprint(\"\\n✅ Search Complete! 50 Images saved. Please check Output folder to hunt for Calcification Errors.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T12:02:37.526394Z","iopub.execute_input":"2026-04-25T12:02:37.526894Z","iopub.status.idle":"2026-04-25T12:03:40.356163Z","shell.execute_reply.started":"2026-04-25T12:02:37.526862Z","shell.execute_reply":"2026-04-25T12:03:40.355342Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport random\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\n\nprint(\"⚕️ KLİNİK PERFORMANS RAPORU (Confusion Matrix) HAZIRLANIYOR...\")\nprint(\"Modelin hiç görmediği hastalar üzerindeki başarısı test ediliyor (Yaklaşık 1-2 dakika sürebilir)...\\n\")\n\n# Görülmemiş hastalardan dengeli bir test grubu seçelim\ntest_hastalar = tam_hasta_listesi[2000:]\n\nkanamali_havuz_test = hasta_matrisi.loc[test_hastalar]\nkanamali_havuz_test = kanamali_havuz_test[kanamali_havuz_test['any'] == 1].index.tolist()\n\nsaglam_havuz_test = hasta_matrisi.loc[test_hastalar]\nsaglam_havuz_test = saglam_havuz_test[saglam_havuz_test['any'] == 0].index.tolist()\n\n# Test için 100'er tane alalım (Hızlı sonuç görmek için)\ntest_kanamalilar = random.sample(kanamali_havuz_test, 100)\ntest_saglamlar = random.sample(saglam_havuz_test, 100)\n\ntest_grubu = test_kanamalilar + test_saglamlar\nrandom.shuffle(test_grubu)\n\ngercek_degerler = []\ntahmin_edilenler = []\n\n# Hastaları sırayla asistanın önüne (predict) gönderiyoruz\nfor i, hasta_id in enumerate(test_grubu):\n    gercek_tani = hasta_matrisi.loc[hasta_id]['any']\n    \n    hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n    \n    try:\n        dataset = pydicom.dcmread(hedef_dosya)\n        fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                  dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n        \n        def get_first_local(x):\n            if type(x) == pydicom.multival.MultiValue: return int(x[0])\n            return int(x)\n\n        _, _, inter, slope = [get_first_local(x) for x in fields]\n\n        img = dataset.pixel_array.astype(float)\n        red = window_image(img.copy(), 40, 80, inter, slope)\n        green = window_image(img.copy(), 80, 200, inter, slope)\n        blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n        rgb = np.zeros((img.shape[0], img.shape[1], 3))\n        rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n        rgb_resized = cv2.resize(rgb, (256, 256))\n        img_array = np.expand_dims(rgb_resized, axis=0)\n        \n        # Sadece \"any\" (herhangi bir kanama var mı?) sonucuna bakıyoruz\n        prediction = bizim_model.predict(img_array, verbose=0)[0][0]\n        \n        # Yapay zeka %50'den fazla şüpheliyse kanama var (1), altındaysa yok (0) diyelim\n        tahmin_sinifi = 1 if prediction > 0.50 else 0\n        \n        tahmin_edilenler.append(tahmin_sinifi)\n        gercek_degerler.append(gercek_tani)\n        \n    except Exception as e:\n        continue\n\n# Karmaşıklık Matrisi (Confusion Matrix) Hesaplama\ncm = confusion_matrix(gercek_degerler, tahmin_edilenler)\n\n# cm matrisi 4 parçadan oluşur:\n# TN (True Negative), FP (False Positive)\n# FN (False Negative), TP (True Positive)\nTN, FP, FN, TP = cm.ravel()\n\n# Görsel Çizdirme\nplt.figure(figsize=(7, 5))\nsns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", cbar=False,\n            xticklabels=['Sağlıklı Dedi', 'Kanama Dedi'],\n            yticklabels=['Gerçekte Sağlıklı', 'Gerçekte Kanama'],\n            annot_kws={\"size\": 16})\nplt.title(\"Asistanın Klinik Karar Matrisi\", fontsize=14)\nplt.show()\n\n# Başhekim İçin Sözlü Rapor\nprint(\"\\n\" + \"=\"*60)\nprint(\" 🩺 BAŞHEKİM İÇİN ASİSTAN PERFORMANS RAPORU \")\nprint(\"=\"*60)\nprint(f\"Toplam İncelenen Hasta Sayısı: {TN + FP + FN + TP}\")\nprint(f\"Gerçekte KANAMASI OLAN Hastalar: {TP + FN}\")\nprint(f\"Gerçekte SAĞLIKLI OLAN Hastalar: {TN + FP}\\n\")\n\nprint(f\"✅ DOĞRU YAKALANANLAR (True Positive): {TP}\")\nprint(f\"   (Radyoloğun kanama dediği ve asistanın da bulduğu hastalar)\\n\")\n\nprint(f\"❌ KAÇIRILANLAR / ÖLÜMCÜL HATA (False Negative): {FN}\")\nprint(f\"   (Radyoloğun kanama dediği ama asistanın 'Sağlıklı' deyip eve gönderdiği hastalar!)\\n\")\n\nprint(f\"⚠️ YALANCI ALARMLAR (False Positive): {FP}\")\nprint(f\"   (Sağlıklı olduğu halde asistanın kafatasını veya kalsifikasyonu kanama sandığı hastalar)\\n\")\n\nprint(f\"✅ DOĞRU TABURCULAR (True Negative): {TN}\")\nprint(f\"   (Gerçekte sağlıklı olan ve asistanın da doğru şekilde eve gönderdiği hastalar)\\n\")\n\nhassasiyet = (TP / (TP + FN)) * 100 if (TP + FN) > 0 else 0\nprint(f\"📊 KLİNİK HASSASİYET (Sensitivity/Recall): %{hassasiyet:.1f}\")\nprint(f\"   ÖZET: Asistan, önüne gelen kanama vakalarının %{hassasiyet:.1f}'ini doğru yakalayabildi.\")\nprint(f\"   Geriye kalan %{100-hassasiyet:.1f}'lik kısmı ise gözden kaçırdı.\")\nprint(\"=\"*60)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T12:14:02.615354Z","iopub.execute_input":"2026-04-25T12:14:02.61626Z","iopub.status.idle":"2026-04-25T12:14:29.740876Z","shell.execute_reply.started":"2026-04-25T12:14:02.616224Z","shell.execute_reply":"2026-04-25T12:14:29.739959Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.optimizers import Adam\nimport random\n\nprint(\"💉 YAPAY ZEKA YOĞUN BAKIMA ALINIYOR (Kısa & Etkili Model İyileştirme)...\")\n\n# 1. HARD NEGATIVE MINING (Kafatasını kanama sanan o hatalı hastaları bulup eğitime zorla ekleyelim)\n# Not: 'test_grubu' ve 'tahmin_edilenler' önceki hücreden geliyor.\nzorlu_hastalar = [test_grubu[i] for i in range(len(test_grubu)) \n                  if tahmin_edilenler[i] == 1 and gercek_degerler[i] == 0]\n\nprint(f\"📌 Tespit edilen {len(zorlu_hastalar)} adet 'Zorlu Negatif' (False Positive) vakası eğitim listesine özel olarak sabitlendi!\")\n\n# 2. SINIF DENGELEME (Class Balancing - Hileyi Bozma)\nkanamali_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 1].index.tolist()\nsaglikli_havuz_tam = hasta_matrisi[hasta_matrisi['any'] == 0].index.tolist()\n\n# 600 Kanamalı, 600 Sağlıklı alıyoruz (Hızlı olması için sayıyı düşük tuttuk)\n# Sağlıklıların içine \"zorlu hastaları\" garanti olarak ekliyoruz.\nsecilen_sagliklilar = zorlu_hastalar + random.sample(saglikli_havuz_tam, 600 - len(zorlu_hastalar))\nsecilen_kanamalilar = random.sample(kanamali_havuz_tam, 600)\n\ndengeli_hastalar = secilen_sagliklilar + secilen_kanamalilar\nrandom.shuffle(dengeli_hastalar)\n\n# Veri bantımızı güncelliyoruz\ndengeli_egitim_bandi = RSNADataset(dengeli_hastalar, hasta_matrisi, batch_size=32)\nprint(\"⚖️ Veri seti %50 - %50 eşitlendi ve modelin kafatası ezberi kırıldı.\")\n\n# 3. YENİ BEYİN İNŞASI (Yüksek Unutma Oranı ve Düşük Öğrenme Hızı)\nx = temel_beyin.output\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\n# %50 Unutma oranı ekliyoruz! (Kafatasını ezberlemekten vazgeçmesi için)\nx = tf.keras.layers.Dropout(0.5)(x) \nkesin_tanilar = tf.keras.layers.Dense(6, activation='sigmoid')(x)\n\ngelismis_model = tf.keras.models.Model(inputs=temel_beyin.input, outputs=kesin_tanilar)\n\n# Çok düşük bir hızla (Learning Rate = 0.0001) detaylı ince ayar yapıyoruz\ngelismis_model.compile(optimizer=Adam(learning_rate=0.0001), \n                       loss='binary_crossentropy', \n                       metrics=['accuracy'])\n\nprint(\"\\n🚀 Hızlı ve Güçlendirilmiş Eğitim Başlıyor...\")\n# Kaggle'da saatler sürmesin diye sadece 2 Tur (Epoch) eğitiyoruz (Yaklaşık 3-4 dakika sürer)\nhistory = gelismis_model.fit(\n    dengeli_egitim_bandi,\n    epochs=2,\n    verbose=1\n)\n\n# Eğitilen güçlü asistanı ana modele eşitleyelim\nbizim_model = gelismis_model\nprint(\"\\n✅ TEDAVİ TAMAMLANDI! Asistan artık kafatasını kanama sanmamayı öğrendi.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T12:24:27.425251Z","iopub.execute_input":"2026-04-25T12:24:27.42638Z","iopub.status.idle":"2026-04-25T12:26:01.667721Z","shell.execute_reply.started":"2026-04-25T12:24:27.426349Z","shell.execute_reply":"2026-04-25T12:26:01.666885Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport cv2\nimport pydicom\nimport random\n\nprint(\"🎯 YENİ MODELİN ODAK TESTİ (Kafatasından vazgeçti mi?)\")\n\n# Gerçekten KANAMASI OLAN rastgele bir hasta seçelim\nkanamali_hasta_id = random.choice(test_kanamalilar)\nhedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{kanamali_hasta_id}.dcm\"\n\n# Görüntüyü hazırlayalım (Önceki pencerelerimizi uygulayalım)\ndataset = pydicom.dcmread(hedef_dosya)\nfields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n          dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n\n# Eğer get_first_local hafızadan silindiyse diye tekrar tanımlıyoruz\ndef get_first_local(x):\n    if type(x) == pydicom.multival.MultiValue: return int(x[0])\n    return int(x)\n\n_, _, inter, slope = [get_first_local(x) for x in fields]\n\nimg = dataset.pixel_array.astype(float)\nred = window_image(img.copy(), 40, 80, inter, slope)\ngreen = window_image(img.copy(), 80, 200, inter, slope)\nblue = window_image(img.copy(), 600, 2800, inter, slope)\n\nrgb = np.zeros((img.shape[0], img.shape[1], 3))\nrgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\nrgb_resized = cv2.resize(rgb, (256, 256))\nimg_array = np.expand_dims(rgb_resized, axis=0)\n\n# Yeni (tedavi görmüş) asistanımızın tahminini alalım\nprediction = bizim_model.predict(img_array, verbose=0)[0][0]\ntahmin_yuzdesi = prediction * 100\n\n# Isı haritasını çıkaralım \nson_gorsel_katman_adi = \"top_activation\"\nheatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n\n# Haritayı boyutlandırıp ana resmin üstüne bindirelim\nheatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\nheatmap_resized = np.uint8(255 * heatmap_resized)\njet = plt.colormaps.get_cmap(\"jet\")\njet_colors = jet(np.arange(256))[:, :3]\njet_heatmap = jet_colors[heatmap_resized]\n\nsuperimposed_img = jet_heatmap * 0.4 + rgb\nsuperimposed_img = np.clip(superimposed_img, 0, 1)\n\n# Ekrana çizelim\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nplt.imshow(rgb)\nplt.title(f\"A) GERÇEK KANAMA VAKASI ({kanamali_hasta_id[-9:]})\")\nplt.axis('off')\n\nplt.subplot(1, 2, 2)\nplt.imshow(superimposed_img)\nplt.title(f\"B) YENİ MODELİN ODAĞI (Kanama Şüphesi: %{tahmin_yuzdesi:.1f})\")\nplt.axis('off')\n\nplt.tight_layout()\nplt.show()\n\nprint(\"\\n💡 BAŞHEKİMİN DİKKATİNE: Kırmızı alan (odak noktası) artık kafatasının sınırlarından kurtulup beynin içine girmeyi başardı mı?\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:04:15.359125Z","iopub.execute_input":"2026-04-25T13:04:15.359869Z","iopub.status.idle":"2026-04-25T13:04:16.397147Z","shell.execute_reply.started":"2026-04-25T13:04:15.359836Z","shell.execute_reply":"2026-04-25T13:04:16.396451Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\nimport tensorflow as tf\n\nprint(\"🧠 DERİN İNCE AYAR (DEEP FINE-TUNING) BAŞLIYOR...\")\nprint(\"Asistanın görsel korteksindeki kilitler açılıyor!\")\n\n# 1. Temel Beynin Kilidini Açıyoruz\ntemel_beyin.trainable = True\n\n# 2. Tamamen unutkanlık yaşamaması için ilk katmanları kilitli bırakıp,\n# sadece son 30 katmanın (en detaylı gören kısımların) kilidini açıyoruz.\nfor layer in temel_beyin.layers[:-30]:\n    layer.trainable = False\n\nfor layer in temel_beyin.layers[-30:]:\n    layer.trainable = True\n\nprint(f\"🔓 Beynin son 30 sinir ağı katmanı tıbbi dokuları öğrenmek için serbest bırakıldı!\")\n\n# 3. Modeli ÇOK DÜŞÜK bir öğrenme hızıyla derliyoruz (Öğrendiklerini unutmaması için)\n# Normalde 1e-3 veya 1e-4 kullanıyorduk. Şimdi 1e-5 (0.00001) kullanacağız.\nbizim_model.compile(optimizer=Adam(learning_rate=1e-5), \n                    loss='binary_crossentropy', \n                    metrics=['accuracy'])\n\nprint(\"\\n🚀 UZMANLIK EĞİTİMİ BAŞLIYOR (Bu işlem modelin milimetrik kanamaları görmesini sağlayacak)...\")\n\n# Daha derin öğrendiği için biraz daha fazla tur (5 Epoch) veriyoruz\nhistory_finetune = bizim_model.fit(\n    dengeli_egitim_bandi,\n    epochs=5,\n    verbose=1\n)\n\nprint(\"\\n🏆 UZMANLIK EĞİTİMİ TAMAMLANDI! Asistan artık kanın dokusunu hücresel düzeyde tanıyabiliyor.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:07:41.021198Z","iopub.execute_input":"2026-04-25T13:07:41.021984Z","iopub.status.idle":"2026-04-25T13:09:33.038117Z","shell.execute_reply.started":"2026-04-25T13:07:41.021954Z","shell.execute_reply":"2026-04-25T13:09:33.037476Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport random\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\n\nprint(\"⚕️ KLİNİK PERFORMANS RAPORU (Confusion Matrix) HAZIRLANIYOR...\")\nprint(\"Modelin hiç görmediği hastalar üzerindeki başarısı test ediliyor (Yaklaşık 1-2 dakika sürebilir)...\\n\")\n\n# Görülmemiş hastalardan dengeli bir test grubu seçelim\ntest_hastalar = tam_hasta_listesi[2000:]\n\nkanamali_havuz_test = hasta_matrisi.loc[test_hastalar]\nkanamali_havuz_test = kanamali_havuz_test[kanamali_havuz_test['any'] == 1].index.tolist()\n\nsaglam_havuz_test = hasta_matrisi.loc[test_hastalar]\nsaglam_havuz_test = saglam_havuz_test[saglam_havuz_test['any'] == 0].index.tolist()\n\n# Test için 100'er tane alalım (Hızlı sonuç görmek için)\ntest_kanamalilar = random.sample(kanamali_havuz_test, 100)\ntest_saglamlar = random.sample(saglam_havuz_test, 100)\n\ntest_grubu = test_kanamalilar + test_saglamlar\nrandom.shuffle(test_grubu)\n\ngercek_degerler = []\ntahmin_edilenler = []\n\n# Hastaları sırayla asistanın önüne (predict) gönderiyoruz\nfor i, hasta_id in enumerate(test_grubu):\n    gercek_tani = hasta_matrisi.loc[hasta_id]['any']\n    \n    hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n    \n    try:\n        dataset = pydicom.dcmread(hedef_dosya)\n        fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                  dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n        \n        def get_first_local(x):\n            if type(x) == pydicom.multival.MultiValue: return int(x[0])\n            return int(x)\n\n        _, _, inter, slope = [get_first_local(x) for x in fields]\n\n        img = dataset.pixel_array.astype(float)\n        red = window_image(img.copy(), 40, 80, inter, slope)\n        green = window_image(img.copy(), 80, 200, inter, slope)\n        blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n        rgb = np.zeros((img.shape[0], img.shape[1], 3))\n        rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n        rgb_resized = cv2.resize(rgb, (256, 256))\n        img_array = np.expand_dims(rgb_resized, axis=0)\n        \n        # Sadece \"any\" (herhangi bir kanama var mı?) sonucuna bakıyoruz\n        prediction = bizim_model.predict(img_array, verbose=0)[0][0]\n        \n        # Yapay zeka %50'den fazla şüpheliyse kanama var (1), altındaysa yok (0) diyelim\n        tahmin_sinifi = 1 if prediction > 0.50 else 0\n        \n        tahmin_edilenler.append(tahmin_sinifi)\n        gercek_degerler.append(gercek_tani)\n        \n    except Exception as e:\n        continue\n\n# Karmaşıklık Matrisi (Confusion Matrix) Hesaplama\ncm = confusion_matrix(gercek_degerler, tahmin_edilenler)\n\n# cm matrisi 4 parçadan oluşur:\n# TN (True Negative), FP (False Positive)\n# FN (False Negative), TP (True Positive)\nTN, FP, FN, TP = cm.ravel()\n\n# Görsel Çizdirme\nplt.figure(figsize=(7, 5))\nsns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", cbar=False,\n            xticklabels=['Sağlıklı Dedi', 'Kanama Dedi'],\n            yticklabels=['Gerçekte Sağlıklı', 'Gerçekte Kanama'],\n            annot_kws={\"size\": 16})\nplt.title(\"Asistanın Klinik Karar Matrisi\", fontsize=14)\nplt.show()\n\n# Başhekim İçin Sözlü Rapor\nprint(\"\\n\" + \"=\"*60)\nprint(\" 🩺 BAŞHEKİM İÇİN ASİSTAN PERFORMANS RAPORU \")\nprint(\"=\"*60)\nprint(f\"Toplam İncelenen Hasta Sayısı: {TN + FP + FN + TP}\")\nprint(f\"Gerçekte KANAMASI OLAN Hastalar: {TP + FN}\")\nprint(f\"Gerçekte SAĞLIKLI OLAN Hastalar: {TN + FP}\\n\")\n\nprint(f\"✅ DOĞRU YAKALANANLAR (True Positive): {TP}\")\nprint(f\"   (Radyoloğun kanama dediği ve asistanın da bulduğu hastalar)\\n\")\n\nprint(f\"❌ KAÇIRILANLAR / ÖLÜMCÜL HATA (False Negative): {FN}\")\nprint(f\"   (Radyoloğun kanama dediği ama asistanın 'Sağlıklı' deyip eve gönderdiği hastalar!)\\n\")\n\nprint(f\"⚠️ YALANCI ALARMLAR (False Positive): {FP}\")\nprint(f\"   (Sağlıklı olduğu halde asistanın kafatasını veya kalsifikasyonu kanama sandığı hastalar)\\n\")\n\nprint(f\"✅ DOĞRU TABURCULAR (True Negative): {TN}\")\nprint(f\"   (Gerçekte sağlıklı olan ve asistanın da doğru şekilde eve gönderdiği hastalar)\\n\")\n\nhassasiyet = (TP / (TP + FN)) * 100 if (TP + FN) > 0 else 0\nprint(f\"📊 KLİNİK HASSASİYET (Sensitivity/Recall): %{hassasiyet:.1f}\")\nprint(f\"   ÖZET: Asistan, önüne gelen kanama vakalarının %{hassasiyet:.1f}'ini doğru yakalayabildi.\")\nprint(f\"   Geriye kalan %{100-hassasiyet:.1f}'lik kısmı ise gözden kaçırdı.\")\nprint(\"=\"*60)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:20:16.489577Z","iopub.execute_input":"2026-04-25T13:20:16.489934Z","iopub.status.idle":"2026-04-25T13:20:48.69108Z","shell.execute_reply.started":"2026-04-25T13:20:16.489908Z","shell.execute_reply":"2026-04-25T13:20:48.690458Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\nprint(\"⚖️ BAŞHEKİMİN 'DROPOUT' MÜDAHALESİ BAŞLIYOR...\")\nprint(\"İlacın dozu düşürülüyor: Asistanın unutkanlık seviyesi %50'den %20'ye çekiliyor!\")\n\n# Temel beynin üzerine yeni bir karar lobu ekliyoruz\nx = temel_beyin.output\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\n\n# İŞTE SENİN DOKUNUŞUN: Dropout'u 0.5'ten 0.2'ye düşürdük!\nx = tf.keras.layers.Dropout(0.2)(x) \nkesin_tanilar = tf.keras.layers.Dense(6, activation='sigmoid')(x)\n\ndengeli_model = tf.keras.models.Model(inputs=temel_beyin.input, outputs=kesin_tanilar)\n\ndengeli_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), \n                      loss='binary_crossentropy', \n                      metrics=['accuracy'])\n\nprint(\"🚀 Daha düşük Dropout (%20) ile dengeli eğitim başlıyor...\")\n\n# Öğrenmesi için 3 Tur (Epoch) zaman veriyoruz\nhistory_yeni = dengeli_model.fit(\n    dengeli_egitim_bandi,\n    epochs=3,\n    verbose=1\n)\n\n# Ana modeli güncelliyoruz\nbizim_model = dengeli_model\nprint(\"\\n✅ MÜDAHALE BİTTİ! Asistanın özgüveni yerine geldi.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:26:24.723207Z","iopub.execute_input":"2026-04-25T13:26:24.724086Z","iopub.status.idle":"2026-04-25T13:27:48.150581Z","shell.execute_reply.started":"2026-04-25T13:26:24.724051Z","shell.execute_reply":"2026-04-25T13:27:48.149937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport random\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\n\nprint(\"⚕️ KLİNİK PERFORMANS RAPORU (Confusion Matrix) HAZIRLANIYOR...\")\nprint(\"Modelin hiç görmediği hastalar üzerindeki başarısı test ediliyor (Yaklaşık 1-2 dakika sürebilir)...\\n\")\n\n# Görülmemiş hastalardan dengeli bir test grubu seçelim\ntest_hastalar = tam_hasta_listesi[2000:]\n\nkanamali_havuz_test = hasta_matrisi.loc[test_hastalar]\nkanamali_havuz_test = kanamali_havuz_test[kanamali_havuz_test['any'] == 1].index.tolist()\n\nsaglam_havuz_test = hasta_matrisi.loc[test_hastalar]\nsaglam_havuz_test = saglam_havuz_test[saglam_havuz_test['any'] == 0].index.tolist()\n\n# Test için 100'er tane alalım (Hızlı sonuç görmek için)\ntest_kanamalilar = random.sample(kanamali_havuz_test, 100)\ntest_saglamlar = random.sample(saglam_havuz_test, 100)\n\ntest_grubu = test_kanamalilar + test_saglamlar\nrandom.shuffle(test_grubu)\n\ngercek_degerler = []\ntahmin_edilenler = []\n\n# Hastaları sırayla asistanın önüne (predict) gönderiyoruz\nfor i, hasta_id in enumerate(test_grubu):\n    gercek_tani = hasta_matrisi.loc[hasta_id]['any']\n    \n    hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n    \n    try:\n        dataset = pydicom.dcmread(hedef_dosya)\n        fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                  dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n        \n        def get_first_local(x):\n            if type(x) == pydicom.multival.MultiValue: return int(x[0])\n            return int(x)\n\n        _, _, inter, slope = [get_first_local(x) for x in fields]\n\n        img = dataset.pixel_array.astype(float)\n        red = window_image(img.copy(), 40, 80, inter, slope)\n        green = window_image(img.copy(), 80, 200, inter, slope)\n        blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n        rgb = np.zeros((img.shape[0], img.shape[1], 3))\n        rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n\n        rgb_resized = cv2.resize(rgb, (256, 256))\n        img_array = np.expand_dims(rgb_resized, axis=0)\n        \n        # Sadece \"any\" (herhangi bir kanama var mı?) sonucuna bakıyoruz\n        prediction = bizim_model.predict(img_array, verbose=0)[0][0]\n        \n        # Yapay zeka %50'den fazla şüpheliyse kanama var (1), altındaysa yok (0) diyelim\n        tahmin_sinifi = 1 if prediction > 0.50 else 0\n        \n        tahmin_edilenler.append(tahmin_sinifi)\n        gercek_degerler.append(gercek_tani)\n        \n    except Exception as e:\n        continue\n\n# Karmaşıklık Matrisi (Confusion Matrix) Hesaplama\ncm = confusion_matrix(gercek_degerler, tahmin_edilenler)\n\n# cm matrisi 4 parçadan oluşur:\n# TN (True Negative), FP (False Positive)\n# FN (False Negative), TP (True Positive)\nTN, FP, FN, TP = cm.ravel()\n\n# Görsel Çizdirme\nplt.figure(figsize=(7, 5))\nsns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", cbar=False,\n            xticklabels=['Sağlıklı Dedi', 'Kanama Dedi'],\n            yticklabels=['Gerçekte Sağlıklı', 'Gerçekte Kanama'],\n            annot_kws={\"size\": 16})\nplt.title(\"Asistanın Klinik Karar Matrisi\", fontsize=14)\nplt.show()\n\n# Başhekim İçin Sözlü Rapor\nprint(\"\\n\" + \"=\"*60)\nprint(\" 🩺 BAŞHEKİM İÇİN ASİSTAN PERFORMANS RAPORU \")\nprint(\"=\"*60)\nprint(f\"Toplam İncelenen Hasta Sayısı: {TN + FP + FN + TP}\")\nprint(f\"Gerçekte KANAMASI OLAN Hastalar: {TP + FN}\")\nprint(f\"Gerçekte SAĞLIKLI OLAN Hastalar: {TN + FP}\\n\")\n\nprint(f\"✅ DOĞRU YAKALANANLAR (True Positive): {TP}\")\nprint(f\"   (Radyoloğun kanama dediği ve asistanın da bulduğu hastalar)\\n\")\n\nprint(f\"❌ KAÇIRILANLAR / ÖLÜMCÜL HATA (False Negative): {FN}\")\nprint(f\"   (Radyoloğun kanama dediği ama asistanın 'Sağlıklı' deyip eve gönderdiği hastalar!)\\n\")\n\nprint(f\"⚠️ YALANCI ALARMLAR (False Positive): {FP}\")\nprint(f\"   (Sağlıklı olduğu halde asistanın kafatasını veya kalsifikasyonu kanama sandığı hastalar)\\n\")\n\nprint(f\"✅ DOĞRU TABURCULAR (True Negative): {TN}\")\nprint(f\"   (Gerçekte sağlıklı olan ve asistanın da doğru şekilde eve gönderdiği hastalar)\\n\")\n\nhassasiyet = (TP / (TP + FN)) * 100 if (TP + FN) > 0 else 0\nprint(f\"📊 KLİNİK HASSASİYET (Sensitivity/Recall): %{hassasiyet:.1f}\")\nprint(f\"   ÖZET: Asistan, önüne gelen kanama vakalarının %{hassasiyet:.1f}'ini doğru yakalayabildi.\")\nprint(f\"   Geriye kalan %{100-hassasiyet:.1f}'lik kısmı ise gözden kaçırdı.\")\nprint(\"=\"*60)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:32:31.690905Z","iopub.execute_input":"2026-04-25T13:32:31.691743Z","iopub.status.idle":"2026-04-25T13:33:03.960248Z","shell.execute_reply.started":"2026-04-25T13:32:31.691712Z","shell.execute_reply":"2026-04-25T13:33:03.95958Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport matplotlib.pyplot as plt\n\nprint(\"📸 VAKA DOSYALARI ÇIKARTILIYOR (TP, TN, FP, FN)...\")\nprint(\"Toplam 40 hastanın ısı haritası çiziliyor. Bu işlem birkaç dakika sürebilir, lütfen bekleyin...\\n\")\n\n# Hastaları 4 ayrı listeye ayırıyoruz\ntp_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 1 and tahmin_edilenler[i] == 1]\ntn_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 0 and tahmin_edilenler[i] == 0]\nfp_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 0 and tahmin_edilenler[i] == 1]\nfn_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 1 and tahmin_edilenler[i] == 0]\n\nkategoriler = {\n    \"✅ TRUE POSITIVE (Kanama Vardı, Asistan Doğru Bildi)\": tp_list[:10],\n    \"❌ FALSE NEGATIVE (Kanama Vardı, Asistan Gözden Kaçırdı - ÖLÜMCÜL HATA)\": fn_list[:10],\n    \"⚠️ FALSE POSITIVE (Sağlıklıydı, Asistan Kanaması Var Sandı)\": fp_list[:10],\n    \"✅ TRUE NEGATIVE (Sağlıklıydı, Asistan Sağlıklı Dedi)\": tn_list[:10]\n}\n\nson_gorsel_katman_adi = \"top_activation\"\n\n# Her bir kategori için 10'lu (2x5) tablo çizdirme\nfor kat_adi, hastalar in kategoriler.items():\n    print(f\"\\n{'='*70}\\n{kat_adi} - ({len(hastalar)} Hasta Gösteriliyor)\\n{'='*70}\")\n    \n    if len(hastalar) == 0:\n        print(\"Bu kategoride hiç hasta yok.\")\n        continue\n        \n    fig, axes = plt.subplots(2, 5, figsize=(25, 10))\n    axes = axes.flatten()\n    \n    for idx, hasta_id in enumerate(hastalar):\n        ax = axes[idx]\n        hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n        \n        try:\n            dataset = pydicom.dcmread(hedef_dosya)\n            fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                      dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n            \n            # Eğer fonksiyon hafızada yoksa diye içerde lokal tanımlıyoruz\n            def get_first_local(x):\n                if type(x) == pydicom.multival.MultiValue: return int(x[0])\n                return int(x)\n\n            _, _, inter, slope = [get_first_local(x) for x in fields]\n\n            img = dataset.pixel_array.astype(float)\n            red = window_image(img.copy(), 40, 80, inter, slope)\n            green = window_image(img.copy(), 80, 200, inter, slope)\n            blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n            rgb = np.zeros((img.shape[0], img.shape[1], 3))\n            rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n            rgb_resized = cv2.resize(rgb, (256, 256))\n            img_array = np.expand_dims(rgb_resized, axis=0)\n\n            # Grad-CAM hesaplama\n            heatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n            heatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\n            heatmap_resized = np.uint8(255 * heatmap_resized)\n            jet = plt.colormaps.get_cmap(\"jet\")\n            jet_colors = jet(np.arange(256))[:, :3]\n            jet_heatmap = jet_colors[heatmap_resized]\n\n            superimposed_img = np.clip(jet_heatmap * 0.4 + rgb, 0, 1)\n            \n            # Subplot'a yerleştirme\n            ax.imshow(superimposed_img)\n            ax.set_title(f\"Hasta: {hasta_id[-8:]}\", fontsize=12)\n            ax.axis('off')\n        except Exception as e:\n            ax.set_title(\"Okuma Hatası\")\n            ax.axis('off')\n            \n    # Eğer o kategoride 10'dan az hasta varsa (Örn: Sadece 6 hata yaptıysa) boş kutuları gizle\n    for i in range(len(hastalar), 10):\n        axes[i].axis('off')\n        \n    plt.tight_layout()\n    plt.show()\n\nprint(\"\\n✅ TÜM HARİTALAR ÇİZİLDİ! Artık asistanın hangi hataları neden yaptığını (Örn: False Negative'lerde nereye bakıp yanıldığını) tek tek görsel olarak analiz edebilirsin.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:40:12.595636Z","iopub.execute_input":"2026-04-25T13:40:12.596496Z","iopub.status.idle":"2026-04-25T13:40:42.917161Z","shell.execute_reply.started":"2026-04-25T13:40:12.596463Z","shell.execute_reply":"2026-04-25T13:40:42.916257Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport matplotlib.pyplot as plt\n\nprint(\"📸 VAKA DOSYALARI ÇIKARTILIYOR (Orijinal vs Isı Haritası)...\")\nprint(\"Lütfen bekleyin, röntgenler yan yana diziliyor...\\n\")\n\n# Hastaları 4 ayrı listeye ayırıyoruz\ntp_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 1 and tahmin_edilenler[i] == 1]\ntn_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 0 and tahmin_edilenler[i] == 0]\nfp_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 0 and tahmin_edilenler[i] == 1]\nfn_list = [test_grubu[i] for i in range(len(test_grubu)) if gercek_degerler[i] == 1 and tahmin_edilenler[i] == 0]\n\nkategoriler = {\n    \"✅ TRUE POSITIVE (Kanama Vardı, Asistan Doğru Bildi)\": tp_list[:10],\n    \"❌ FALSE NEGATIVE (Kanama Vardı, Asistan Kaçırdı - ÖLÜMCÜL HATA)\": fn_list[:10],\n    \"⚠️ FALSE POSITIVE (Sağlıklıydı, Asistan Kanama Sandı)\": fp_list[:10],\n    \"✅ TRUE NEGATIVE (Sağlıklıydı, Asistan Sağlıklı Dedi)\": tn_list[:10]\n}\n\nson_gorsel_katman_adi = \"top_activation\"\n\nfor kat_adi, hastalar in kategoriler.items():\n    print(f\"\\n{'='*80}\\n{kat_adi} - ({len(hastalar)} Hasta)\\n{'='*80}\")\n    \n    if len(hastalar) == 0:\n        print(\"Bu kategoride hasta yok.\")\n        continue\n        \n    # Her satıra 2 hasta (Yani 4 resim: Orijinal-Heatmap | Orijinal-Heatmap) sığacak şekilde ayarlıyoruz\n    satir_sayisi = int(np.ceil(len(hastalar) / 2))\n    fig, axes = plt.subplots(satir_sayisi, 4, figsize=(20, 5 * satir_sayisi))\n    \n    # Eksenleri düzleştirip (flatten) tek boyutlu listeye çeviriyoruz ki kolay erişelim\n    if satir_sayisi == 1:\n        axes = np.array([axes]) if len(hastalar) == 1 else axes\n    axes = axes.flatten()\n    \n    for idx, hasta_id in enumerate(hastalar):\n        ax_orijinal = axes[idx * 2]\n        ax_heatmap = axes[idx * 2 + 1]\n        \n        hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n        \n        try:\n            dataset = pydicom.dcmread(hedef_dosya)\n            fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                      dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n            \n            def get_first_local(x):\n                if type(x) == pydicom.multival.MultiValue: return int(x[0])\n                return int(x)\n\n            _, _, inter, slope = [get_first_local(x) for x in fields]\n\n            img = dataset.pixel_array.astype(float)\n            red = window_image(img.copy(), 40, 80, inter, slope)\n            green = window_image(img.copy(), 80, 200, inter, slope)\n            blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n            rgb = np.zeros((img.shape[0], img.shape[1], 3))\n            rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n            rgb_resized = cv2.resize(rgb, (256, 256))\n            img_array = np.expand_dims(rgb_resized, axis=0)\n\n            # Grad-CAM Isı Haritası\n            heatmap = isi_haritasi_cikar(img_array, bizim_model, son_gorsel_katman_adi)\n            heatmap_resized = cv2.resize(heatmap, (rgb.shape[1], rgb.shape[0]))\n            heatmap_resized = np.uint8(255 * heatmap_resized)\n            jet = plt.colormaps.get_cmap(\"jet\")\n            jet_colors = jet(np.arange(256))[:, :3]\n            jet_heatmap = jet_colors[heatmap_resized]\n\n            superimposed_img = np.clip(jet_heatmap * 0.4 + rgb, 0, 1)\n            \n            # Orijinal Görüntüyü Sola Çiz\n            ax_orijinal.imshow(rgb)\n            ax_orijinal.set_title(f\"ORİJİNAL ({hasta_id[-8:]})\", fontsize=12, fontweight='bold')\n            ax_orijinal.axis('off')\n            \n            # Isı Haritasını Sağa Çiz\n            ax_heatmap.imshow(superimposed_img)\n            ax_heatmap.set_title(f\"YZ ODAĞI (Grad-CAM)\", fontsize=12, color='red', fontweight='bold')\n            ax_heatmap.axis('off')\n            \n        except Exception as e:\n            ax_orijinal.set_title(\"Okuma Hatası\")\n            ax_orijinal.axis('off')\n            ax_heatmap.axis('off')\n            \n    # Boş kalan kutuları (subplot) gizle\n    for i in range(len(hastalar) * 2, len(axes)):\n        axes[i].axis('off')\n        \n    plt.tight_layout()\n    plt.show()\n\nprint(\"\\n✅ TÜM KARŞILAŞTIRMALI HARİTALAR ÇİZİLDİ! Artık 'Model burada ne gördü de kanama sandı?' analizini rahatça yapabilirsin.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T13:42:46.359143Z","iopub.execute_input":"2026-04-25T13:42:46.359817Z","iopub.status.idle":"2026-04-25T13:43:19.090636Z","shell.execute_reply.started":"2026-04-25T13:42:46.359784Z","shell.execute_reply":"2026-04-25T13:43:19.089866Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport matplotlib.pyplot as plt\n\nprint(\"🔬 KLİNİK DENEY: SKULL STRIPPING (KAFATASI SOYMA) ETKİSİ BAŞLIYOR...\")\n\n# ==========================================\n# 1. SKULL STRIPPING ALGORİTMASI\n# ==========================================\ndef skull_strip(rgb_image):\n    # rgb_image: 256x256x3 (Red: Brain, Green: Subdural, Blue: Bone)\n    # Sadece beyin dokusunu (Kırmızı Kanal) kullanarak bir maske çıkaralım\n    gray = np.uint8(rgb_image[:,:,0] * 255) \n    \n    # Çok karanlık olmayan dokuları seç (Kemik ve arka planı ayır)\n    _, thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)\n    \n    # Morfolojik temizlik (Ufak parazitleri sil)\n    kernel = np.ones((5,5), np.uint8)\n    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)\n    \n    # En büyük konturu (Yani Ana Beyin Parankimini) bul\n    contours, _ = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    \n    if contours:\n        c = max(contours, key=cv2.contourArea)\n        mask = np.zeros_like(gray)\n        cv2.drawContours(mask, [c], -1, 1.0, -1) # Beynin olduğu yerleri 1 yap\n        \n        # Maskeyi 3 kanala da uygula (Kemiği sil)\n        stripped = np.zeros_like(rgb_image)\n        stripped[:,:,0] = rgb_image[:,:,0] * mask\n        stripped[:,:,1] = rgb_image[:,:,1] * mask\n        stripped[:,:,2] = rgb_image[:,:,2] * mask\n        return stripped\n    \n    return rgb_image # Eğer beyni bulamazsa orijinali döndür\n\n# ==========================================\n# 2. HASTA SEÇİMİ (KOHORT)\n# ==========================================\nhic_gorulmeyenler = tam_hasta_listesi[2000:]\ntest_df = hasta_matrisi.loc[hic_gorulmeyenler]\n\n# Sadece İntraparenkimal kanaması olan 10 hasta\nintra_havuzu = test_df[(test_df['intraparenchymal'] == 1) & \n                       (test_df['subdural'] == 0) & \n                       (test_df['epidural'] == 0)].index.tolist()\nintra_hastalar = intra_havuzu[:10]\n\n# Sadece Subdural veya Epidural kanaması olan 10 hasta\nsubdural_havuzu = test_df[((test_df['subdural'] == 1) | (test_df['epidural'] == 1)) & \n                          (test_df['intraparenchymal'] == 0)].index.tolist()\nsubdural_hastalar = subdural_havuzu[:10]\n\ndeney_grubu = {\"🧠 İntraparenkimal (Derin)\": intra_hastalar, \n               \"💀 Subdural/Epidural (Yüzeyel)\": subdural_hastalar}\n\n# ==========================================\n# 3. TEST VE KARŞILAŞTIRMA\n# ==========================================\nprint(\"Kafatası öncesi ve sonrası model tahminleri ölçülüyor...\\n\")\n\nfor grup_adi, hastalar in deney_grubu.items():\n    print(f\"[{grup_adi} KANAMALAR - 10 Hasta]\")\n    print(f\"{'HASTA ID':<15} | {'ORİJİNAL TAHMİN':<18} | {'KAFATASI SOYULUNCA':<18} | {'SONUÇ'}\")\n    print(\"-\" * 80)\n    \n    iyilesme_sayisi = 0\n    kotulesme_sayisi = 0\n    \n    for hasta_id in hastalar:\n        hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n        \n        try:\n            dataset = pydicom.dcmread(hedef_dosya)\n            fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                      dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n            \n            def get_first_local(x):\n                if type(x) == pydicom.multival.MultiValue: return int(x[0])\n                return int(x)\n\n            _, _, inter, slope = [get_first_local(x) for x in fields]\n\n            img = dataset.pixel_array.astype(float)\n            red = window_image(img.copy(), 40, 80, inter, slope)\n            green = window_image(img.copy(), 80, 200, inter, slope)\n            blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n            rgb = np.zeros((img.shape[0], img.shape[1], 3))\n            rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n            rgb_resized = cv2.resize(rgb, (256, 256))\n            \n            # 1. Orijinal Görüntü ile Tahmin\n            orijinal_array = np.expand_dims(rgb_resized, axis=0)\n            tahmin_orijinal = bizim_model.predict(orijinal_array, verbose=0)[0][0] * 100\n            \n            # 2. Skull Stripped (Soyulmuş) Görüntü ile Tahmin\n            soyulmus_rgb = skull_strip(rgb_resized)\n            soyulmus_array = np.expand_dims(soyulmus_rgb, axis=0)\n            tahmin_soyulmus = bizim_model.predict(soyulmus_array, verbose=0)[0][0] * 100\n            \n            # 3. Kıyaslama\n            fark = tahmin_soyulmus - tahmin_orijinal\n            if fark > 5.0: # %5'ten fazla artış varsa iyileşme\n                sonuc = \"📈 İyileşti (Daha emin)\"\n                iyilesme_sayisi += 1\n            elif fark < -5.0: # %5'ten fazla düşüş varsa kötüleşme\n                sonuc = \"📉 Kötüleşti (Kafası karıştı)\"\n                kotulesme_sayisi += 1\n            else:\n                sonuc = \"➖ Değişmedi\"\n                \n            print(f\"{hasta_id[-10:]:<15} | % {tahmin_orijinal:>5.1f} Emin         | % {tahmin_soyulmus:>5.1f} Emin         | {sonuc}\")\n            \n        except Exception as e:\n            continue\n            \n    print(\"-\" * 80)\n    print(f\"👉 Özet: Kemik silinince {iyilesme_sayisi} hastada tespit kolaylaştı, {kotulesme_sayisi} hastada tespit zorlaştı.\\n\")\n\nprint(\"✅ Deney Tamamlandı!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T14:09:47.531258Z","iopub.execute_input":"2026-04-25T14:09:47.531757Z","iopub.status.idle":"2026-04-25T14:09:52.713338Z","shell.execute_reply.started":"2026-04-25T14:09:47.531727Z","shell.execute_reply":"2026-04-25T14:09:52.712455Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pydicom\nimport matplotlib.pyplot as plt\n\nprint(\"🔬 BÜYÜK KLİNİK DENEY: SKULL STRIPPING (KAFATASI SOYMA) ETKİSİ BAŞLIYOR...\")\nprint(\"100 İntraparenkimal ve 100 Subdural/Epidural hasta olmak üzere toplam 200 hasta ameliyata alınıyor.\\n\")\n\n# ==========================================\n# 1. SKULL STRIPPING ALGORİTMASI\n# ==========================================\ndef skull_strip(rgb_image):\n    gray = np.uint8(rgb_image[:,:,0] * 255) \n    _, thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)\n    kernel = np.ones((5,5), np.uint8)\n    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)\n    contours, _ = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    \n    if contours:\n        c = max(contours, key=cv2.contourArea)\n        mask = np.zeros_like(gray)\n        cv2.drawContours(mask, [c], -1, 1.0, -1) \n        \n        stripped = np.zeros_like(rgb_image)\n        stripped[:,:,0] = rgb_image[:,:,0] * mask\n        stripped[:,:,1] = rgb_image[:,:,1] * mask\n        stripped[:,:,2] = rgb_image[:,:,2] * mask\n        return stripped\n    return rgb_image \n\n# ==========================================\n# 2. HASTA SEÇİMİ (100'er KOHORT)\n# ==========================================\nhic_gorulmeyenler = tam_hasta_listesi[2000:]\ntest_df = hasta_matrisi.loc[hic_gorulmeyenler]\n\n# 100 İntraparenkimal Hasta\nintra_havuzu = test_df[(test_df['intraparenchymal'] == 1) & \n                       (test_df['subdural'] == 0) & \n                       (test_df['epidural'] == 0)].index.tolist()\nintra_hastalar = intra_havuzu[:100]  # SAYIYI 100 YAPTIK!\n\n# 100 Subdural/Epidural Hasta\nsubdural_havuzu = test_df[((test_df['subdural'] == 1) | (test_df['epidural'] == 1)) & \n                          (test_df['intraparenchymal'] == 0)].index.tolist()\nsubdural_hastalar = subdural_havuzu[:100]  # SAYIYI 100 YAPTIK!\n\ndeney_grubu = {\"🧠 İntraparenkimal (Derin) Kanamalar\": intra_hastalar, \n               \"💀 Subdural/Epidural (Yüzeyel) Kanamalar\": subdural_hastalar}\n\n# ==========================================\n# 3. TEST VE KARŞILAŞTIRMA (Sessiz Mod)\n# ==========================================\nfor grup_adi, hastalar in deney_grubu.items():\n    print(f\"\\n[{grup_adi} - 100 Hasta İnceleniyor... Lütfen bekleyin]\")\n    \n    iyilesme_sayisi = 0\n    kotulesme_sayisi = 0\n    degismeme_sayisi = 0\n    hatali_dosya_sayisi = 0\n    \n    for idx, hasta_id in enumerate(hastalar):\n        # Kullanıcıya arka planda donmadığını göstermek için her 20 hastada bir bilgi verelim\n        if (idx + 1) % 20 == 0:\n            print(f\"   ... {idx + 1} hasta tamamlandı.\")\n            \n        hedef_dosya = f\"/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/{hasta_id}.dcm\"\n        \n        try:\n            dataset = pydicom.dcmread(hedef_dosya)\n            fields = [dataset[('0028','1050')].value, dataset[('0028','1051')].value,\n                      dataset[('0028','1052')].value, dataset[('0028','1053')].value]\n            \n            def get_first_local(x):\n                if type(x) == pydicom.multival.MultiValue: return int(x[0])\n                return int(x)\n\n            _, _, inter, slope = [get_first_local(x) for x in fields]\n\n            img = dataset.pixel_array.astype(float)\n            red = window_image(img.copy(), 40, 80, inter, slope)\n            green = window_image(img.copy(), 80, 200, inter, slope)\n            blue = window_image(img.copy(), 600, 2800, inter, slope)\n\n            rgb = np.zeros((img.shape[0], img.shape[1], 3))\n            rgb[:,:,0], rgb[:,:,1], rgb[:,:,2] = red, green, blue\n            rgb_resized = cv2.resize(rgb, (256, 256))\n            \n            # Orijinal Görüntü\n            orijinal_array = np.expand_dims(rgb_resized, axis=0)\n            tahmin_orijinal = bizim_model.predict(orijinal_array, verbose=0)[0][0] * 100\n            \n            # Skull Stripped Görüntü\n            soyulmus_rgb = skull_strip(rgb_resized)\n            soyulmus_array = np.expand_dims(soyulmus_rgb, axis=0)\n            tahmin_soyulmus = bizim_model.predict(soyulmus_array, verbose=0)[0][0] * 100\n            \n            # Kıyaslama (%5'ten büyük artış veya düşüşleri dikkate alıyoruz)\n            fark = tahmin_soyulmus - tahmin_orijinal\n            if fark > 5.0:\n                iyilesme_sayisi += 1\n            elif fark < -5.0:\n                kotulesme_sayisi += 1\n            else:\n                degismeme_sayisi += 1\n                \n        except Exception as e:\n            hatali_dosya_sayisi += 1\n            continue\n            \n    # Grup Raporunu Yazdır\n    gecerli_hasta = 100 - hatali_dosya_sayisi\n    print(\"-\" * 50)\n    print(f\"📊 {grup_adi} İSTATİSTİKLERİ ({gecerli_hasta} Hasta):\")\n    print(f\"📈 Kemik silinince TESPİTİ KOLAYLAŞAN (İyileşen): % {((iyilesme_sayisi/gecerli_hasta)*100):.1f} ({iyilesme_sayisi} Hasta)\")\n    print(f\"📉 Kemik silinince TESPİTİ ZORLAŞAN (Kötüleşen): % {((kotulesme_sayisi/gecerli_hasta)*100):.1f} ({kotulesme_sayisi} Hasta)\")\n    print(f\"➖ Etkilenmeyenler: % {((degismeme_sayisi/gecerli_hasta)*100):.1f} ({degismeme_sayisi} Hasta)\")\n    print(\"-\" * 50)\n\nprint(\"\\n✅ BÜYÜK DENEY TAMAMLANDI! Sonuçları inceleyebilirsiniz.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-25T14:14:24.102298Z","iopub.execute_input":"2026-04-25T14:14:24.102959Z","iopub.status.idle":"2026-04-25T14:15:03.665905Z","shell.execute_reply.started":"2026-04-25T14:14:24.102928Z","shell.execute_reply":"2026-04-25T14:15:03.664903Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}