{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.13","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":5441,"databundleVersionId":38425},{"sourceType":"datasetVersion","sourceId":872462,"datasetId":464180,"databundleVersionId":899123},{"sourceType":"datasetVersion","sourceId":8821206,"datasetId":5306782,"databundleVersionId":8979353}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os, cv2\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom keras.applications.resnet50 import ResNet50\nfrom keras import Input, Model, Sequential\nfrom keras.layers import Dense, Flatten, BatchNormalization, GlobalAveragePooling2D\nfrom keras.optimizers import Adam\nfrom keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint\nfrom keras.models import load_model","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:44:03.242062Z","iopub.execute_input":"2024-06-30T00:44:03.242405Z","iopub.status.idle":"2024-06-30T00:44:03.248864Z","shell.execute_reply.started":"2024-06-30T00:44:03.242378Z","shell.execute_reply":"2024-06-30T00:44:03.247894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Move files to a structure","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:04:52.311295Z","iopub.execute_input":"2024-06-30T00:04:52.311666Z","iopub.status.idle":"2024-06-30T00:04:52.316141Z","shell.execute_reply.started":"2024-06-30T00:04:52.311636Z","shell.execute_reply":"2024-06-30T00:04:52.315062Z"}}},{"cell_type":"code","source":"import zipfile\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip', 'r') as z:\n    z.extractall('.')\n\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip', 'r') as z:\n    z.extractall('.')","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:38.757144Z","iopub.execute_input":"2024-06-30T00:03:38.757452Z","iopub.status.idle":"2024-06-30T00:03:53.575982Z","shell.execute_reply.started":"2024-06-30T00:03:38.757428Z","shell.execute_reply":"2024-06-30T00:03:53.575154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.listdir('.')","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:53.577375Z","iopub.execute_input":"2024-06-30T00:03:53.577668Z","iopub.status.idle":"2024-06-30T00:03:53.589139Z","shell.execute_reply.started":"2024-06-30T00:03:53.577643Z","shell.execute_reply":"2024-06-30T00:03:53.588451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Make training set","metadata":{}},{"cell_type":"code","source":"%mkdir \"train/dog\"\n%mkdir \"train/cat\"","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:53.590143Z","iopub.execute_input":"2024-06-30T00:03:53.590404Z","iopub.status.idle":"2024-06-30T00:03:55.511056Z","shell.execute_reply.started":"2024-06-30T00:03:53.590382Z","shell.execute_reply":"2024-06-30T00:03:55.509883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# file format: dog.1.jpg\nfor dirpath, dirnames, filenames in os.walk('train'):\n    if len(dirnames) == 0:\n        continue\n    for file in filenames:\n        category = file.split('.')[0]\n        os.rename(f\"{dirpath}/{file}\", f\"{dirpath}/{category}/{file}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:55.513666Z","iopub.execute_input":"2024-06-30T00:03:55.513969Z","iopub.status.idle":"2024-06-30T00:03:56.146662Z","shell.execute_reply.started":"2024-06-30T00:03:55.513941Z","shell.execute_reply":"2024-06-30T00:03:56.145879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dog_filenames = list(os.listdir('train/dog'))\ncat_filenames = list(os.listdir('train/cat'))","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:56.147696Z","iopub.execute_input":"2024-06-30T00:03:56.147948Z","iopub.status.idle":"2024-06-30T00:03:56.166242Z","shell.execute_reply.started":"2024-06-30T00:03:56.147926Z","shell.execute_reply":"2024-06-30T00:03:56.165518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Make validation set","metadata":{}},{"cell_type":"code","source":"%mkdir 'valid'\n%mkdir 'valid/dog'\n%mkdir 'valid/cat'","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:56.167152Z","iopub.execute_input":"2024-06-30T00:03:56.167389Z","iopub.status.idle":"2024-06-30T00:03:59.017231Z","shell.execute_reply.started":"2024-06-30T00:03:56.167368Z","shell.execute_reply":"2024-06-30T00:03:59.016046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\n\n# Use 10% for validation\n# If not yet make the valid set\nif len(os.listdir('valid/dog')) < 1:\n    for file in random.sample(dog_filenames, k = int(len(dog_filenames) * 0.1)):\n        os.rename(f\"train/dog/{file}\", f\"valid/dog/{file}\")\n\n        \nif len(os.listdir('valid/cat')) < 1:\n    for file in random.sample(cat_filenames, k = int(len(cat_filenames) * 0.1)):\n        os.rename(f\"train/cat/{file}\", f\"valid/cat/{file}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:03:59.018752Z","iopub.execute_input":"2024-06-30T00:03:59.019061Z","iopub.status.idle":"2024-06-30T00:03:59.086907Z","shell.execute_reply.started":"2024-06-30T00:03:59.019032Z","shell.execute_reply":"2024-06-30T00:03:59.086144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transfer learning with ResNet50\nWe will use a CNN pre-trained on the Imagenet challenge and append a new \"head\" to it. \nWe will \"freeze\" the convolutional layers in order to only learn the weights of our new head.","metadata":{}},{"cell_type":"code","source":"WEIGHT_PATH = '/kaggle/input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'\nIMG_SIZE = (300, 300)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:26:17.923219Z","iopub.execute_input":"2024-06-30T00:26:17.923606Z","iopub.status.idle":"2024-06-30T00:26:17.928164Z","shell.execute_reply.started":"2024-06-30T00:26:17.923578Z","shell.execute_reply":"2024-06-30T00:26:17.927147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resnet_body = ResNet50(include_top=False, weights=WEIGHT_PATH, input_shape=IMG_SIZE + (3,))\nfor layer in resnet_body.layers:\n    layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:27:22.695652Z","iopub.execute_input":"2024-06-30T00:27:22.695920Z","iopub.status.idle":"2024-06-30T00:27:24.635151Z","shell.execute_reply.started":"2024-06-30T00:27:22.695897Z","shell.execute_reply":"2024-06-30T00:27:24.634358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = resnet_body.output\nX = BatchNormalization()(X)\nX = GlobalAveragePooling2D()(X)\nX = Dense(2, activation='softmax')(X)\n\nmodel = Model(resnet_body.input, X)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:32:57.478703Z","iopub.execute_input":"2024-06-30T00:32:57.479052Z","iopub.status.idle":"2024-06-30T00:32:57.529122Z","shell.execute_reply.started":"2024-06-30T00:32:57.479024Z","shell.execute_reply":"2024-06-30T00:32:57.528419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:06:00.937748Z","iopub.execute_input":"2024-06-30T01:06:00.938135Z","iopub.status.idle":"2024-06-30T01:06:01.188876Z","shell.execute_reply.started":"2024-06-30T01:06:00.938105Z","shell.execute_reply":"2024-06-30T01:06:01.187920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train / Val generators with augmentation","metadata":{}},{"cell_type":"code","source":"aug_gen = tf.keras.preprocessing.image.ImageDataGenerator(\n    horizontal_flip=True, \n    zoom_range=0.05,\n    fill_mode=\"constant\",\n    channel_shift_range=10,\n    rotation_range=5,\n    width_shift_range=0.05,\n    height_shift_range=0.05\n)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:34:47.470145Z","iopub.execute_input":"2024-06-30T00:34:47.470987Z","iopub.status.idle":"2024-06-30T00:34:47.501766Z","shell.execute_reply.started":"2024-06-30T00:34:47.470952Z","shell.execute_reply":"2024-06-30T00:34:47.501003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32\n\ntrain_batches = aug_gen.flow_from_directory(\n    directory=r\"./train/\",\n    target_size=IMG_SIZE,\n    color_mode=\"rgb\",\n    batch_size=BATCH_SIZE,\n    class_mode=\"categorical\",\n    shuffle=True,\n    seed=88\n)\n\nval_batches = train_batches = aug_gen.flow_from_directory(\n    directory=r\"./valid/\",\n    target_size=IMG_SIZE,\n    color_mode=\"rgb\",\n    batch_size=BATCH_SIZE,\n    class_mode=\"categorical\",\n    shuffle=True,\n    seed=88\n)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:40:22.824489Z","iopub.execute_input":"2024-06-30T00:40:22.825301Z","iopub.status.idle":"2024-06-30T00:40:23.982980Z","shell.execute_reply.started":"2024-06-30T00:40:22.825270Z","shell.execute_reply":"2024-06-30T00:40:23.982158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_batches.class_indices.keys()","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:42:21.142883Z","iopub.execute_input":"2024-06-30T00:42:21.143599Z","iopub.status.idle":"2024-06-30T00:42:21.148977Z","shell.execute_reply.started":"2024-06-30T00:42:21.143569Z","shell.execute_reply":"2024-06-30T00:42:21.148099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Dog is the second index","metadata":{}},{"cell_type":"code","source":"checkpoint = ModelCheckpoint(\"full_model.weights.h5\", save_best_only=True, save_weights_only=True)\nmodel.compile(Adam(), \"categorical_crossentropy\", metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:55:54.754148Z","iopub.execute_input":"2024-06-30T00:55:54.754529Z","iopub.status.idle":"2024-06-30T00:55:54.764725Z","shell.execute_reply.started":"2024-06-30T00:55:54.754487Z","shell.execute_reply":"2024-06-30T00:55:54.763843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit(\n    x=train_batches,\n    validation_data=val_batches,\n    epochs=5,\n    callbacks=[checkpoint],\n    verbose=1\n)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T00:55:58.268313Z","iopub.execute_input":"2024-06-30T00:55:58.269158Z","iopub.status.idle":"2024-06-30T01:05:27.596376Z","shell.execute_reply.started":"2024-06-30T00:55:58.269126Z","shell.execute_reply":"2024-06-30T01:05:27.595538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10,10))\n\nplt.subplot(1,2,1)\nplt.plot(model.history.history['loss'], label='Train loss')\nplt.plot(model.history.history['val_loss'], label='Val loss')\nplt.legend()\nplt.title('Loss')\n\nplt.subplot(1,2,2)\nplt.plot(model.history.history['accuracy'], label='Train accu')\nplt.plot(model.history.history['val_accuracy'], label='Val accu')\nplt.legend()\nplt.title('Accuracy')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:09:43.933732Z","iopub.execute_input":"2024-06-30T01:09:43.934441Z","iopub.status.idle":"2024-06-30T01:09:44.202639Z","shell.execute_reply.started":"2024-06-30T01:09:43.934407Z","shell.execute_reply":"2024-06-30T01:09:44.201416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(val_batches)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:07:09.361978Z","iopub.execute_input":"2024-06-30T01:07:09.362345Z","iopub.status.idle":"2024-06-30T01:07:37.089124Z","shell.execute_reply.started":"2024-06-30T01:07:09.362313Z","shell.execute_reply":"2024-06-30T01:07:37.088316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = tf.keras.preprocessing.image_dataset_from_directory(\n    directory='test',\n    labels= None,\n    label_mode= None,\n    class_names=None,\n    color_mode='rgb',\n    batch_size=1, \n    image_size= IMG_SIZE, \n    shuffle=False)\ntest_dataset","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:11:21.857846Z","iopub.execute_input":"2024-06-30T01:11:21.858474Z","iopub.status.idle":"2024-06-30T01:11:22.549223Z","shell.execute_reply.started":"2024-06-30T01:11:21.858438Z","shell.execute_reply":"2024-06-30T01:11:22.548294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(test_dataset)\npredictions","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:11:37.533581Z","iopub.execute_input":"2024-06-30T01:11:37.533964Z","iopub.status.idle":"2024-06-30T01:13:14.988605Z","shell.execute_reply.started":"2024-06-30T01:11:37.533933Z","shell.execute_reply":"2024-06-30T01:13:14.987562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(15, 15))\n\nfor i in range(25):\n    index = np.random.randint(0, len(test_dataset))\n    pred = predictions[index].argmax()\n    \n    img = cv2.imread(test_dataset.file_paths[index])\n    img = cv2.resize(img, IMG_SIZE)\n    \n    plt.subplot(5, 5, i + 1)\n    plt.imshow(img)\n    plt.axis('off')\n    title = \"Dog\" if pred == 1 else \"Cat\"\n    plt.title(title)\n    \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:15:09.059997Z","iopub.execute_input":"2024-06-30T01:15:09.060841Z","iopub.status.idle":"2024-06-30T01:15:11.507832Z","shell.execute_reply.started":"2024-06-30T01:15:09.060810Z","shell.execute_reply":"2024-06-30T01:15:11.506428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subm = pd.read_csv(\"/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:16:08.047988Z","iopub.execute_input":"2024-06-30T01:16:08.048625Z","iopub.status.idle":"2024-06-30T01:16:08.068375Z","shell.execute_reply.started":"2024-06-30T01:16:08.048592Z","shell.execute_reply":"2024-06-30T01:16:08.067655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids = [int(x.split(\"/\")[-1].split(\".\")[0]) for x in test_dataset.file_paths]","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:16:44.463932Z","iopub.execute_input":"2024-06-30T01:16:44.464288Z","iopub.status.idle":"2024-06-30T01:16:44.478283Z","shell.execute_reply.started":"2024-06-30T01:16:44.464258Z","shell.execute_reply":"2024-06-30T01:16:44.477326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(len(ids)):\n    subm.loc[subm.id == ids[i], \"label\"] = np.clip(predictions[:,1],0.0125,0.9875)[i]","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:21:10.112483Z","iopub.execute_input":"2024-06-30T01:21:10.113154Z","iopub.status.idle":"2024-06-30T01:21:15.936691Z","shell.execute_reply.started":"2024-06-30T01:21:10.113122Z","shell.execute_reply":"2024-06-30T01:21:15.935686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subm.to_csv(\"submission_clip.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:21:20.944709Z","iopub.execute_input":"2024-06-30T01:21:20.945420Z","iopub.status.idle":"2024-06-30T01:21:20.985539Z","shell.execute_reply.started":"2024-06-30T01:21:20.945384Z","shell.execute_reply":"2024-06-30T01:21:20.984717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"full_model.h5\")","metadata":{"execution":{"iopub.status.busy":"2024-06-30T01:23:33.794841Z","iopub.execute_input":"2024-06-30T01:23:33.795211Z","iopub.status.idle":"2024-06-30T01:23:34.216801Z","shell.execute_reply.started":"2024-06-30T01:23:33.795179Z","shell.execute_reply":"2024-06-30T01:23:34.215988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_test = list(os.listdir('/kaggle/input/test-img'))\nn = len(my_test)\n\n# plt.figure(figsize=(15,10))\nfor i, file in enumerate(my_test):\n    img = cv2.imread('/kaggle/input/test-img/' + file)\n    img = cv2.resize(img, IMG_SIZE)\n\n    img_input = np.expand_dims(img, axis=0)\n    pred = model.predict(img_input).argmax()\n\n    plt.subplot(1,n, i + 1)\n    plt.axis('off')\n    plt.imshow(img)\n    plt.title(\"Dog\" if pred == 1 else \"Cat\")\nplt.show()","metadata":{},"execution_count":null,"outputs":[]}]}