{"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":"none","dataSources":[{"sourceType":"competition","sourceId":3362,"databundleVersionId":31148}],"dockerImageVersionId":31328,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# ============================================\n# DOGS VS CATS - COMPLETE SOLUTION FOR KAGGLE\n# WITH SUPPRESSED WARNINGS\n# ============================================\n\n# Suppress all warnings\nimport warnings\nwarnings.filterwarnings('ignore')\n\n# Suppress TensorFlow warnings and logs\nimport os\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'  # Suppress TF info/warnings\nos.environ['CUDA_VISIBLE_DEVICES'] = '-1'  # Optional: disable GPU warnings\n\n# Suppress other common warnings\nimport logging\nlogging.disable(logging.CRITICAL)\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport cv2\nimport zipfile\nfrom PIL import Image\nimport tensorflow as tf\n\n# Additional TensorFlow warning suppression\ntf.get_logger().setLevel('ERROR')\ntf.autograph.set_verbosity(3)\n\n# Suppress oneDNN and other optimizations warnings\nos.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'\n\n# Suppress absl logs\nfrom absl import logging as absl_logging\nabsl_logging.set_verbosity(absl_logging.ERROR)\n\nfrom tensorflow import keras\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.models import Sequential, Model\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization, GlobalAveragePooling2D\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom tensorflow.keras.applications import VGG16, ResNet50, MobileNetV2\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report, confusion_matrix, accuracy_score, roc_curve, auc\n\nnp.random.seed(42)\ntf.random.set_seed(42)\n\n# ============================================\n# CORRECT PATH FOR KAGGLE COMPETITION WITH ZIP FILES\n# ============================================\nDATASET_PATH = '/kaggle/input/competitions/dogs-vs-cats'\nEXTRACT_PATH = '/kaggle/working/dogs-vs-cats'\n\nprint(\"=\"*60)\nprint(\"DOGS VS CATS CLASSIFICATION PROJECT\")\nprint(\"=\"*60)\n\n# ============================================\n# STEP 1: EXTRACT ZIP FILES\n# ============================================\nprint(\"\\n[1] Extracting zip files...\")\n\n# Create extraction directory\nos.makedirs(EXTRACT_PATH, exist_ok=True)\n\n# Extract train.zip\ntrain_zip_path = os.path.join(DATASET_PATH, 'train.zip')\ntest_zip_path = os.path.join(DATASET_PATH, 'test1.zip')\n\n# Extract training data\nif os.path.exists(train_zip_path):\n    print(\"Extracting training images...\")\n    with zipfile.ZipFile(train_zip_path, 'r') as zip_ref:\n        zip_ref.extractall(EXTRACT_PATH)\n    print(\"Training extraction complete!\")\n\n# Set paths after extraction\nTRAIN_PATH = os.path.join(EXTRACT_PATH, 'train')\nTEST_PATH = os.path.join(EXTRACT_PATH, 'test1')\n\nprint(f\"\\nTrain path exists: {os.path.exists(TRAIN_PATH)}\")\n\n# ============================================\n# STEP 2: DATASET EXPLORATION\n# ============================================\nprint(\"\\n[2] Dataset Exploration:\")\n\ntrain_files = os.listdir(TRAIN_PATH)\ndog_count = sum(1 for f in train_files if f.startswith('dog'))\ncat_count = sum(1 for f in train_files if f.startswith('cat'))\n\nprint(f\"Total images: {len(train_files)}\")\nprint(f\"Dogs : {dog_count}\")\nprint(f\"Cats : {cat_count}\")\n\n# Display sample images\nfig, axes = plt.subplots(2, 4, figsize=(14, 7))\naxes = axes.ravel()\nfor i, animal in enumerate(['dog', 'cat']):\n    animal_files = [f for f in train_files if f.startswith(animal)][:4]\n    for j, file in enumerate(animal_files):\n        idx = i*4 + j\n        img_path = os.path.join(TRAIN_PATH, file)\n        img = load_img(img_path)\n        axes[idx].imshow(img)\n        axes[idx].set_title(f\"{animal.capitalize()}\")\n        axes[idx].axis('off')\nplt.suptitle(\"Sample Images from Dataset - Dogs and Cats\", fontsize=14)\nplt.tight_layout()\nplt.show()\n\n# ============================================\n# STEP 3: DATA PREPROCESSING\n# ============================================\nprint(\"\\n[3] Loading and Preprocessing Images...\")\n\nIMG_SIZE = (128, 128)\nBATCH_SIZE = 64\nEPOCHS = 20\n\ndef load_data(img_size=IMG_SIZE, num_samples=None):\n    \"\"\"Load images and preprocess them (resizing + normalization)\"\"\"\n    images = []\n    labels = []\n    \n    files_to_use = train_files\n    if num_samples:\n        files_to_use = train_files[:num_samples]\n    \n    for i, filename in enumerate(files_to_use):\n        if filename.endswith('.jpg'):\n            img_path = os.path.join(TRAIN_PATH, filename)\n            # Load and resize\n            img = load_img(img_path, target_size=img_size)\n            # Convert to array and normalize to [0,1]\n            img_array = img_to_array(img) / 255.0\n            # Label: 1 for dog, 0 for cat\n            label = 1 if filename.startswith('dog') else 0\n            images.append(img_array)\n            labels.append(label)\n        \n        if (i + 1) % 5000 == 0:\n            print(f\"Processed {i+1} images...\")\n    \n    return np.array(images), np.array(labels)\n\n# Load data (using 20000 images for faster training)\nprint(\"Loading images (this may take a few minutes)...\")\nX, y = load_data(num_samples=20000)\nprint(f\"Data shape: X={X.shape}, y={y.shape}\")\n\n# Split data into train, validation, test sets\nX_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)\nX_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp)\n\nprint(f\"\\nTraining set: {X_train.shape}\")\nprint(f\"Validation set: {X_val.shape}\")\nprint(f\"Test set: {X_test.shape}\")\n\n# ============================================\n# STEP 4: DATA AUGMENTATION\n# ============================================\nprint(\"\\n[4] Applying Data Augmentation...\")\n\ntrain_datagen = ImageDataGenerator(\n    rotation_range=20,\n    width_shift_range=0.15,\n    height_shift_range=0.15,\n    shear_range=0.15,\n    zoom_range=0.15,\n    horizontal_flip=True,\n    fill_mode='nearest'\n)\n\nval_datagen = ImageDataGenerator()\n\ntrain_generator = train_datagen.flow(X_train, y_train, batch_size=BATCH_SIZE, shuffle=True)\nval_generator = val_datagen.flow(X_val, y_val, batch_size=BATCH_SIZE, shuffle=False)\n\n# Visualize augmentation results\ndef visualize_augmentation():\n    \"\"\"Show examples of augmented images\"\"\"\n    sample_img = X_train[0]\n    sample_img_expanded = sample_img.reshape((1,) + sample_img.shape)\n    \n    fig, axes = plt.subplots(1, 5, figsize=(15, 4))\n    axes[0].imshow(sample_img)\n    axes[0].set_title(\"Original\")\n    axes[0].axis('off')\n    \n    for i in range(4):\n        augmented = next(train_datagen.flow(sample_img_expanded, batch_size=1))[0]\n        axes[i+1].imshow(augmented)\n        axes[i+1].set_title(f\"Augmented {i+1}\")\n        axes[i+1].axis('off')\n    \n    plt.suptitle(\"Data Augmentation Examples\", fontsize=14)\n    plt.tight_layout()\n    plt.show()\n\nvisualize_augmentation()\n\n# ============================================\n# STEP 5A: CNN MODEL FROM SCRATCH\n# ============================================\nprint(\"\\n[5] Building CNN Model from Scratch...\")\n\ndef build_cnn_scratch(input_shape=(128, 128, 3)):\n    \"\"\"Build CNN model from scratch\"\"\"\n    model = Sequential([\n        Conv2D(32, (3, 3), activation='relu', padding='same', input_shape=input_shape),\n        BatchNormalization(),\n        MaxPooling2D((2, 2)),\n        \n        Conv2D(64, (3, 3), activation='relu', padding='same'),\n        BatchNormalization(),\n        MaxPooling2D((2, 2)),\n        \n        Conv2D(128, (3, 3), activation='relu', padding='same'),\n        BatchNormalization(),\n        MaxPooling2D((2, 2)),\n        \n        Conv2D(256, (3, 3), activation='relu', padding='same'),\n        BatchNormalization(),\n        MaxPooling2D((2, 2)),\n        \n        Flatten(),\n        Dense(512, activation='relu'),\n        Dropout(0.5),\n        Dense(256, activation='relu'),\n        Dropout(0.3),\n        Dense(1, activation='sigmoid')\n    ])\n    return model\n\ncnn_model = build_cnn_scratch()\ncnn_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\ncnn_model.summary()\n\ncallbacks = [\n    EarlyStopping(patience=5, restore_best_weights=True, verbose=0),  # Changed to 0 to suppress output\n    ReduceLROnPlateau(factor=0.5, patience=3, verbose=0),  # Changed to 0\n    ModelCheckpoint('/kaggle/working/best_cnn_model.h5', save_best_only=True, verbose=0)\n]\n\nprint(\"\\nTraining CNN from scratch...\")\nhistory_cnn = cnn_model.fit(\n    train_generator,\n    validation_data=val_generator,\n    epochs=EPOCHS,\n    callbacks=callbacks,\n    verbose=1\n)\n\n# ============================================\n# STEP 5B: TRANSFER LEARNING MODELS\n# ============================================\nprint(\"\\n[6] Building Transfer Learning Models...\")\n\ndef build_transfer_learning_model(base_model):\n    \"\"\"Build transfer learning model with pre-trained base\"\"\"\n    base_model.trainable = False\n    model = Sequential([\n        base_model,\n        GlobalAveragePooling2D(),\n        Dense(256, activation='relu'),\n        Dropout(0.5),\n        Dense(128, activation='relu'),\n        Dropout(0.3),\n        Dense(1, activation='sigmoid')\n    ])\n    return model\n\n# Load pre-trained models with verbose=0 to suppress output\nprint(\"Loading pre-trained models...\")\nvgg16_base = VGG16(weights='imagenet', include_top=False, input_shape=(128, 128, 3))\nresnet50_base = ResNet50(weights='imagenet', include_top=False, input_shape=(128, 128, 3))\nmobilenet_base = MobileNetV2(weights='imagenet', include_top=False, input_shape=(128, 128, 3))\n\ntransfer_models = {}\ntransfer_histories = {}\n\n# Train each transfer learning model\nfor name, base_model in [('VGG16', vgg16_base), ('ResNet50', resnet50_base), ('MobileNetV2', mobilenet_base)]:\n    print(f\"\\n{'='*40}\")\n    print(f\"Training {name}...\")\n    print('='*40)\n    \n    model = build_transfer_learning_model(base_model)\n    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n    \n    history = model.fit(\n        train_generator,\n        validation_data=val_generator,\n        epochs=12,\n        callbacks=callbacks,\n        verbose=1\n    )\n    \n    transfer_models[name] = model\n    transfer_histories[name] = history\n\n# ============================================\n# STEP 6: EVALUATION AND COMPARISON\n# ============================================\nprint(\"\\n[7] Model Evaluation and Comparison...\")\n\ndef evaluate_model(model, model_name, X_test, y_test):\n    \"\"\"Evaluate model and print metrics\"\"\"\n    y_pred_proba = model.predict(X_test, verbose=0)  # Suppress prediction output\n    y_pred = (y_pred_proba > 0.5).astype(int).flatten()\n    accuracy = accuracy_score(y_test, y_pred)\n    \n    print(f\"\\n{model_name} - Accuracy: {accuracy:.4f} ({accuracy*100:.2f}%)\")\n    print(f\"\\nClassification Report for {model_name}:\")\n    print(classification_report(y_test, y_pred, target_names=['Cat', 'Dog']))\n    \n    cm = confusion_matrix(y_test, y_pred)\n    plt.figure(figsize=(6, 5))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n                xticklabels=['Cat', 'Dog'], yticklabels=['Cat', 'Dog'])\n    plt.title(f'Confusion Matrix - {model_name}')\n    plt.ylabel('True Label')\n    plt.xlabel('Predicted Label')\n    plt.show()\n    \n    return accuracy, y_pred_proba\n\nresults = {}\n\nprint(\"\\n\" + \"=\"*50)\nprint(\"EVALUATING CNN FROM SCRATCH\")\nprint(\"=\"*50)\nacc_cnn, preds_cnn = evaluate_model(cnn_model, \"CNN from Scratch\", X_test, y_test)\nresults[\"CNN from Scratch\"] = acc_cnn\n\nfor name, model in transfer_models.items():\n    print(\"\\n\" + \"=\"*50)\n    print(f\"EVALUATING {name}\")\n    print(\"=\"*50)\n    acc, preds = evaluate_model(model, name, X_test, y_test)\n    results[name] = acc\n\n# ============================================\n# STEP 7: COMPARISON PLOTS\n# ============================================\nprint(\"\\n[8] Generating Comparison Plots...\")\n\n# Accuracy Comparison Bar Chart\nplt.figure(figsize=(10, 6))\nmodels_names = list(results.keys())\naccuracies = list(results.values())\ncolors = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd']\nbars = plt.bar(models_names, accuracies, color=colors)\nplt.title('Model Accuracy Comparison', fontsize=14, fontweight='bold')\nplt.xlabel('Model', fontsize=12)\nplt.ylabel('Accuracy', fontsize=12)\nplt.ylim(0, 1)\nfor bar, acc in zip(bars, accuracies):\n    plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01, \n             f'{acc:.3f}', ha='center', va='bottom', fontweight='bold', fontsize=11)\nplt.xticks(rotation=15, ha='right')\nplt.grid(axis='y', alpha=0.3)\nplt.tight_layout()\nplt.show()\n\n# Training History Comparison\nfig, axes = plt.subplots(1, 2, figsize=(14, 5))\n\naxes[0].plot(history_cnn.history['accuracy'], label='CNN Scratch (train)', linewidth=2)\naxes[0].plot(history_cnn.history['val_accuracy'], label='CNN Scratch (val)', linewidth=2, linestyle='--')\nfor name, history in transfer_histories.items():\n    axes[0].plot(history.history['val_accuracy'], label=f'{name} (val)', linestyle='--', linewidth=2)\naxes[0].set_title('Model Accuracy Comparison', fontsize=12, fontweight='bold')\naxes[0].set_xlabel('Epoch')\naxes[0].set_ylabel('Accuracy')\naxes[0].legend(loc='lower right')\naxes[0].grid(True, alpha=0.3)\n\naxes[1].plot(history_cnn.history['loss'], label='CNN Scratch (train)', linewidth=2)\naxes[1].plot(history_cnn.history['val_loss'], label='CNN Scratch (val)', linewidth=2, linestyle='--')\nfor name, history in transfer_histories.items():\n    axes[1].plot(history.history['val_loss'], label=f'{name} (val)', linestyle='--', linewidth=2)\naxes[1].set_title('Model Loss Comparison', fontsize=12, fontweight='bold')\naxes[1].set_xlabel('Epoch')\naxes[1].set_ylabel('Loss')\naxes[1].legend(loc='upper right')\naxes[1].grid(True, alpha=0.3)\n\nplt.tight_layout()\nplt.show()\n\n# ROC Curves\nplt.figure(figsize=(10, 8))\n\nfpr_cnn, tpr_cnn, _ = roc_curve(y_test, preds_cnn)\nroc_auc_cnn = auc(fpr_cnn, tpr_cnn)\nplt.plot(fpr_cnn, tpr_cnn, label=f'CNN Scratch (AUC = {roc_auc_cnn:.3f})', linewidth=2)\n\nfor name, model in transfer_models.items():\n    preds = model.predict(X_test, verbose=0)  # Suppress prediction output\n    fpr, tpr, _ = roc_curve(y_test, preds)\n    roc_auc = auc(fpr, tpr)\n    plt.plot(fpr, tpr, label=f'{name} (AUC = {roc_auc:.3f})', linewidth=2, linestyle='--')\n\nplt.plot([0, 1], [0, 1], 'k--', label='Random Classifier (AUC = 0.5)', linewidth=1)\nplt.xlim([0.0, 1.0])\nplt.ylim([0.0, 1.05])\nplt.xlabel('False Positive Rate', fontsize=12)\nplt.ylabel('True Positive Rate', fontsize=12)\nplt.title('ROC Curves - Model Comparison', fontsize=14, fontweight='bold')\nplt.legend(loc=\"lower right\")\nplt.grid(True, alpha=0.3)\nplt.show()\n\n# ============================================\n# FINAL SUMMARY\n# ============================================\nprint(\"\\n\" + \"=\"*60)\nprint(\"FINAL SUMMARY\")\nprint(\"=\"*60)\n\nbest_model = max(results, key=results.get)\nprint(f\"\\n Best Performing Model: {best_model}\")\nprint(f\"Best Accuracy: {results[best_model]:.4f} ({results[best_model]*100:.2f}%)\")\n\nprint(\"\\n Results Summary:\")\nprint(\"-\" * 40)\nfor model, acc in sorted(results.items(), key=lambda x: x[1], reverse=True):\n    print(f\"  {model:20s}: {acc:.4f} ({acc*100:.2f}%)\")\n\nprint(\"\\n Key Findings:\")\nprint(\"1. Transfer Learning models generally outperform CNN from scratch\")\nprint(\"2. Data augmentation helps prevent overfitting\")\nprint(\"3. Pre-trained models leverage knowledge from ImageNet\")\nprint(\"4. MobileNetV2 offers good balance between accuracy and efficiency\")\n\nprint(\"\\n\" + \"=\"*60)\nprint(\" PROJECT COMPLETED SUCCESSFULLY!\")\nprint(\"=\"*60)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T11:37:58.523823Z","iopub.execute_input":"2026-04-26T11:37:58.524218Z","execution_failed":"2026-04-26T14:19:31.477Z"}},"outputs":[],"execution_count":null}]}