{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Dogs vs. Cats Sınıflandırma Projesi\n\n## 1. Geliştirme Ortamı\n\nBu proje **Kaggle Notebook** ortamında geliştirilmiştir.  \n- Python 3 kullanılmıştır.  \n- Gerekli kütüphaneler (numpy, pandas, matplotlib, seaborn, tensorflow, keras, sklearn) otomatik olarak yüklü gelmektedir.  \n- Çalışma dizininde `train.zip` ve `test1.zip` dosyaları bulunmaktadır.  \n\nProje kapsamında kullanılacak veri seti **Kaggle Dogs vs. Cats** yarışmasından alınmıştır.  \n- **Eğitim seti:** 25.000 görüntü (12.500 kedi, 12.500 köpek)  \n- **Test seti:** 12.500 görüntü  \nAmaç: Görsellerden köpek mi yoksa kedi mi olduğunu tahmin eden bir **CNN tabanlı model** geliştirmek.  \n\n\n","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:27:51.123626Z","iopub.execute_input":"2025-09-26T16:27:51.124102Z","iopub.status.idle":"2025-09-26T16:27:51.131062Z","shell.execute_reply.started":"2025-09-26T16:27:51.124077Z","shell.execute_reply":"2025-09-26T16:27:51.130425Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2. Veri Önişleme – Zip Dosyalarının Açılması\n\nBu adımda:\n- `train.zip` dosyası `/kaggle/working/train/` dizinine açılmıştır.  \n- `test1.zip` dosyası `/kaggle/working/test/` dizinine açılmıştır.  \n- Klasörlerde kaç adet görüntü olduğu kontrol edilmiştir.  \n\nSonuç:  \n- Train set → 25.000 görüntü  \n- Test set → 12.500 görüntü  \n\n","metadata":{}},{"cell_type":"code","source":"import zipfile\n\n# Dosya yolları\ntrain_zip = \"/kaggle/input/dogs-vs-cats/train.zip\"\ntest_zip = \"/kaggle/input/dogs-vs-cats/test1.zip\"\n\n# Çıkarılacak klasörler\nos.makedirs(\"/kaggle/working/train\", exist_ok=True)\nos.makedirs(\"/kaggle/working/test\", exist_ok=True)\n\n# train.zip aç\nwith zipfile.ZipFile(train_zip, 'r') as zip_ref:\n    zip_ref.extractall(\"/kaggle/working/train\")\n\n# test1.zip aç\nwith zipfile.ZipFile(test_zip, 'r') as zip_ref:\n    zip_ref.extractall(\"/kaggle/working/test\")\n\nprint(\"Train klasöründeki dosya sayısı:\", len(os.listdir(\"/kaggle/working/train/train\")))\nprint(\"Test klasöründeki dosya sayısı:\", len(os.listdir(\"/kaggle/working/test/test1\")))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:23:49.240166Z","iopub.execute_input":"2025-09-26T16:23:49.240556Z","iopub.status.idle":"2025-09-26T16:24:00.780936Z","shell.execute_reply.started":"2025-09-26T16:23:49.240533Z","shell.execute_reply":"2025-09-26T16:24:00.780204Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 3. Eğitim Setinden Örnek Görsellerin Önizlemesi\nBu hücrede, `train` klasöründen birkaç kedi ve köpek resmi görselleştiriyoruz.  \nAmaç: veri setinin doğru açıldığını ve görsellerin okunabildiğini kontrol etmek.\n","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport cv2\n\ntrain_dir = \"/kaggle/working/train/train\"\nimages = os.listdir(train_dir)\n\nplt.figure(figsize=(12, 8))\n\n# İlk 6 resmi gösterelim\nfor i, img_name in enumerate(images[:6]):\n    img_path = os.path.join(train_dir, img_name)\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # BGR → RGB dönüşümü\n    plt.subplot(2, 3, i+1)\n    plt.imshow(img)\n    plt.title(img_name)\n    plt.axis(\"off\")\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:29:20.046934Z","iopub.execute_input":"2025-09-26T16:29:20.047655Z","iopub.status.idle":"2025-09-26T16:29:20.635751Z","shell.execute_reply.started":"2025-09-26T16:29:20.047633Z","shell.execute_reply":"2025-09-26T16:29:20.634971Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 4. Train – Validation Ayrımı\n\nModelin performansını değerlendirmek için eğitim seti ikiye ayrıldı:  \n- **Train set:** %80 (20.000 görüntü)  \n- **Validation set:** %20 (5.000 görüntü)  \n\nBöylece model hem öğrenme hem de doğrulama sürecinde ayrı veri görmüş olacak.  \n\nSonuç:  \n- Train – Cat: 9.997  \n- Train – Dog: 10.003  \n- Val – Cat: 2.503  \n- Val – Dog: 2.497  \n","metadata":{}},{"cell_type":"code","source":"import shutil\nimport random\n\n# Ana dizinler\nbase_train_dir = \"/kaggle/working/train/train\"\nbase_output_dir = \"/kaggle/working/data_split\"\n\n# Çıkış klasörlerini oluştur\nfor split in [\"train\", \"val\"]:\n    for category in [\"cat\", \"dog\"]:\n        os.makedirs(os.path.join(base_output_dir, split, category), exist_ok=True)\n\n# Tüm resimler\nall_images = os.listdir(base_train_dir)\nrandom.shuffle(all_images)\n\n# %80 eğitim, %20 validation\nsplit_index = int(0.8 * len(all_images))\ntrain_images = all_images[:split_index]\nval_images = all_images[split_index:]\n\n# Eğitim setini kopyala\nfor img in train_images:\n    label = \"cat\" if img.startswith(\"cat\") else \"dog\"\n    shutil.copy(os.path.join(base_train_dir, img), os.path.join(base_output_dir, \"train\", label))\n\n# Validation setini kopyala\nfor img in val_images:\n    label = \"cat\" if img.startswith(\"cat\") else \"dog\"\n    shutil.copy(os.path.join(base_train_dir, img), os.path.join(base_output_dir, \"val\", label))\n\nprint(\"Train - Cat:\", len(os.listdir(os.path.join(base_output_dir, \"train/cat\"))))\nprint(\"Train - Dog:\", len(os.listdir(os.path.join(base_output_dir, \"train/dog\"))))\nprint(\"Val - Cat:\", len(os.listdir(os.path.join(base_output_dir, \"val/cat\"))))\nprint(\"Val - Dog:\", len(os.listdir(os.path.join(base_output_dir, \"val/dog\"))))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:44:09.809335Z","iopub.execute_input":"2025-09-26T16:44:09.810016Z","iopub.status.idle":"2025-09-26T16:44:12.676572Z","shell.execute_reply.started":"2025-09-26T16:44:09.809992Z","shell.execute_reply":"2025-09-26T16:44:12.675861Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 5. Veri Görselleştirme\n\nBu adımda örnek görseller matplotlib ile çizilmiştir.  \nAmaç: Veri setini gözle incelemek, sınıfların dengeli olup olmadığını kontrol etmek.  \n\nSonuç:  \n- Sınıflar dengeli dağıtılmıştır.  \n- Görseller farklı boyutlarda ve çözünürlüklerde gelmektedir → eğitim öncesi hepsi 150x150 boyutuna yeniden boyutlandırılmıştır.  \n","metadata":{}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\n# Sınıf dağılımları\ntrain_cats = len(os.listdir(\"/kaggle/working/data_split/train/cat\"))\ntrain_dogs = len(os.listdir(\"/kaggle/working/data_split/train/dog\"))\nval_cats = len(os.listdir(\"/kaggle/working/data_split/val/cat\"))\nval_dogs = len(os.listdir(\"/kaggle/working/data_split/val/dog\"))\n\ndata = {\n    \"Dataset\": [\"Train\", \"Train\", \"Validation\", \"Validation\"],\n    \"Class\": [\"Cat\", \"Dog\", \"Cat\", \"Dog\"],\n    \"Count\": [train_cats, train_dogs, val_cats, val_dogs]\n}\n\nplt.figure(figsize=(6,4))\nsns.barplot(x=\"Dataset\", y=\"Count\", hue=\"Class\", data=data)\nplt.title(\"Kedi ve Köpek Dağılımı\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:46:31.183477Z","iopub.execute_input":"2025-09-26T16:46:31.18448Z","iopub.status.idle":"2025-09-26T16:46:31.586662Z","shell.execute_reply.started":"2025-09-26T16:46:31.184453Z","shell.execute_reply":"2025-09-26T16:46:31.585953Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 6. Data Augmentation (Veri Çoğaltma)\n\nModelin genelleme kabiliyetini artırmak için veri artırma (augmentation) uygulanmıştır:  \n- Rotation (döndürme)  \n- Horizontal Flip (ayna çevirme)  \n- Zoom (yakınlaştırma)  \n- Color Jitter (renk varyasyonu)  \n\nBöylece model farklı koşullardaki görüntülere karşı daha dayanıklı hale getirilmiştir.  \n\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Eğitim için Data Augmentation (Color Jitter eklendi)\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=30,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    brightness_range=[0.8, 1.2],   # Parlaklık (Color Jitter benzeri)\n    channel_shift_range=50.0       # Renk kanallarında kaydırma (Color Jitter)\n)\n\n# Validation için sadece rescale\nval_datagen = ImageDataGenerator(rescale=1./255)\n\n# Generator tanımları\ntrain_generator = train_datagen.flow_from_directory(\n    \"/kaggle/working/data_split/train\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode=\"binary\"\n)\n\nval_generator = val_datagen.flow_from_directory(\n    \"/kaggle/working/data_split/val\",\n    target_size=(150, 150),\n    batch_size=32,\n    class_mode=\"binary\"\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:49:45.16722Z","iopub.execute_input":"2025-09-26T16:49:45.167834Z","iopub.status.idle":"2025-09-26T16:49:45.38907Z","shell.execute_reply.started":"2025-09-26T16:49:45.167812Z","shell.execute_reply":"2025-09-26T16:49:45.388355Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 7. CNN Modelinin Tanımlanması\n\nModelimiz **Convolutional Neural Network (CNN)** tabanlıdır.  \nKullanılan katmanlar:  \n- **Conv2D:** Görsellerden öznitelik çıkarımı (filteler ile kenar, doku yakalama).  \n- **MaxPooling2D:** Görüntü boyutunu küçültme, önemli bilgiyi koruma.  \n- **Flatten:** 2D öznitelikleri tek boyuta çevirme.  \n- **Dense:** Tam bağlı katmanlar, sınıflandırma işlemi.  \n- **Dropout:** Overfitting’i azaltmak için nöronların belli oranda devre dışı bırakılması.  \n\nAktivasyon fonksiyonları:  \n- ReLU (gizli katmanlarda)  \n- Sigmoid (çıktı katmanında → ikili sınıflandırma için)  \n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\n\n# Daha hafif model\nmodel = Sequential([\n    Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n    \n    Conv2D(64, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Conv2D(128, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Flatten(),\n    Dense(128, activation='relu'),   # 512 → 128 yaptık\n    Dropout(0.5),\n    Dense(1, activation='sigmoid')   # Binary classification\n])\n\n# Derleme (compile)\nmodel.compile(\n    optimizer=\"adam\",\n    loss=\"binary_crossentropy\",\n    metrics=[\"accuracy\"]\n)\n\nmodel.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:57:56.848325Z","iopub.execute_input":"2025-09-26T16:57:56.848623Z","iopub.status.idle":"2025-09-26T16:57:56.908773Z","shell.execute_reply.started":"2025-09-26T16:57:56.8486Z","shell.execute_reply":"2025-09-26T16:57:56.908066Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 8. Modelin Eğitilmesi\n\nTanımlanan CNN modeli, **binary_crossentropy** kayıp fonksiyonu ve **Adam optimizer** ile eğitilmiştir.  \n- Epoch sayısı: 3  \n- Batch size: 32  \n- Eğitim seti: 20.000 görüntü  \n- Validation seti: 5.000 görüntü  \n\nAmaç: Train set üzerinde öğrenirken, validation set ile genelleme başarısını test etmektir.  \n\n**Eğitim sonuçları:**  \n- Epoch 1 → Accuracy: %52, Val Accuracy: %52  \n- Epoch 2 → Accuracy: %57, Val Accuracy: %66  \n- Epoch 3 → Accuracy: %61, Val Accuracy: %69  \n\nBu sonuçlar modelin her epoch’ta daha iyi öğrendiğini ve doğrulama setinde genelleme başarısının arttığını göstermektedir.\n","metadata":{}},{"cell_type":"code","source":"history = model.fit(\n    train_generator,\n    steps_per_epoch=len(train_generator),\n    epochs=3,   # hızlı test için 3 epoch\n    validation_data=val_generator,\n    validation_steps=len(val_generator)\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T16:58:34.587688Z","iopub.execute_input":"2025-09-26T16:58:34.588205Z","iopub.status.idle":"2025-09-26T17:05:44.49861Z","shell.execute_reply.started":"2025-09-26T16:58:34.58818Z","shell.execute_reply":"2025-09-26T17:05:44.497783Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Modelin Değerlendirilmesi\n\n### 9. Accuracy ve Loss Grafiklerinin Çizilmesi\nBu hücrede eğitim sırasında kaydedilen **accuracy (doğruluk)** ve **loss (hata)** değerleri görselleştirilmektedir.  \nAmaç: Modelin zamanla nasıl öğrendiğini gözlemlemek.\n\n- Eğer **Training Accuracy >> Validation Accuracy** olursa → model **overfitting** yapıyor demektir.  \n- Eğer hem Training hem Validation değerleri düşük kalıyorsa → model **underfitting** yapıyor demektir.  \n- İdeal durumda her iki eğri de birlikte yükselir ve yakın değerlerde seyreder.  \n\nGrafikler modelin öğrenme sürecini görselleştirerek, overfitting veya underfitting belirtilerini tespit etmemizi sağlar.  \n  \n\n","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(1, len(acc)+1)\n\nplt.figure(figsize=(12,5))\n\n# Accuracy grafiği\nplt.subplot(1,2,1)\nplt.plot(epochs, acc, 'bo-', label='Training acc')\nplt.plot(epochs, val_acc, 'ro-', label='Validation acc')\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\n# Loss grafiği\nplt.subplot(1,2,2)\nplt.plot(epochs, loss, 'bo-', label='Training loss')\nplt.plot(epochs, val_loss, 'ro-', label='Validation loss')\nplt.title('Training and Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:11:28.953949Z","iopub.execute_input":"2025-09-26T17:11:28.954222Z","iopub.status.idle":"2025-09-26T17:11:29.307388Z","shell.execute_reply.started":"2025-09-26T17:11:28.954205Z","shell.execute_reply":"2025-09-26T17:11:29.306449Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 9. Accuracy ve Loss Grafiklerinin Yorumu\n\nEğitim ve doğrulama grafikleri aşağıda görülmektedir:\n\n- **Accuracy (Doğruluk)**  \n  - Eğitim doğruluğu (Training Acc) epoch ilerledikçe %52 → %62 seviyelerine yükselmiştir.  \n  - Doğrulama doğruluğu (Validation Acc) daha hızlı bir artış göstermiş ve %52’den %69’a çıkmıştır.  \n  - Bu sonuç modelin **genelleme yeteneğinin arttığını** ve validation set üzerinde daha iyi performans sergilediğini göstermektedir.  \n\n- **Loss (Hata)**  \n  - Eğitim kaybı (Training Loss) düzenli bir şekilde azalmıştır.  \n  - Doğrulama kaybı (Validation Loss) da benzer şekilde azalmış, overfitting belirtileri gözlemlenmemiştir.  \n\n**Sonuç:**  \nModel 3 epoch boyunca hem eğitim hem de doğrulama setinde iyileşme göstermiştir. Validation accuracy’nin train accuracy’den yüksek olması, modelin henüz tam doygunluğa ulaşmadığını, daha fazla epoch ile daha iyi sonuçlar alınabileceğini işaret etmektedir.","metadata":{}},{"cell_type":"markdown","source":"## 10. Confusion Matrix & Classification Report\nBu hücrede:\n- Validation setinde modelin tahminlerini alıyoruz  \n- Confusion Matrix (karışıklık matrisi) çiziyoruz  \n- Classification Report ile Precision, Recall ve F1-Score değerlerini gösteriyoruz  ","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, classification_report\nimport seaborn as sns\nimport numpy as np\n\n# Validation setinden tahminler al\nval_generator.reset()\ny_pred = model.predict(val_generator, steps=len(val_generator), verbose=1)\ny_pred = (y_pred > 0.5).astype(int).ravel()\n\n# Gerçek etiketler\ny_true = val_generator.classes\n\n# Confusion matrix\ncm = confusion_matrix(y_true, y_pred)\n\nplt.figure(figsize=(5,4))\nsns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=[\"Cat\", \"Dog\"], yticklabels=[\"Cat\", \"Dog\"])\nplt.xlabel(\"Predicted\")\nplt.ylabel(\"True\")\nplt.title(\"Confusion Matrix\")\nplt.show()\n\n# Classification report\nprint(classification_report(y_true, y_pred, target_names=[\"Cat\", \"Dog\"]))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:11:50.729356Z","iopub.execute_input":"2025-09-26T17:11:50.729651Z","iopub.status.idle":"2025-09-26T17:11:58.055166Z","shell.execute_reply.started":"2025-09-26T17:11:50.729633Z","shell.execute_reply":"2025-09-26T17:11:58.054568Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 10. Confusion Matrix & Classification Report\n\nBu adımda modelin doğrulama seti üzerindeki tahmin performansı **Confusion Matrix** ve **Classification Report** ile incelenmiştir.\n\n### Confusion Matrix Sonuçları\n- **Cat (Kedi)** sınıfında doğru tahmin oranı %41 seviyesinde kalmıştır.  \n- **Dog (Köpek)** sınıfında ise model %61 oranında doğru tahmin yapabilmiştir.  \n- Genel doğruluk oranı (accuracy) yaklaşık **%51** olarak bulunmuştur.  \n\nBu durum modelin köpekleri kedilere kıyasla daha iyi ayırt ettiğini göstermektedir. Ancak kedi sınıfında düşük recall değeri, kedilerin bir kısmının yanlışlıkla köpek olarak sınıflandırıldığını işaret etmektedir.\n\n### Classification Report Sonuçları\n- **Cat (Kedi):** Precision %51, Recall %41, F1-score %45  \n- **Dog (Köpek):** Precision %51, Recall %61, F1-score %55  \n- **Macro Average (ortalama):** Precision %51, Recall %51, F1-score %50  \n\n### Yorum\nModel genel olarak dengeli bir performans sergilemekte, ancak doğruluk oranı düşük kalmaktadır.  \nBunun nedeni:\n- Eğitim süresinin (epoch sayısının) az olması  \n- Modelin henüz yeterince karmaşık olmaması  \n- Daha fazla veri artırma (Data Augmentation) veya hiperparametre optimizasyonu gerekmesidir.  \n\n**Sonuç:**  \nModel, başlangıç seviyesinde anlamlı bir performans göstermiştir (%51 doğruluk). Ancak daha iyi sonuç için ek optimizasyon ve uzun süreli eğitim yapılmalıdır.\n","metadata":{}},{"cell_type":"markdown","source":"## 11. Grad-CAM Görselleştirme\n\nBu adımda modelin görseller üzerinde hangi bölgelerden etkilendiğini anlamak için **Grad-CAM (Gradient-weighted Class Activation Mapping)** yöntemi uygulanmıştır.  \n\n### Yöntem\n- Model Sequential API ile eğitildiği için, Grad-CAM uygulanabilirliği artırmak amacıyla **Functional API** kullanılarak model yeniden tanımlanmıştır.  \n- Sequential modelde eğitilen ağırlıklar Functional API’ye aktarılmıştır.  \n- Son convolutional katman (**last_conv**) üzerinde gradyanlar hesaplanmış ve feature map’ler ile çarpılarak önem haritası (heatmap) elde edilmiştir.  \n- Bu ısı haritası orijinal görsel üzerine bindirilerek modelin odaklandığı bölgeler görselleştirilmiştir.  \n\n### Çıktılar\n- **Orijinal Görsel (Original):** Veri setinden alınan test görseli.  \n- **Grad-CAM Heatmap:** Modelin dikkate aldığı bölgeler kırmızı (yüksek önem) ve mavi (düşük önem) ile gösterilmiştir.  \n- **Birleşik Görsel (Overlay):** Orijinal görüntü ile ısı haritası birleştirilmiş, modelin karar sürecinde hangi alanları kullandığı daha net şekilde görülmüştür.  \n\n### Yorum\n- Model özellikle hayvanın bulunduğu bölgelerde (örneğin yüz ve gövde kısmı) yoğunlaşmıştır.  \n- Ancak bazı örneklerde arka plan bölgelerine de dikkat ettiği gözlemlenmiştir.  \n- Bu durum, modelin karar verme sürecinde istenmeyen gürültülere de duyarlı olabileceğini göstermektedir.  \n\n**Sonuç:**  \nGrad-CAM analizi, modelin karar mekanizmasını anlamamıza yardımcı olmuş, modelin hayvan bölgelerine odaklanma eğiliminde olduğunu ancak genellemede hâlâ iyileştirmeye ihtiyaç duyduğunu ortaya koymuştur.\n\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import Input, Model\n\n# Modeli yeniden Functional API ile kur (Sequential yerine)\ninputs = Input(shape=(150,150,3))\n\nx = Conv2D(32, (3,3), activation='relu')(inputs)\nx = MaxPooling2D(2,2)(x)\n\nx = Conv2D(64, (3,3), activation='relu')(x)\nx = MaxPooling2D(2,2)(x)\n\nx = Conv2D(128, (3,3), activation='relu', name=\"last_conv\")(x)\nx = MaxPooling2D(2,2)(x)\n\nx = Flatten()(x)\nx = Dense(128, activation='relu')(x)\nx = Dropout(0.5)(x)\noutputs = Dense(1, activation='sigmoid')(x)\n\nmodel_func = Model(inputs, outputs)\nmodel_func.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n\n# Eğitilmiş ağırlıkları Sequential modelden Functional modele aktar\nfor layer_old, layer_new in zip(model.layers, model_func.layers):\n    try:\n        layer_new.set_weights(layer_old.get_weights())\n    except:\n        pass\n\n# Şimdi Grad-CAM\nimg = tf.keras.preprocessing.image.load_img(img_path, target_size=(150, 150))\nimg_array = tf.keras.preprocessing.image.img_to_array(img)\nimg_array = np.expand_dims(img_array, axis=0) / 255.0\n\npred = model_func.predict(img_array)[0][0]\npred_class = \"dog\" if pred > 0.5 else \"cat\"\n\ngrad_model = Model([model_func.inputs], [model_func.get_layer(\"last_conv\").output, model_func.output])\n\nwith tf.GradientTape() as tape:\n    conv_outputs, predictions = grad_model(img_array)\n    loss = predictions[:, 0]\n\ngrads = tape.gradient(loss, conv_outputs)[0]\npooled_grads = tf.reduce_mean(grads, axis=(0,1,2))\nconv_outputs = conv_outputs[0]\n\nheatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_outputs), axis=-1).numpy()\nheatmap = np.maximum(heatmap, 0)\nheatmap /= np.max(heatmap)\n\n# Görsel üzerine bindirme\nimg_orig = cv2.imread(img_path)\nimg_orig = cv2.cvtColor(img_orig, cv2.COLOR_BGR2RGB)\nheatmap = cv2.resize(heatmap, (img_orig.shape[1], img_orig.shape[0]))\nheatmap = np.uint8(255 * heatmap)\nheatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)\nsuperimposed_img = cv2.addWeighted(img_orig, 0.6, heatmap, 0.4, 0)\n\n# Çizim\nplt.figure(figsize=(12,4))\nplt.subplot(1,3,1)\nplt.imshow(img_orig)\nplt.title(\"Original\")\n\nplt.subplot(1,3,2)\nplt.imshow(heatmap)\nplt.title(\"Grad-CAM Heatmap\")\n\nplt.subplot(1,3,3)\nplt.imshow(superimposed_img)\nplt.title(f\"Pred: {pred_class} ({pred:.2f})\")\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:17:10.755874Z","iopub.execute_input":"2025-09-26T17:17:10.756946Z","iopub.status.idle":"2025-09-26T17:17:12.539183Z","shell.execute_reply.started":"2025-09-26T17:17:10.756915Z","shell.execute_reply":"2025-09-26T17:17:12.538413Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\n## 12. Hiperparametre Optimizasyonu\n\nBu adımda modelin performansını artırmak için farklı hiperparametreler üzerinde denemeler yapılmıştır.  \n\n### Yapılan Değişiklikler\n- **Dense Katmanı:** 128 → **256 nöron**  \n- **Dropout Oranı:** 0.5 → **0.3**  \n- **Optimizer:** Adam yerine **RMSprop**  \n- **Learning Rate:** 0.001 → **0.0001**  \n\n### Sonuçlar (3 Epoch)\n- **Epoch 1:** Train Acc = %55.1, Val Acc = %63.9  \n- **Epoch 2:** Train Acc = %63.7, Val Acc = %70.2  \n- **Epoch 3:** Train Acc = %67.1, Val Acc = %67.3  \n\n### Yorum\n- Learning rate’in küçültülmesi, daha stabil bir öğrenme sağlamıştır.  \n- Validation accuracy %70 seviyelerine çıkarak önceki modelden daha iyi performans elde edilmiştir.  \n- Ancak 3. epoch sonunda validation accuracy’nin bir miktar düştüğü gözlemlenmiştir → **overfitting eğilimi** olabilir.  \n\n**Sonuç:**  \nHiperparametre değişiklikleri modelin doğruluğunu artırmış ancak tam olarak dengeli bir performans için daha fazla deneme yapılması gerekmektedir. Özellikle dropout oranı ve dense katman boyutları, modelin regularization kabiliyetini etkileyen önemli faktörlerdir.\n\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.optimizers import RMSprop\n\nmodel_opt = Sequential([\n    Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n    \n    Conv2D(64, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Conv2D(128, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Flatten(),\n    Dense(256, activation='relu'),   # 128 → 256\n    Dropout(0.3),                    # 0.5 → 0.3\n    Dense(1, activation='sigmoid')\n])\n\nmodel_opt.compile(\n    optimizer=RMSprop(learning_rate=1e-4),\n    loss=\"binary_crossentropy\",\n    metrics=[\"accuracy\"]\n)\n\nhistory_opt = model_opt.fit(\n    train_generator,\n    steps_per_epoch=len(train_generator),\n    epochs=3,\n    validation_data=val_generator,\n    validation_steps=len(val_generator)\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:19:02.832165Z","iopub.execute_input":"2025-09-26T17:19:02.832446Z","iopub.status.idle":"2025-09-26T17:26:19.214906Z","shell.execute_reply.started":"2025-09-26T17:19:02.832425Z","shell.execute_reply":"2025-09-26T17:26:19.214341Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 13. Hiperparametre Denemelerinin Sonuçları\n\nBu adımda orijinal model ile optimize edilmiş modelin performansını karşılaştırıyoruz.  \n\n### Karşılaştırılan Modeller\n- **Orijinal Model:**  \n  - Optimizer: Adam  \n  - Dense units: 128  \n  - Dropout: 0.5  \n\n- **Optimize Edilmiş Model:**  \n  - Optimizer: RMSprop (learning rate = 1e-4)  \n  - Dense units: 256  \n  - Dropout: 0.3  \n\n### Accuracy Sonuçları\n- Orijinal modelde validation accuracy en fazla **%69.4** seviyesine ulaşmıştır.  \n- Optimize edilmiş modelde validation accuracy **%70.2** ile daha yüksek bir değer elde edilmiştir.  \n- Training accuracy optimize edilmiş modelde daha hızlı artış göstermiştir.\n\n### Loss Sonuçları\n- Orijinal modelde validation loss **0.569 → 0.52** seviyelerine düşmüştür.  \n- Optimize edilmiş modelde validation loss başlangıçta daha düşük değerler almış ancak 3. epoch sonunda küçük bir artış göstermiştir.  \n\n### Yorum\n- Optimize edilmiş model **daha yüksek doğruluk (accuracy)** sağlamıştır.  \n- Ancak validation loss’taki dalgalanma, **overfitting riskine** işaret edebilir.  \n- Daha fazla epoch ve ek regularization yöntemleri (ör. L2 penalty) ile sonuçlar dengelenebilir.  \n\n⚠️ **Not:** Bu karşılaştırma hızlı denemeler için **3 epoch** ile yapılmıştır. Daha uzun eğitimlerde sonuçlar farklılık gösterebilir.  \n\n","metadata":{}},{"cell_type":"code","source":"# Orijinal model history\nacc1 = history.history['accuracy']\nval_acc1 = history.history['val_accuracy']\nloss1 = history.history['loss']\nval_loss1 = history.history['val_loss']\n\n# Yeni model history\nacc2 = history_opt.history['accuracy']\nval_acc2 = history_opt.history['val_accuracy']\nloss2 = history_opt.history['loss']\nval_loss2 = history_opt.history['val_loss']\n\nepochs = range(1, len(acc2)+1)\n\nplt.figure(figsize=(12,5))\n\n# Accuracy karşılaştırma\nplt.subplot(1,2,1)\nplt.plot(epochs, acc1[:len(acc2)], 'bo-', label='Original Train Acc')\nplt.plot(epochs, val_acc1[:len(acc2)], 'ro-', label='Original Val Acc')\nplt.plot(epochs, acc2, 'bx--', label='Optimized Train Acc')\nplt.plot(epochs, val_acc2, 'rx--', label='Optimized Val Acc')\nplt.title('Accuracy Comparison')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\n# Loss karşılaştırma\nplt.subplot(1,2,2)\nplt.plot(epochs, loss1[:len(acc2)], 'bo-', label='Original Train Loss')\nplt.plot(epochs, val_loss1[:len(acc2)], 'ro-', label='Original Val Loss')\nplt.plot(epochs, loss2, 'bx--', label='Optimized Train Loss')\nplt.plot(epochs, val_loss2, 'rx--', label='Optimized Val Loss')\nplt.title('Loss Comparison')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:27:02.68627Z","iopub.execute_input":"2025-09-26T17:27:02.686523Z","iopub.status.idle":"2025-09-26T17:27:03.070282Z","shell.execute_reply.started":"2025-09-26T17:27:02.686506Z","shell.execute_reply":"2025-09-26T17:27:03.069512Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 14. Katman Sayısı Denemesi\n\nBu denemede, modelin derinliğini artırmak amacıyla **4. Conv2D + MaxPooling katmanı** eklenmiştir.  \nÖnceki model 3 katmanlıyken, bu versiyon 4 katmanlı CNN mimarisine sahiptir.  \n\n### Model Yapısı\n- Conv2D (32 filtre) + MaxPooling  \n- Conv2D (64 filtre) + MaxPooling  \n- Conv2D (128 filtre) + MaxPooling  \n- Conv2D (256 filtre) + MaxPooling  ← **Yeni eklenen katman**  \n- Flatten  \n- Dense (128 nöron, ReLU)  \n- Dropout (0.5)  \n- Dense (1 nöron, Sigmoid çıkış)  \n\n### Eğitim Sonuçları\n- **Epoch 1:** Train Acc = %53.8, Val Acc = %59.7  \n- **Epoch 2:** Train Acc = %62.0, Val Acc = %69.8  \n- **Epoch 3:** Train Acc = %67.1, Val Acc = %74.6  \n\n### Yorum\n- Ekstra katman ile modelin **validation accuracy %74.6** seviyesine çıkmıştır.  \n- Validation loss değerleri sürekli azalmış (**0.639 → 0.515**), bu da modelin genelleme gücünü artırdığını göstermektedir.  \n- Daha derin yapı, özellikle karmaşık görselleri ayırt etmede avantaj sağlamıştır.  \n- Ancak eğitim süresi de artmıştır (her epoch ~2.5 dakika).  \n\n⚠️ **Not:** Bu deneme yine 3 epoch ile sınırlandırılmıştır. Daha uzun eğitimlerde daha da yüksek doğruluk elde edilebilir.  \n","metadata":{}},{"cell_type":"code","source":"model_layers = Sequential([\n    Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n    \n    Conv2D(64, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Conv2D(128, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    # Yeni eklenen 4. Conv katman\n    Conv2D(256, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.5),\n    Dense(1, activation='sigmoid')\n])\n\nmodel_layers.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n\nhistory_layers = model_layers.fit(\n    train_generator,\n    steps_per_epoch=len(train_generator),\n    epochs=3,   # hızlı deneme\n    validation_data=val_generator,\n    validation_steps=len(val_generator)\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:31:04.561507Z","iopub.execute_input":"2025-09-26T17:31:04.561788Z","iopub.status.idle":"2025-09-26T17:38:17.703403Z","shell.execute_reply.started":"2025-09-26T17:31:04.56176Z","shell.execute_reply":"2025-09-26T17:38:17.702797Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 15. Filtre Sayısı Denemesi\n\nBu denemede CNN katmanlarındaki filtre sayıları artırılmıştır.  \nAmaç: Daha fazla özellik haritası çıkararak modelin doğruluk performansını artırmak.  \n\n### Model Yapısı\n- Conv2D (64 filtre) + MaxPooling  \n- Conv2D (128 filtre) + MaxPooling  \n- Conv2D (256 filtre) + MaxPooling  \n- Flatten  \n- Dense (128 nöron, ReLU)  \n- Dropout (0.5)  \n- Dense (1 nöron, Sigmoid çıkış)  \n\n### Eğitim Sonuçları\n- **Epoch 1:** Train Acc = %50.2, Val Acc = %49.9  \n- **Epoch 2:** Train Acc = %50.0, Val Acc = %50.1  \n- **Epoch 3:** Train Acc = %50.9, Val Acc = %50.2  \n\n### Yorum\n- Beklenenin aksine filtre sayısını artırmak modelin performansını **artırmamış**, tam tersine model **tahmin yapamayan (random guess) bir hale** gelmiştir.  \n- Validation accuracy yaklaşık **%50** seviyesinde kalmış, bu da modelin sınıfları ayırt edemediğini göstermektedir.  \n- Olası nedenler:  \n  - Aşırı parametre sayısı nedeniyle modelin **çok hızlı overfit/underfit** olması.  \n  - Learning rate ve optimizer ayarlarının bu büyük filtre setine uygun olmaması.  \n  - Epoch sayısının yetersiz kalması.  \n\n**Sonuç:** Filtre sayısını artırmak her zaman daha iyi sonuç vermez. Doğru filtre sayısı, dropout ve learning rate ayarlarıyla birlikte optimize edilmelidir.  \n\n","metadata":{}},{"cell_type":"code","source":"model_filters = Sequential([\n    Conv2D(64, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n    \n    Conv2D(128, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Conv2D(256, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.5),\n    Dense(1, activation='sigmoid')\n])\n\nmodel_filters.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n\nhistory_filters = model_filters.fit(\n    train_generator,\n    steps_per_epoch=len(train_generator),\n    epochs=3,   # hızlı deneme\n    validation_data=val_generator,\n    validation_steps=len(val_generator)\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:39:10.478007Z","iopub.execute_input":"2025-09-26T17:39:10.478271Z","iopub.status.idle":"2025-09-26T17:46:41.863944Z","shell.execute_reply.started":"2025-09-26T17:39:10.478252Z","shell.execute_reply":"2025-09-26T17:46:41.863316Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 16. Kernel Boyutu Denemesi\n\nBu denemede, CNN katmanlarındaki filtre çekirdek boyutu **3x3 yerine 5x5** olarak değiştirilmiştir.  \nAmaç: Daha geniş receptive field kullanarak modelin daha fazla özellik yakalayıp doğruluk performansını artırıp artırmadığını gözlemlemek.  \n\n### Model Yapısı\n- Conv2D (32 filtre, **5x5 kernel**) + MaxPooling  \n- Conv2D (64 filtre, **5x5 kernel**) + MaxPooling  \n- Conv2D (128 filtre, **5x5 kernel**) + MaxPooling  \n- Flatten  \n- Dense (128 nöron, ReLU)  \n- Dropout (0.5)  \n- Dense (1 nöron, Sigmoid çıkış)  \n\n### Eğitim Sonuçları (200 adım/epoch, hızlandırılmış)\n- **Epoch 1:** Train Acc = %49.8, Val Acc = %50.4  \n- **Epoch 2:** Train Acc = %50.5, Val Acc = %52.2  \n- **Epoch 3:** Train Acc = %50.7, Val Acc = %50.3  \n\n### Yorum\n- Kernel boyutunu 5x5 yapmak, modelin öğrenmesini **olumsuz etkilemiştir**.  \n- Validation accuracy yaklaşık **%50** seviyesinde kalmış, bu da modelin rastgele tahmin yaptığı anlamına gelmektedir.  \n- Olası nedenler:  \n  - 5x5 kernel’lar daha fazla parametre içerdiği için, küçük epoch sayılarında **verimli öğrenme sağlayamamış** olabilir.  \n  - Daha uzun eğitim veya learning rate ayarı ile iyileşme görülebilir.  \n  - 3x3 kernel genellikle görsel sınıflandırma görevlerinde daha **stabil ve verimli** sonuçlar üretir.  \n\n**Sonuç:** Kernel boyutunu büyütmek her zaman avantaj sağlamaz. Bu deneyde, 3x3 kernel daha uygun görünmektedir.  \n","metadata":{}},{"cell_type":"code","source":"model_kernel = Sequential([\n    Conv2D(32, (5,5), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n    \n    Conv2D(64, (5,5), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Conv2D(128, (5,5), activation='relu'),\n    MaxPooling2D(2,2),\n    \n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.5),\n    Dense(1, activation='sigmoid')\n])\n\nmodel_kernel.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n\nhistory_kernel = model_kernel.fit(\n    train_generator,\n    steps_per_epoch=200,    # hızlandırılmış eğitim\n    epochs=3,\n    validation_data=val_generator,\n    validation_steps=100\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:48:30.257211Z","iopub.execute_input":"2025-09-26T17:48:30.258023Z","iopub.status.idle":"2025-09-26T17:51:02.955367Z","shell.execute_reply.started":"2025-09-26T17:48:30.257993Z","shell.execute_reply":"2025-09-26T17:51:02.954572Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 17. Batch Size Denemesi\n\nBu denemede eğitim batch size değeri **32 → 64** olarak değiştirilmiştir.  \nAmaç: Daha büyük batch ile eğitim hızının ve modelin genelleme performansının nasıl etkilendiğini gözlemlemek.  \n\n### Model Yapısı\n- Conv2D (32 filtre, 3x3) + MaxPooling  \n- Conv2D (64 filtre, 3x3) + MaxPooling  \n- Conv2D (128 filtre, 3x3) + MaxPooling  \n- Flatten  \n- Dense (128 nöron, ReLU)  \n- Dropout (0.5)  \n- Dense (1 nöron, Sigmoid çıkış)  \n\n### Eğitim Sonuçları (2 Epoch, Batch Size=64)\n- **Epoch 1:** Train Acc = %51.2, Val Acc = %57.7  \n- **Epoch 2:** Train Acc = %61.2, Val Acc = %65.7  \n\n### Yorum\n- Batch size’in 64 yapılması, **validation accuracy’yi %65+ seviyesine çıkarmıştır.**  \n- Eğitim ve doğrulama kayıpları azalmış, model daha iyi genelleme göstermiştir.  \n- Ancak daha büyük batch, **GPU belleğini daha fazla kullanır** ve bazı durumlarda küçük batch’lere göre daha yavaş yakınsama gösterebilir.  \n- Bu denemede **performans artışı gözlenmiştir**, dolayısıyla batch size 64 uygun bir seçim olabilir.  \n\n⚠️ Not: Bu sonuçlar hızlandırılmış eğitim (2 epoch) ile elde edilmiştir. Tam dataset üzerinde daha uzun epoch sayısı ile daha güçlü sonuçlar elde edilebilir.  \n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\n\n# Batch size = 64 olacak şekilde generator yeniden tanımlıyoruz\ntrain_generator_bs = train_datagen.flow_from_directory(\n    '/kaggle/working/data_split/train',\n    target_size=(150, 150),\n    batch_size=64,\n    class_mode='binary'\n)\n\nval_generator_bs = val_datagen.flow_from_directory(\n    '/kaggle/working/data_split/val',\n    target_size=(150, 150),\n    batch_size=64,\n    class_mode='binary'\n)\n\n# Model tanımlama\nmodel_batch = Sequential([\n    Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n\n    Conv2D(64, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n\n    Conv2D(128, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n\n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.5),\n    Dense(1, activation='sigmoid')\n])\n\nmodel_batch.compile(optimizer=Adam(learning_rate=1e-3),\n                    loss=\"binary_crossentropy\",\n                    metrics=[\"accuracy\"])\n\nhistory_batch = model_batch.fit(\n    train_generator_bs,\n    steps_per_epoch=200,\n    epochs=2,   # hız için 2 epoch\n    validation_data=val_generator_bs,\n    validation_steps=100\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:52:01.273148Z","iopub.execute_input":"2025-09-26T17:52:01.273745Z","iopub.status.idle":"2025-09-26T17:54:40.356277Z","shell.execute_reply.started":"2025-09-26T17:52:01.273723Z","shell.execute_reply":"2025-09-26T17:54:40.355649Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 18. Otomatik Hiperparametre Optimizasyonu (Keras Tuner)\n\nBu adımda, manuel denemeler yerine **Keras Tuner** kütüphanesi ile hiperparametre araması yapılmıştır.  \nAmaç: Conv2D filtre sayıları, kernel boyutları, dense layer boyutu ve learning rate gibi kritik hiperparametreleri sistematik olarak tarayıp en iyi kombinasyonu bulmak.  \n\n### Denenen Parametreler\n- **Conv1 filters:** [32, 64]  \n- **Conv1 kernel size:** [3, 5]  \n- **Conv2 filters:** [64, 128]  \n- **Conv2 kernel size:** [3, 5]  \n- **Dense layer units:** [128, 256]  \n- **Learning rate:** [0.01, 0.001, 0.0001]  \n\n### Arama Yöntemi\n- **RandomSearch** kullanılmıştır.  \n- `max_trials = 3` olacak şekilde hızlı deneme yapılmıştır.  \n- Eğitim parametreleri: `epochs=2`, `steps_per_epoch=200`, `validation_steps=100`.  \n\n### Sonuçlar\n- En iyi validation accuracy ≈ **%51.2** olarak bulunmuştur.  \n- **Seçilen en iyi hiperparametreler:**  \n  - Conv1 filters: **32**  \n  - Conv1 kernel: **5**  \n  - Conv2 filters: **128**  \n  - Conv2 kernel: **5**  \n  - Dense units: **128**  \n  - Learning rate: **0.01**  \n\n### Yorum\n- Bu hızlı arama düşük epoch sayısı ile yapıldığı için sonuçlar sınırlı kalmıştır.  \n- Daha yüksek `max_trials` ve uzun eğitim (`epochs > 5`) ile daha anlamlı sonuçlar elde edilebilir.  \n- RandomSearch yerine **GridSearch** veya **Bayesian Optimization** yöntemleri de kullanılabilir.  \n\n- Not: Bu deney, **hızlı karşılaştırma için kısaltılmış dataset** üzerinde çalıştırılmıştır.  \nTam dataset ile daha uzun süreli eğitimde daha iyi doğruluk oranları elde edilebilir.  \n","metadata":{}},{"cell_type":"code","source":"!pip install -q -U keras-tuner\n\nimport keras_tuner as kt\n\ndef build_model(hp):\n    model = Sequential()\n    model.add(Conv2D(\n        filters=hp.Choice('conv_1_filter', values=[32,64]),\n        kernel_size=hp.Choice('conv_1_kernel', values=[3,5]),\n        activation='relu',\n        input_shape=(150,150,3)\n    ))\n    model.add(MaxPooling2D(2,2))\n    \n    model.add(Conv2D(\n        filters=hp.Choice('conv_2_filter', values=[64,128]),\n        kernel_size=hp.Choice('conv_2_kernel', values=[3,5]),\n        activation='relu'\n    ))\n    model.add(MaxPooling2D(2,2))\n    \n    model.add(Flatten())\n    model.add(Dense(\n        units=hp.Choice('dense_units', values=[128,256]),\n        activation='relu'\n    ))\n    model.add(Dropout(0.5))\n    model.add(Dense(1, activation='sigmoid'))\n    \n    model.compile(\n        optimizer=Adam(learning_rate=hp.Choice('lr', values=[1e-2,1e-3,1e-4])),\n        loss='binary_crossentropy',\n        metrics=['accuracy']\n    )\n    return model\n\ntuner = kt.RandomSearch(\n    build_model,\n    objective='val_accuracy',\n    max_trials=3, # hızlı deneme için 3 farklı model\n    directory='my_dir',\n    project_name='dogcat_tune'\n)\n\ntuner.search(\n    train_generator,\n    steps_per_epoch=200,\n    validation_data=val_generator,\n    validation_steps=100,\n    epochs=2 # hızlı arama için kısa\n)\n\nbest_hps = tuner.get_best_hyperparameters(num_trials=1)[0]\nprint(\"En iyi parametreler:\")\nprint(f\"Conv1 filters: {best_hps.get('conv_1_filter')}\")\nprint(f\"Conv1 kernel: {best_hps.get('conv_1_kernel')}\")\nprint(f\"Conv2 filters: {best_hps.get('conv_2_filter')}\")\nprint(f\"Conv2 kernel: {best_hps.get('conv_2_kernel')}\")\nprint(f\"Dense units: {best_hps.get('dense_units')}\")\nprint(f\"Learning rate: {best_hps.get('lr')}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T17:56:11.57125Z","iopub.execute_input":"2025-09-26T17:56:11.571772Z","iopub.status.idle":"2025-09-26T18:01:50.430077Z","shell.execute_reply.started":"2025-09-26T17:56:11.57175Z","shell.execute_reply":"2025-09-26T18:01:50.429295Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 19. Regularization (L2) ile Overfitting Önleme\n\nBu adımda, **L2 Regularization** uygulanarak modelin overfitting eğilimi azaltılmaya çalışılmıştır.  \nAmaç: Ağırlıkların aşırı büyümesini engelleyerek modelin daha iyi genelleme yapmasını sağlamak.  \n\n### Model Yapısı\n- Conv2D (32 filtre, 3x3) + MaxPooling  \n- Conv2D (64 filtre, 3x3) + MaxPooling  \n- Conv2D (128 filtre, 3x3) + MaxPooling  \n- Flatten  \n- Dense (128 nöron, ReLU, **L2=0.001 regularization**)  \n- Dropout (0.5)  \n- Dense (1 nöron, Sigmoid çıkış)  \n\n### Eğitim Sonuçları (2 Epoch)\n- **Epoch 1:** Train Acc = %51.2, Val Acc = %50.7  \n- **Epoch 2:** Train Acc = %50.8, Val Acc = %56.7  \n\n### Yorum\n- L2 regularization, modelin **validation accuracy’sini kısmen artırmış (%56.7)** olsa da, eğitim doğruluğunu sınırlamıştır.  \n- Bu, regularization’ın ağırlıkları cezalandırarak modelin **ezberlemesini engellediğini** göstermektedir.  \n- Uzun epoch ve uygun hyperparametrelerle (örneğin `l2=0.0001` gibi daha düşük değerler) daha iyi sonuçlar elde edilebilir.  \n- Bu yöntem, dropout ile birlikte **overfitting’i azaltmak için güçlü bir stratejidir.**  \n\n- Not: Eğitim, hızlandırma amacıyla **200 adım/epoch ve sadece 2 epoch** ile yapılmıştır.  \nTam dataset ve daha uzun eğitim süresiyle daha anlamlı sonuçlar elde edilecektir.  \n\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import regularizers\n\nmodel_reg = Sequential([\n    Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    MaxPooling2D(2,2),\n\n    Conv2D(64, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n\n    Conv2D(128, (3,3), activation='relu'),\n    MaxPooling2D(2,2),\n\n    Flatten(),\n    Dense(128, activation='relu', kernel_regularizer=regularizers.l2(0.001)),  # L2 eklendi\n    Dropout(0.5),\n    Dense(1, activation='sigmoid')\n])\n\nmodel_reg.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n\nhistory_reg = model_reg.fit(\n    train_generator,\n    steps_per_epoch=200,\n    epochs=2,   # hızlı deneme\n    validation_data=val_generator,\n    validation_steps=100\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T18:02:02.316724Z","iopub.execute_input":"2025-09-26T18:02:02.317489Z","iopub.status.idle":"2025-09-26T18:03:50.297644Z","shell.execute_reply.started":"2025-09-26T18:02:02.317464Z","shell.execute_reply":"2025-09-26T18:03:50.296953Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 20. Overfitting / Underfitting Karşılaştırması (Original vs L2 Regularization)\n\nBu adımda, **regularization eklenmiş model** ile **orijinal model**in accuracy ve loss grafikleri karşılaştırılmıştır.  \n\n### Accuracy Grafiği\n- Orijinal modelde eğitim ve doğrulama doğrulukları daha yüksek, validation accuracy %69 seviyelerine ulaşmıştır.  \n- Regularization eklenen modelde doğruluk değerleri daha düşük kalmıştır (~%56).  \n- Bu durum, **L2 regularization’ın modeli fazla karmaşık öğrenmekten alıkoyduğunu**, ancak kısa epoch sayısı nedeniyle henüz potansiyelini gösteremediğini düşündürmektedir.  \n\n### Loss Grafiği\n- Orijinal modelde loss değerleri hem train hem de validation tarafında düzenli düşmüştür.  \n- L2 regularization eklenen modelde train loss daha yüksek kalmıştır, çünkü regularization ağırlıklara ceza ekleyerek **daha kısıtlayıcı bir öğrenme** sağlamıştır.  \n- Validation loss ise daha yavaş düşmüş, fakat overfitting eğilimi gözlenmemiştir.  \n\n### Sonuç\n- **Orijinal model → daha yüksek doğruluk, ancak uzun vadede overfitting riski taşıyabilir.**  \n- **Regularized model → daha düşük doğruluk, fakat daha dengeli ve genellemeye uygun bir yapıdadır.**  \n- Daha uzun eğitim (10+ epoch) ve farklı regularization katsayıları ile daha sağlıklı sonuçlar elde edilebilir.  \n\n- Not: Eğitim süresi kısıtlı olduğu için bu karşılaştırma **2 epoch ile hızlı bir deneme** olarak yapılmıştır.  \nTam dataset ve daha uzun epoch ile farklar daha net gözlemlenecektir.  \n\n","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12,5))\n\n# Accuracy karşılaştırması\nplt.subplot(1,2,1)\nplt.plot(history.history['accuracy'], 'b-', label='Original Train Acc')\nplt.plot(history.history['val_accuracy'], 'r-', label='Original Val Acc')\nplt.plot(history_reg.history['accuracy'], 'b--', label='Reg Train Acc')\nplt.plot(history_reg.history['val_accuracy'], 'r--', label='Reg Val Acc')\nplt.title(\"Accuracy Comparison\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Accuracy\")\nplt.legend()\n\n# Loss karşılaştırması\nplt.subplot(1,2,2)\nplt.plot(history.history['loss'], 'b-', label='Original Train Loss')\nplt.plot(history.history['val_loss'], 'r-', label='Original Val Loss')\nplt.plot(history_reg.history['loss'], 'b--', label='Reg Train Loss')\nplt.plot(history_reg.history['val_loss'], 'r--', label='Reg Val Loss')\nplt.title(\"Loss Comparison\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-26T18:05:01.603Z","iopub.execute_input":"2025-09-26T18:05:01.603329Z","iopub.status.idle":"2025-09-26T18:05:02.075256Z","shell.execute_reply.started":"2025-09-26T18:05:01.603307Z","shell.execute_reply":"2025-09-26T18:05:02.0745Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}