{"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":"# 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":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:29.054459Z","iopub.execute_input":"2025-09-04T12:40:29.054742Z","iopub.status.idle":"2025-09-04T12:40:30.697646Z","shell.execute_reply.started":"2025-09-04T12:40:29.054714Z","shell.execute_reply":"2025-09-04T12:40:30.696994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport zipfile\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom random import shuffle\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report\nfrom tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense,Dropout\nfrom tensorflow.keras.optimizers import Adam\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:30.698909Z","iopub.execute_input":"2025-09-04T12:40:30.699305Z","iopub.status.idle":"2025-09-04T12:40:44.194736Z","shell.execute_reply.started":"2025-09-04T12:40:30.699285Z","shell.execute_reply":"2025-09-04T12:40:44.194146Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TEST_SIZE = 0.2\nRANDOM_STATE = 42\nBATCH_SIZE = 32\nNO_EPOCHS = 20\nNUM_CLASSES = 2\nSAMPLE_SIZE = 20000\nIMG_SIZE = 128\n\nTRAIN_FOLDER = \"/kaggle/working/train\"\nTEST_FOLDER  = \"/kaggle/working/test\"\nPATH_TRAIN = '/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip'\nPATH_TEST  = '/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip'\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:44.195556Z","iopub.execute_input":"2025-09-04T12:40:44.196407Z","iopub.status.idle":"2025-09-04T12:40:44.200173Z","shell.execute_reply.started":"2025-09-04T12:40:44.196379Z","shell.execute_reply":"2025-09-04T12:40:44.199407Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\nwith zipfile.ZipFile(PATH_TRAIN, 'r') as zip_ref:\n    zip_ref.extractall(TRAIN_FOLDER)\nwith zipfile.ZipFile(PATH_TEST, 'r') as zip_ref:\n    zip_ref.extractall(TEST_FOLDER)\n\ntrain_inner_folder = os.path.join(TRAIN_FOLDER, 'train')\ntest_inner_folder = os.path.join(TEST_FOLDER, 'test')\n\ntrain_image_list = os.listdir(train_inner_folder)[:SAMPLE_SIZE]\ntest_image_list = os.listdir(test_inner_folder)\n\nprint(\"Found train images:\", len(train_image_list))\nprint(\"Using SAMPLE_SIZE:\", len(train_image_list))\nprint(\"Found test images:\", len(test_image_list))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:44.201676Z","iopub.execute_input":"2025-09-04T12:40:44.201954Z","iopub.status.idle":"2025-09-04T12:40:58.171553Z","shell.execute_reply.started":"2025-09-04T12:40:44.201914Z","shell.execute_reply":"2025-09-04T12:40:58.170950Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def label_pet_image_one_hot_encoder(img_filename):\n    pet = img_filename.split('.')[0]\n    if pet == 'cat': return [1,0]\n    elif pet == 'dog': return [0,1]\n    return [1,0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:58.172357Z","iopub.execute_input":"2025-09-04T12:40:58.172636Z","iopub.status.idle":"2025-09-04T12:40:58.176495Z","shell.execute_reply.started":"2025-09-04T12:40:58.172613Z","shell.execute_reply":"2025-09-04T12:40:58.175978Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def process_data(data_image_list, DATA_FOLDER, isTrain=True):\n    data_df = []\n    for img in data_image_list:\n        path = os.path.join(DATA_FOLDER, img)\n        if isTrain:\n            label = label_pet_image_one_hot_encoder(img)\n        else:\n            label = img\n        img_array = cv2.imread(path)\n        if img_array is None:\n            continue\n        img_array = cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB)\n        img_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))\n        data_df.append([np.array(img_array), np.array(label)])\n    shuffle(data_df)\n    return data_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:58.177241Z","iopub.execute_input":"2025-09-04T12:40:58.177575Z","iopub.status.idle":"2025-09-04T12:40:58.401666Z","shell.execute_reply.started":"2025-09-04T12:40:58.177549Z","shell.execute_reply":"2025-09-04T12:40:58.400806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_image_list_count(data_image_list):\n    labels = []\n    for img in data_image_list:\n        labels.append(img.split('.')[0])   \n    plt.figure(figsize=(6,4))\n    sns.countplot(x=labels)\n    plt.title('Cats and Dogs')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:58.402474Z","iopub.execute_input":"2025-09-04T12:40:58.402765Z","iopub.status.idle":"2025-09-04T12:40:58.415210Z","shell.execute_reply.started":"2025-09-04T12:40:58.402733Z","shell.execute_reply":"2025-09-04T12:40:58.414590Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_image_list_count(train_image_list)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:58.416028Z","iopub.execute_input":"2025-09-04T12:40:58.416400Z","iopub.status.idle":"2025-09-04T12:40:58.679731Z","shell.execute_reply.started":"2025-09-04T12:40:58.416354Z","shell.execute_reply":"2025-09-04T12:40:58.679036Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = process_data(train_image_list, train_inner_folder, True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:40:58.680411Z","iopub.execute_input":"2025-09-04T12:40:58.680615Z","iopub.status.idle":"2025-09-04T12:41:27.717886Z","shell.execute_reply.started":"2025-09-04T12:40:58.680599Z","shell.execute_reply":"2025-09-04T12:41:27.717224Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_images(data, isTest=False):\n    f, ax = plt.subplots(5,5, figsize=(12,12))\n    for i,item in enumerate(data[:25]):\n        img_data = item[0]\n        img_num = item[1]\n        if isTest:\n            str_label = \"None\"\n        else:\n            label = np.argmax(img_num)\n            str_label = \"Dog\" if label == 1 else \"Cat\"\n        ax[i//5, i%5].imshow(img_data.astype(np.uint8))\n        ax[i//5, i%5].axis('off')\n        ax[i//5, i%5].set_title(\"Label: {}\".format(str_label))\n    plt.tight_layout()\n    plt.show()\n\nshow_images(train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:41:27.720383Z","iopub.execute_input":"2025-09-04T12:41:27.720582Z","iopub.status.idle":"2025-09-04T12:41:29.738581Z","shell.execute_reply.started":"2025-09-04T12:41:27.720567Z","shell.execute_reply":"2025-09-04T12:41:29.737586Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test = process_data(test_image_list, test_inner_folder, False)\nshow_images(test, True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:41:29.739724Z","iopub.execute_input":"2025-09-04T12:41:29.740105Z","iopub.status.idle":"2025-09-04T12:41:50.157606Z","shell.execute_reply.started":"2025-09-04T12:41:29.740074Z","shell.execute_reply":"2025-09-04T12:41:50.156393Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = np.array([i[0] for i in train]).reshape(-1, IMG_SIZE, IMG_SIZE, 3)\ny = np.array([i[1] for i in train])\nprint(\"X shape:\", X.shape, \"y shape:\", y.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:41:50.158737Z","iopub.execute_input":"2025-09-04T12:41:50.159103Z","iopub.status.idle":"2025-09-04T12:41:50.499552Z","shell.execute_reply.started":"2025-09-04T12:41:50.159073Z","shell.execute_reply":"2025-09-04T12:41:50.498708Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base = ResNet50(\n    include_top=False,\n    weights='imagenet',\n    input_shape=(IMG_SIZE, IMG_SIZE, 3),\n    pooling='avg'\n)\nfor layer in base.layers[:-10]:\n    layer.trainable = False\nfor layer in base.layers[-10:]:\n    layer.trainable = True\n\n\nmodel = Sequential()\nmodel.add(base)\nmodel.add(Dropout(0.5))\nmodel.add(Dense(256, activation='relu'))\nmodel.add(Dropout(0.3))\nmodel.add(Dense(NUM_CLASSES, activation='softmax'))\n\nmodel.compile(optimizer=Adam(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:41:50.500495Z","iopub.execute_input":"2025-09-04T12:41:50.500756Z","iopub.status.idle":"2025-09-04T12:41:59.268269Z","shell.execute_reply.started":"2025-09-04T12:41:50.500728Z","shell.execute_reply":"2025-09-04T12:41:59.267713Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\n\ndatagen = ImageDataGenerator(\n    rotation_range=40,\n    shear_range=0.2,\n    zoom_range=0.3,\n    horizontal_flip=True,\n    fill_mode='nearest',\n    validation_split=0.2\n)\n\ntrain_generator = datagen.flow(X, y, batch_size=BATCH_SIZE, subset='training')\nval_generator = datagen.flow(X, y, batch_size=BATCH_SIZE, subset='validation')\n\n\nearly_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\n\ntrain_model = model.fit(\n    train_generator,\n    epochs=NO_EPOCHS,\n    validation_data=val_generator,\n    verbose=1,\n    callbacks=[early_stop]\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:41:59.268952Z","iopub.execute_input":"2025-09-04T12:41:59.269189Z","iopub.status.idle":"2025-09-04T12:59:37.489982Z","shell.execute_reply.started":"2025-09-04T12:41:59.269172Z","shell.execute_reply":"2025-09-04T12:59:37.489299Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_accuracy_and_loss(train_model):\n    hist = train_model.history\n    acc = hist['accuracy'] if 'accuracy' in hist else hist.get('acc', [])\n    val_acc = hist['val_accuracy'] if 'val_accuracy' in hist else hist.get('val_acc', [])\n    loss = hist['loss']\n    val_loss = hist['val_loss']\n    epochs = range(len(acc))\n    f, ax = plt.subplots(1,2, figsize=(14,6))\n    ax[0].plot(epochs, acc, 'g', label='Training accuracy')\n    ax[0].plot(epochs, val_acc, 'r', label='Validation accuracy')\n    ax[0].set_title('Training and validation accuracy')\n    ax[0].legend()\n    ax[1].plot(epochs, loss, 'g', label='Training loss')\n    ax[1].plot(epochs, val_loss, 'r', label='Validation loss')\n    ax[1].set_title('Training and validation loss')\n    ax[1].legend()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:59:37.495528Z","iopub.execute_input":"2025-09-04T12:59:37.495753Z","iopub.status.idle":"2025-09-04T12:59:37.501424Z","shell.execute_reply.started":"2025-09-04T12:59:37.495737Z","shell.execute_reply":"2025-09-04T12:59:37.500689Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_accuracy_and_loss(train_model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:59:37.502276Z","iopub.execute_input":"2025-09-04T12:59:37.503036Z","iopub.status.idle":"2025-09-04T12:59:37.836827Z","shell.execute_reply.started":"2025-09-04T12:59:37.503010Z","shell.execute_reply":"2025-09-04T12:59:37.836076Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = np.array([i[0] for i in test]).reshape(-1, IMG_SIZE, IMG_SIZE, 3)\ntest_filenames = [str(i[1]) for i in test]\n\n\ny_pred_proba = model.predict(X_test)\npredicted_classes = np.argmax(y_pred_proba, axis=1)\n\ntest_ids = [int(os.path.splitext(f)[0]) for f in test_filenames]\n\nsubmission = pd.DataFrame({\n    'id': test_ids,\n    'label': predicted_classes\n})\n\nsubmission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:59:37.837754Z","iopub.execute_input":"2025-09-04T12:59:37.838324Z","iopub.status.idle":"2025-09-04T12:59:56.955443Z","shell.execute_reply.started":"2025-09-04T12:59:37.838298Z","shell.execute_reply":"2025-09-04T12:59:56.954838Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:59:56.956161Z","iopub.execute_input":"2025-09-04T12:59:56.956405Z","iopub.status.idle":"2025-09-04T12:59:56.972294Z","shell.execute_reply.started":"2025-09-04T12:59:56.956384Z","shell.execute_reply":"2025-09-04T12:59:56.971657Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T12:59:56.973113Z","iopub.execute_input":"2025-09-04T12:59:56.973371Z","iopub.status.idle":"2025-09-04T12:59:56.978319Z","shell.execute_reply.started":"2025-09-04T12:59:56.973343Z","shell.execute_reply":"2025-09-04T12:59:56.977586Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}