{"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":"gpu","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#importsssssss\nimport zipfile\nimport os, cv2, re, random\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport keras","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:37:15.395632Z","iopub.execute_input":"2025-08-19T14:37:15.396367Z","iopub.status.idle":"2025-08-19T14:37:29.685353Z","shell.execute_reply.started":"2025-08-19T14:37:15.396341Z","shell.execute_reply":"2025-08-19T14:37:29.684687Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\n# Paths\ntrain_zip_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\"\ntrain_dir = \"/kaggle/working/train\"\n\n# 1. Clean old extraction if exists\nif os.path.exists(train_dir):\n    shutil.rmtree(train_dir)\n\n# 2. Extract train.zip into /kaggle/working\nwith zipfile.ZipFile(train_zip_path, 'r') as zip_ref:\n    zip_ref.extractall(\"/kaggle/working\")\n\n# After extraction, images are in /kaggle/working/train/\nprint(\"Total extracted files:\", len(os.listdir(train_dir)))\nprint(\"First 10 files:\", os.listdir(train_dir)[:10])\nprint(\"Last 10 files:\", os.listdir(train_dir)[-10:])\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:37:29.686735Z","iopub.execute_input":"2025-08-19T14:37:29.687339Z","iopub.status.idle":"2025-08-19T14:37:41.978559Z","shell.execute_reply.started":"2025-08-19T14:37:29.687316Z","shell.execute_reply":"2025-08-19T14:37:41.977785Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for root, dirs, files in os.walk(\"/kaggle/working\"):\n    level = root.replace(\"/kaggle/working\", \"\").count(os.sep)\n    indent = \" \" * 4 * level\n    print(f\"{indent}{os.path.basename(root)}/\")\n    subindent = \" \" * 4 * (level + 1)\n    for f in files[:10]:  # show up to 10 files per folder\n        print(f\"{subindent}{f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:37:41.979427Z","iopub.execute_input":"2025-08-19T14:37:41.979737Z","iopub.status.idle":"2025-08-19T14:37:42.005506Z","shell.execute_reply.started":"2025-08-19T14:37:41.979719Z","shell.execute_reply":"2025-08-19T14:37:42.004702Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_image_paths = []\ntrain_labels = []\n\nfor fname in os.listdir(train_dir):\n    fpath = os.path.join(train_dir, fname)\n    \n    if os.path.getsize(fpath) <= 0:\n        print(fname + \" has not enough pixels, seems corrupted, ignoring.\")\n        continue  # skip corrupted file\n    if \".jpg\" not in fpath:\n        print(\"not image: \", fname)\n        continue\n    if fname.startswith(\"cat\"):\n        train_labels.append(0)\n        train_image_paths.append(fpath)\n    elif fname.startswith(\"dog\"):\n        train_labels.append(1)\n        train_image_paths.append(fpath)\n\nprint(len(train_image_paths), len(train_labels))\nprint(\"Cats:\", train_labels.count(0))\nprint(\"Dogs:\", train_labels.count(1))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:37:42.007334Z","iopub.execute_input":"2025-08-19T14:37:42.007595Z","iopub.status.idle":"2025-08-19T14:37:42.158077Z","shell.execute_reply.started":"2025-08-19T14:37:42.007577Z","shell.execute_reply":"2025-08-19T14:37:42.157413Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# preprocessing and Convert to numpy arrays\ntrain_images = []\nfor path in train_image_paths:\n    img = cv2.imread(path)                      # read image (BGR)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # convert to RGB\n    img = cv2.resize(img, (150, 150))   # resize\n    train_images.append(img)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:37:42.158813Z","iopub.execute_input":"2025-08-19T14:37:42.159031Z","iopub.status.idle":"2025-08-19T14:38:24.612682Z","shell.execute_reply.started":"2025-08-19T14:37:42.159014Z","shell.execute_reply":"2025-08-19T14:38:24.612095Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_images = np.array(train_images, dtype=\"float32\")/255.0\ntrain_labels = np.array(train_labels, dtype=\"int32\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:24.613263Z","iopub.execute_input":"2025-08-19T14:38:24.613470Z","iopub.status.idle":"2025-08-19T14:38:28.131163Z","shell.execute_reply.started":"2025-08-19T14:38:24.613452Z","shell.execute_reply":"2025-08-19T14:38:28.130495Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nX_train, X_val, y_train, y_val = train_test_split(\n    train_images, train_labels, test_size=0.2, random_state=42, stratify=train_labels\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:28.131941Z","iopub.execute_input":"2025-08-19T14:38:28.132257Z","iopub.status.idle":"2025-08-19T14:38:30.221905Z","shell.execute_reply.started":"2025-08-19T14:38:28.132230Z","shell.execute_reply":"2025-08-19T14:38:30.220968Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# ---------------------------\n# Data Augmentation (Train)\n# ---------------------------\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,          # normalize\n    rotation_range=30,       # random rotation\n    width_shift_range=0.1,   # horizontal shift\n    height_shift_range=0.1,  # vertical shift\n    zoom_range = 0.2,        # zoom in\n    horizontal_flip=True     # random flip\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:30.222862Z","iopub.execute_input":"2025-08-19T14:38:30.223119Z","iopub.status.idle":"2025-08-19T14:38:30.289372Z","shell.execute_reply.started":"2025-08-19T14:38:30.223094Z","shell.execute_reply":"2025-08-19T14:38:30.288712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ---------------------------\n# Validation Data (No Augmentation, only rescale)\n# ---------------------------\nval_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:30.290054Z","iopub.execute_input":"2025-08-19T14:38:30.290282Z","iopub.status.idle":"2025-08-19T14:38:30.294194Z","shell.execute_reply.started":"2025-08-19T14:38:30.290265Z","shell.execute_reply":"2025-08-19T14:38:30.293384Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_datagen = ImageDataGenerator()\nval_datagen = ImageDataGenerator()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:30.296493Z","iopub.execute_input":"2025-08-19T14:38:30.296677Z","iopub.status.idle":"2025-08-19T14:38:30.312486Z","shell.execute_reply.started":"2025-08-19T14:38:30.296663Z","shell.execute_reply":"2025-08-19T14:38:30.311824Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_generator = train_datagen.flow(X_train, y_train, batch_size=32, shuffle=True)\nval_generator = val_datagen.flow(X_val, y_val, batch_size=32, shuffle=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:30.313096Z","iopub.execute_input":"2025-08-19T14:38:30.313269Z","iopub.status.idle":"2025-08-19T14:38:30.329666Z","shell.execute_reply.started":"2025-08-19T14:38:30.313255Z","shell.execute_reply":"2025-08-19T14:38:30.329029Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#checking images with its labels\n\nimport matplotlib.pyplot as plt\n\n# pick 16 random indices\nidx = np.random.choice(len(train_images), 16, replace=False)\n\nplt.figure(figsize=(10, 10))\nfor i, index in enumerate(idx):\n    plt.subplot(4, 4, i + 1)\n    plt.imshow(train_images[index].squeeze(), cmap=\"gray\")  # squeeze in case of (128,128,1)\n    plt.title(\"Dog\" if train_labels[index] == 1 else \"Cat\")\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:30.330344Z","iopub.execute_input":"2025-08-19T14:38:30.330527Z","iopub.status.idle":"2025-08-19T14:38:31.947585Z","shell.execute_reply.started":"2025-08-19T14:38:30.330514Z","shell.execute_reply":"2025-08-19T14:38:31.946559Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\n\n# ---------------------------\n# Build CNN model\n# ---------------------------\nmodel = Sequential([\n            Conv2D(16, (3, 3),activation='relu',input_shape=(150, 150, 3)),\n            MaxPooling2D(2, 2),\n            Conv2D(32, (3, 3), activation='relu'),\n            Conv2D(64, (3, 3), activation='relu'),\n            MaxPooling2D(2, 2),\n            Conv2D(128, (3, 3), activation='relu'),\n            Conv2D(256, (3, 3), activation='relu'),\n            MaxPooling2D(2, 2),\n            Flatten(),\n            Dense(128, activation='relu'),\n            Dense(256, activation='relu'),\n            Dropout(0.2),\n            Dense(64, activation='relu'),\n            Dense(1, activation='sigmoid')\n        ])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:31.948875Z","iopub.execute_input":"2025-08-19T14:38:31.949186Z","iopub.status.idle":"2025-08-19T14:38:34.166399Z","shell.execute_reply.started":"2025-08-19T14:38:31.949159Z","shell.execute_reply":"2025-08-19T14:38:34.165584Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#combiling model\nmodel.compile(\n    optimizer=Adam(learning_rate=0.0001),\n    loss='binary_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:34.167106Z","iopub.execute_input":"2025-08-19T14:38:34.167339Z","iopub.status.idle":"2025-08-19T14:38:34.180206Z","shell.execute_reply.started":"2025-08-19T14:38:34.167312Z","shell.execute_reply":"2025-08-19T14:38:34.179600Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ---------------------------\n# Early stopping\n# ---------------------------\nearly_stop = EarlyStopping(\n    monitor='val_loss',\n    patience=5,\n    restore_best_weights=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:34.180956Z","iopub.execute_input":"2025-08-19T14:38:34.181321Z","iopub.status.idle":"2025-08-19T14:38:34.190818Z","shell.execute_reply.started":"2025-08-19T14:38:34.181291Z","shell.execute_reply":"2025-08-19T14:38:34.190069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ---------------------------\n# Train the model\n# ---------------------------\nhistory = model.fit(\n    train_datagen.flow(train_images, train_labels, batch_size=16, shuffle=True),\n    validation_data=(X_val, y_val),   # (numpy arrays for validation set)\n    epochs=20,\n    callbacks=[early_stop]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:38:34.191732Z","iopub.execute_input":"2025-08-19T14:38:34.192246Z","iopub.status.idle":"2025-08-19T14:45:07.755323Z","shell.execute_reply.started":"2025-08-19T14:38:34.192227Z","shell.execute_reply":"2025-08-19T14:45:07.754627Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Plot accuracy\nplt.plot(history.history['accuracy'], label='Train Accuracy')\nplt.plot(history.history['val_accuracy'], label='Val Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:45:07.759853Z","iopub.execute_input":"2025-08-19T14:45:07.760269Z","iopub.status.idle":"2025-08-19T14:45:07.934879Z","shell.execute_reply.started":"2025-08-19T14:45:07.760248Z","shell.execute_reply":"2025-08-19T14:45:07.934075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot loss\nplt.plot(history.history['loss'], label='Train Loss')\nplt.plot(history.history['val_loss'], label='Val Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:45:07.935788Z","iopub.execute_input":"2025-08-19T14:45:07.936092Z","iopub.status.idle":"2025-08-19T14:45:08.106014Z","shell.execute_reply.started":"2025-08-19T14:45:07.936072Z","shell.execute_reply":"2025-08-19T14:45:08.105101Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_zip_path = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip\"\ntest_extract_path = \"working/\"\n\nwith zipfile.ZipFile(test_zip_path, 'r') as zip_ref:\n    zip_ref.extractall(test_extract_path)\n\nprint(\"Extracted to:\", test_extract_path)\nprint(os.listdir(\"working/\"))  # should show 'train' and 'test'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:46:43.694296Z","iopub.execute_input":"2025-08-19T14:46:43.695083Z","iopub.status.idle":"2025-08-19T14:46:48.730187Z","shell.execute_reply.started":"2025-08-19T14:46:43.695057Z","shell.execute_reply":"2025-08-19T14:46:48.729397Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_dir = \"working/test\"\nimg_size = (150, 150)  # same size used in training\n\n# Image generator (only rescaling, no augmentation for test)\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# Flow from directory (no labels since it's test data)\ntest_generator = test_datagen.flow_from_directory(\n    directory=\"working\",         # parent dir\n    classes=[\"test\"],            # only the test folder\n    target_size=(150, 150),      # use same size as training\n    batch_size=32,\n    class_mode=None,             # no labels\n    shuffle=False                # IMPORTANT to keep order\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:49:51.809654Z","iopub.execute_input":"2025-08-19T14:49:51.810524Z","iopub.status.idle":"2025-08-19T14:49:51.974240Z","shell.execute_reply.started":"2025-08-19T14:49:51.810496Z","shell.execute_reply":"2025-08-19T14:49:51.973631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Predict probabilities\npreds = model.predict(test_generator, verbose=1)\n\n# Flatten if needed\npreds = preds.ravel()\n\n# Extract ids from filenames\nids = [os.path.basename(f).split(\".\")[0] for f in test_generator.filenames]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:52:27.461276Z","iopub.execute_input":"2025-08-19T14:52:27.461582Z","iopub.status.idle":"2025-08-19T14:52:46.766716Z","shell.execute_reply.started":"2025-08-19T14:52:27.461558Z","shell.execute_reply":"2025-08-19T14:52:46.765815Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create dataframe\nsubmission = pd.DataFrame({\"id\": ids, \"label\": preds})\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T14:53:33.834352Z","iopub.execute_input":"2025-08-19T14:53:33.835195Z","iopub.status.idle":"2025-08-19T14:53:33.879702Z","shell.execute_reply.started":"2025-08-19T14:53:33.835142Z","shell.execute_reply":"2025-08-19T14:53:33.879103Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission[\"id\"] = submission[\"id\"].astype(int)  # make sure ids are int\nsubmission = submission.sort_values(\"id\")  # ensure correct order\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T15:00:00.155076Z","iopub.execute_input":"2025-08-19T15:00:00.155733Z","iopub.status.idle":"2025-08-19T15:00:00.186451Z","shell.execute_reply.started":"2025-08-19T15:00:00.155706Z","shell.execute_reply":"2025-08-19T15:00:00.185804Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(submission.head(10))\nprint(submission.tail(10))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-19T15:00:02.746423Z","iopub.execute_input":"2025-08-19T15:00:02.746686Z","iopub.status.idle":"2025-08-19T15:00:02.754896Z","shell.execute_reply.started":"2025-08-19T15:00:02.746667Z","shell.execute_reply":"2025-08-19T15:00:02.753933Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}