{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","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":30822,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport shutil\nimport zipfile\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\nfrom tensorflow.keras.metrics import BinaryCrossentropy\nimport gc\nfrom tensorflow.keras.backend import clear_session\n\ndef clear_memory():\n    clear_session()\n    gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:23:52.203912Z","iopub.execute_input":"2025-01-14T02:23:52.204208Z","iopub.status.idle":"2025-01-14T02:23:59.960080Z","shell.execute_reply.started":"2025-01-14T02:23:52.204183Z","shell.execute_reply":"2025-01-14T02:23:59.959371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndata_base_dir = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition\"\ntrain_zip_path = os.path.join(data_base_dir, \"train.zip\")\ntest_zip_path = os.path.join(data_base_dir, \"test.zip\")\n\ntrain_dir = \"/kaggle/working/train\"\ntest_dir = \"/kaggle/working/test\"\n\nif not os.path.exists(train_dir):\n    with zipfile.ZipFile(train_zip_path, 'r') as zip_ref:\n        zip_ref.extractall(\"/kaggle/working\")\n\nif not os.path.exists(test_dir):\n    with zipfile.ZipFile(test_zip_path, 'r') as zip_ref:\n        zip_ref.extractall(\"/kaggle/working\")\n\n# Check the decompressed contents\n#print(\"Train directory contents:\", os.listdir(train_dir))\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:23:59.961132Z","iopub.execute_input":"2025-01-14T02:23:59.961726Z","iopub.status.idle":"2025-01-14T02:24:14.458255Z","shell.execute_reply.started":"2025-01-14T02:23:59.961694Z","shell.execute_reply":"2025-01-14T02:24:14.457540Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create cats and dogs subfolders\ncats_dir = os.path.join(train_dir, 'cats')\ndogs_dir = os.path.join(train_dir, 'dogs')\n\nos.makedirs(cats_dir, exist_ok=True)\nos.makedirs(dogs_dir, exist_ok=True)\n\nfor filename in os.listdir(train_dir):\n    file_path = os.path.join(train_dir, filename)\n    if filename.endswith('.jpg'): \n        if 'cat' in filename.lower():\n            shutil.move(file_path, os.path.join(cats_dir, filename))\n        elif 'dog' in filename.lower():\n            shutil.move(file_path, os.path.join(dogs_dir, filename))\n\n# Ensure folder structure\n#print(\"Cats directory contents:\", os.listdir(cats_dir))\n#print(\"Dogs directory contents:\", os.listdir(dogs_dir))\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:14.459525Z","iopub.execute_input":"2025-01-14T02:24:14.459746Z","iopub.status.idle":"2025-01-14T02:24:15.314098Z","shell.execute_reply.started":"2025-01-14T02:24:14.459727Z","shell.execute_reply":"2025-01-14T02:24:15.313157Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{}},{"cell_type":"code","source":"\nbatch_size = 16\nimg_size = (224, 224)\n\ndatagen = ImageDataGenerator(\n    rescale=1.0 / 255,\n    validation_split=0.2  \n)\n\ntrain_generator = datagen.flow_from_directory(\n    train_dir,\n    target_size=img_size,\n    batch_size=batch_size,\n    class_mode='binary',\n    subset='training'\n)\n\nval_generator = datagen.flow_from_directory(\n    train_dir,\n    target_size=img_size,\n    batch_size=batch_size,\n    class_mode='binary',\n    subset='validation'\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:15.315546Z","iopub.execute_input":"2025-01-14T02:24:15.315812Z","iopub.status.idle":"2025-01-14T02:24:15.672250Z","shell.execute_reply.started":"2025-01-14T02:24:15.315790Z","shell.execute_reply":"2025-01-14T02:24:15.671375Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"\n_input = Input((224, 224, 3))  # The input is an RGB image\n\n# Convolution block\nconv1 = Conv2D(64, (3, 3), padding=\"same\", activation=\"relu\")(_input)\nconv2 = Conv2D(64, (3, 3), padding=\"same\", activation=\"relu\")(conv1)\npool1 = MaxPooling2D((2, 2))(conv2)\n\nconv3 = Conv2D(128, (3, 3), padding=\"same\", activation=\"relu\")(pool1)\nconv4 = Conv2D(128, (3, 3), padding=\"same\", activation=\"relu\")(conv3)\npool2 = MaxPooling2D((2, 2))(conv4)\n\nconv5 = Conv2D(256, (3, 3), padding=\"same\", activation=\"relu\")(pool2)\nconv6 = Conv2D(256, (3, 3), padding=\"same\", activation=\"relu\")(conv5)\npool3 = MaxPooling2D((2, 2))(conv6)\n\nconv7 = Conv2D(512, (3, 3), padding=\"same\", activation=\"relu\")(pool3)\nconv8 = Conv2D(512, (3, 3), padding=\"same\", activation=\"relu\")(conv7)\npool4 = MaxPooling2D((2, 2))(conv8)\n\nconv9 = Conv2D(512, (3, 3), padding=\"same\", activation=\"relu\")(pool4)\nconv10 = Conv2D(512, (3, 3), padding=\"same\", activation=\"relu\")(conv9)\npool5 = MaxPooling2D((2, 2))(conv10)\n\n# Fully connected layer\nflat = Flatten()(pool5)\ndense1 = Dense(4096, activation=\"relu\")(flat)\ndropout1 = Dropout(0.5)(dense1)\ndense2 = Dense(4096, activation=\"relu\")(dropout1)\ndropout2 = Dropout(0.5)(dense2)\n\n# Output layer (single node for binary classification)\noutput = Dense(1, activation=\"sigmoid\")(dropout2)\n\nvgg16_model = Model(inputs=_input, outputs=output)\nvgg16_model.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:15.673179Z","iopub.execute_input":"2025-01-14T02:24:15.673531Z","iopub.status.idle":"2025-01-14T02:24:16.504405Z","shell.execute_reply.started":"2025-01-14T02:24:15.673497Z","shell.execute_reply":"2025-01-14T02:24:16.503478Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"vgg16_model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:16.505382Z","iopub.execute_input":"2025-01-14T02:24:16.505714Z","iopub.status.idle":"2025-01-14T02:24:16.537379Z","shell.execute_reply.started":"2025-01-14T02:24:16.505683Z","shell.execute_reply":"2025-01-14T02:24:16.536037Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def log_loss(y_true, y_pred):\n    y_pred = tf.squeeze(y_pred, axis=-1)  \n    return tf.keras.losses.binary_crossentropy(y_true, y_pred)\n\nvgg16_model.compile(\n    optimizer=Adam(learning_rate=0.0001),\n    loss='binary_crossentropy',\n    metrics=['accuracy', log_loss]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:16.539037Z","iopub.execute_input":"2025-01-14T02:24:16.539379Z","iopub.status.idle":"2025-01-14T02:24:16.548715Z","shell.execute_reply.started":"2025-01-14T02:24:16.539347Z","shell.execute_reply":"2025-01-14T02:24:16.547526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"checkpoint = ModelCheckpoint(\"vgg16_model.keras\", monitor=\"val_loss\", save_best_only=True)\nearly_stop = EarlyStopping(monitor=\"val_loss\", patience=5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:16.551803Z","iopub.execute_input":"2025-01-14T02:24:16.552131Z","iopub.status.idle":"2025-01-14T02:24:16.566804Z","shell.execute_reply.started":"2025-01-14T02:24:16.552101Z","shell.execute_reply":"2025-01-14T02:24:16.565751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nepochs = 10\n\nhistory = vgg16_model.fit(\n    train_generator,\n    steps_per_epoch=train_generator.samples // train_generator.batch_size,\n    validation_data=val_generator,\n    validation_steps=val_generator.samples // val_generator.batch_size,\n    epochs=epochs,\n    callbacks=[checkpoint, early_stop]\n)\nclear_memory()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:24:16.568158Z","iopub.execute_input":"2025-01-14T02:24:16.568493Z","iopub.status.idle":"2025-01-14T02:37:37.060203Z","shell.execute_reply.started":"2025-01-14T02:24:16.568460Z","shell.execute_reply":"2025-01-14T02:37:37.059533Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Visual result","metadata":{}},{"cell_type":"code","source":"def plot_history(history):\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs = range(len(acc))\n\n    plt.figure()\n    plt.plot(epochs, acc, label='Training Accuracy')\n    plt.plot(epochs, val_acc, label='Validation Accuracy')\n    plt.title('Training and Validation Accuracy')\n    plt.legend()\n\n    plt.figure()\n    plt.plot(epochs, loss, label='Training Loss')\n    plt.plot(epochs, val_loss, label='Validation Loss')\n    plt.title('Training and Validation Loss')\n    plt.legend()\n\n    plt.show()\n\nplot_history(history)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:37:37.064850Z","iopub.execute_input":"2025-01-14T02:37:37.065181Z","iopub.status.idle":"2025-01-14T02:37:37.508775Z","shell.execute_reply.started":"2025-01-14T02:37:37.065161Z","shell.execute_reply":"2025-01-14T02:37:37.508057Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# prediction","metadata":{}},{"cell_type":"code","source":"def prepare_test_images(test_dir, img_size=(224, 224)):\n    filenames = os.listdir(test_dir)\n    images = []\n    for filename in filenames:\n        img_path = os.path.join(test_dir, filename)\n        img = load_img(img_path, target_size=img_size)\n        img = img_to_array(img)\n        img = np.expand_dims(img, axis=0) \n        img = img / 255.0  \n        images.append(img)\n    return filenames, np.vstack(images)\n\ntest_filenames, test_images = prepare_test_images(test_dir, img_size=(224, 224))\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:37:37.509430Z","iopub.execute_input":"2025-01-14T02:37:37.509676Z","iopub.status.idle":"2025-01-14T02:38:29.484041Z","shell.execute_reply.started":"2025-01-14T02:37:37.509655Z","shell.execute_reply":"2025-01-14T02:38:29.483109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = vgg16_model.predict(test_images, batch_size=batch_size)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:38:29.486143Z","iopub.execute_input":"2025-01-14T02:38:29.486427Z","iopub.status.idle":"2025-01-14T02:39:27.217926Z","shell.execute_reply.started":"2025-01-14T02:38:29.486405Z","shell.execute_reply":"2025-01-14T02:39:27.216994Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"submission_df = pd.DataFrame({\n    'id': [filename.split('.')[0] for filename in test_filenames],  \n    'label': predictions.flatten()                                 \n})\n\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:49:48.738663Z","iopub.execute_input":"2025-01-14T02:49:48.739000Z","iopub.status.idle":"2025-01-14T02:49:48.764134Z","shell.execute_reply.started":"2025-01-14T02:49:48.738973Z","shell.execute_reply":"2025-01-14T02:49:48.763532Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T02:49:55.597088Z","iopub.execute_input":"2025-01-14T02:49:55.597407Z","iopub.status.idle":"2025-01-14T02:49:55.604954Z","shell.execute_reply.started":"2025-01-14T02:49:55.597380Z","shell.execute_reply":"2025-01-14T02:49:55.604226Z"}},"outputs":[],"execution_count":null}]}