{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":38284,"databundleVersionId":4155799,"sourceType":"competition"},{"sourceId":10479700,"sourceType":"datasetVersion","datasetId":6489097},{"sourceId":11969669,"sourceType":"datasetVersion","datasetId":7526841},{"sourceId":11969807,"sourceType":"datasetVersion","datasetId":7526939},{"sourceId":11969973,"sourceType":"datasetVersion","datasetId":7527061},{"sourceId":11970212,"sourceType":"datasetVersion","datasetId":7527241},{"sourceId":11970989,"sourceType":"datasetVersion","datasetId":7527801},{"sourceId":11971008,"sourceType":"datasetVersion","datasetId":7527810},{"sourceId":11971057,"sourceType":"datasetVersion","datasetId":7527832},{"sourceId":11971070,"sourceType":"datasetVersion","datasetId":7527843},{"sourceId":11971087,"sourceType":"datasetVersion","datasetId":7527856},{"sourceId":11971127,"sourceType":"datasetVersion","datasetId":7527879},{"sourceId":11971159,"sourceType":"datasetVersion","datasetId":7527899}],"dockerImageVersionId":31040,"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 numpy as np\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport cv2\nfrom skimage.io import imread\nfrom skimage.transform import resize\nfrom sklearn.preprocessing import OneHotEncoder\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras.applications.vgg16 import VGG16, preprocess_input\nfrom tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Input, Lambda, BatchNormalization, Dense, GlobalAveragePooling2D, Dropout\nfrom tensorflow.keras.optimizers import Adam\nimport os","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:45:25.119389Z","iopub.execute_input":"2025-05-28T11:45:25.120109Z","iopub.status.idle":"2025-05-28T11:45:39.383304Z","shell.execute_reply.started":"2025-05-28T11:45:25.120070Z","shell.execute_reply":"2025-05-28T11:45:39.382549Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Load data**","metadata":{}},{"cell_type":"code","source":"train_path = '/kaggle/input/4-animal-classification/train'\n\nX_train, y_train = [], []\nmp = {}\nfor label_name in os.listdir(train_path):\n    sub_dir = os.path.join(train_path, label_name)\n    mp[label_name] = 0\n    for sub_dirp in os.listdir(sub_dir):\n        mp[label_name] = mp[label_name] + 1\n        file = os.path.join(sub_dir, sub_dirp)\n        img = imread(file)\n        img = resize(img, (224, 224), preserve_range=True)\n        img = img.astype(np.float32)\n        X_train.append(img)\n        y_train.append(label_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:45:39.384527Z","iopub.execute_input":"2025-05-28T11:45:39.385365Z","iopub.status.idle":"2025-05-28T11:47:29.879182Z","shell.execute_reply.started":"2025-05-28T11:45:39.385346Z","shell.execute_reply":"2025-05-28T11:47:29.878612Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"other_path = '/kaggle/input/coco-subset-for-pose-estimation/dataset/train'\nmp['other'] = 0\nd = 0\nfor sub_dir in os.listdir(other_path):\n    if d == 1000:\n        break\n    d = d + 1\n    file = os.path.join(other_path, sub_dir)\n    mp['other'] = mp['other'] + 1\n    img = imread(file)\n    if img.ndim == 2:\n        img = np.stack([img]*3, axis=-1)\n    elif img.ndim == 3 and img.shape[2] == 4:\n        img = img[..., :3]\n    elif img.ndim != 3 or img.shape[2] != 3:\n        print(f\"Unexpected shape {img.shape} at {file}, skipping.\")\n        continue\n    img = resize(img, (224, 224), preserve_range=True)\n    img = img.astype(np.float32)\n    X_train.append(img)\n    y_train.append('other')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:47:29.879884Z","iopub.execute_input":"2025-05-28T11:47:29.880094Z","iopub.status.idle":"2025-05-28T11:48:10.497326Z","shell.execute_reply.started":"2025-05-28T11:47:29.880077Z","shell.execute_reply":"2025-05-28T11:48:10.496780Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(mp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:10.498088Z","iopub.execute_input":"2025-05-28T11:48:10.498332Z","iopub.status.idle":"2025-05-28T11:48:10.502369Z","shell.execute_reply.started":"2025-05-28T11:48:10.498305Z","shell.execute_reply":"2025-05-28T11:48:10.501836Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels = list(mp.keys())\ncounts = list(mp.values())\n\nplt.figure(figsize=(10, 6))\nplt.bar(labels, counts)\nplt.xlabel('Class')\nplt.ylabel('Number of Images')\nplt.title('Number of Images per Class')\nplt.xticks(rotation=45, ha='right')\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:10.504534Z","iopub.execute_input":"2025-05-28T11:48:10.504803Z","iopub.status.idle":"2025-05-28T11:48:10.687081Z","shell.execute_reply.started":"2025-05-28T11:48:10.504786Z","shell.execute_reply":"2025-05-28T11:48:10.686383Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_path = '/kaggle/input/4-animal-classification/test/test'\n\nX_test, id_sub = [], []\nfor sub_dir in os.listdir(test_path):\n    file = os.path.join(test_path, sub_dir)\n    img = imread(file)\n    img = resize(img, (224, 224), preserve_range=True)\n    img = img.astype(np.float32)\n    id_sub.append(sub_dir.split('.')[0])\n    X_test.append(img)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:10.687855Z","iopub.execute_input":"2025-05-28T11:48:10.688179Z","iopub.status.idle":"2025-05-28T11:48:38.945045Z","shell.execute_reply.started":"2025-05-28T11:48:10.688155Z","shell.execute_reply":"2025-05-28T11:48:38.944240Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train = np.array(X_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:38.945865Z","iopub.execute_input":"2025-05-28T11:48:38.946091Z","iopub.status.idle":"2025-05-28T11:48:39.619286Z","shell.execute_reply.started":"2025-05-28T11:48:38.946074Z","shell.execute_reply":"2025-05-28T11:48:39.618744Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = np.array(X_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:39.620170Z","iopub.execute_input":"2025-05-28T11:48:39.620381Z","iopub.status.idle":"2025-05-28T11:48:39.716905Z","shell.execute_reply.started":"2025-05-28T11:48:39.620364Z","shell.execute_reply":"2025-05-28T11:48:39.716316Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:39.717761Z","iopub.execute_input":"2025-05-28T11:48:39.718119Z","iopub.status.idle":"2025-05-28T11:48:39.723495Z","shell.execute_reply.started":"2025-05-28T11:48:39.718091Z","shell.execute_reply":"2025-05-28T11:48:39.722822Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_train = np.array(y_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:39.724375Z","iopub.execute_input":"2025-05-28T11:48:39.724972Z","iopub.status.idle":"2025-05-28T11:48:39.733516Z","shell.execute_reply.started":"2025-05-28T11:48:39.724948Z","shell.execute_reply":"2025-05-28T11:48:39.732848Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(y_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:39.734338Z","iopub.execute_input":"2025-05-28T11:48:39.734505Z","iopub.status.idle":"2025-05-28T11:48:39.746306Z","shell.execute_reply.started":"2025-05-28T11:48:39.734492Z","shell.execute_reply":"2025-05-28T11:48:39.745546Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ec = OneHotEncoder(sparse=False, categories=[['cat', 'deer', 'dog', 'horse', 'other']])\n\ny_train = ec.fit_transform(y_train.reshape(-1, 1))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:39.747080Z","iopub.execute_input":"2025-05-28T11:48:39.747802Z","iopub.status.idle":"2025-05-28T11:48:39.764859Z","shell.execute_reply.started":"2025-05-28T11:48:39.747784Z","shell.execute_reply":"2025-05-28T11:48:39.764176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size = 0.2, random_state = 19)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:39.765607Z","iopub.execute_input":"2025-05-28T11:48:39.766192Z","iopub.status.idle":"2025-05-28T11:48:40.425511Z","shell.execute_reply.started":"2025-05-28T11:48:39.766176Z","shell.execute_reply":"2025-05-28T11:48:40.424954Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for i in range(10):\n    plt.imshow(X_train[i] / 255.0)\n    plt.show()\n    print(ec.inverse_transform([y_train[i]]))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:40.428855Z","iopub.execute_input":"2025-05-28T11:48:40.429074Z","iopub.status.idle":"2025-05-28T11:48:42.610164Z","shell.execute_reply.started":"2025-05-28T11:48:40.429058Z","shell.execute_reply":"2025-05-28T11:48:42.609365Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:42.610961Z","iopub.execute_input":"2025-05-28T11:48:42.611168Z","iopub.status.idle":"2025-05-28T11:48:42.615854Z","shell.execute_reply.started":"2025-05-28T11:48:42.611152Z","shell.execute_reply":"2025-05-28T11:48:42.615183Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:42.616759Z","iopub.execute_input":"2025-05-28T11:48:42.616982Z","iopub.status.idle":"2025-05-28T11:48:42.628016Z","shell.execute_reply.started":"2025-05-28T11:48:42.616958Z","shell.execute_reply":"2025-05-28T11:48:42.627457Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_train","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:42.628806Z","iopub.execute_input":"2025-05-28T11:48:42.629042Z","iopub.status.idle":"2025-05-28T11:48:42.639441Z","shell.execute_reply.started":"2025-05-28T11:48:42.629027Z","shell.execute_reply":"2025-05-28T11:48:42.638883Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Modeling**","metadata":{}},{"cell_type":"markdown","source":"## VGG16","metadata":{}},{"cell_type":"code","source":"def model(model_name):\n  model = Sequential()\n  # model.add(Lambda(preprocess_input)(Input(shape=(224, 224, 3))))\n  for layer in model_name.layers:\n    layer.trainable = False\n    model.add(layer)\n  return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:42.640126Z","iopub.execute_input":"2025-05-28T11:48:42.640373Z","iopub.status.idle":"2025-05-28T11:48:42.649216Z","shell.execute_reply.started":"2025-05-28T11:48:42.640352Z","shell.execute_reply":"2025-05-28T11:48:42.648495Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"vgg16 = VGG16(weights='imagenet',include_top=False, input_tensor= Lambda(preprocess_input)(Input(shape=(224, 224, 3))))\nmodel_vgg16 = model(vgg16)\nmodel_vgg16.add(GlobalAveragePooling2D())\nmodel_vgg16.add(Dense(4096, activation='relu'))\nmodel_vgg16.add(BatchNormalization())\nmodel_vgg16.add(Dropout(0.2))\n\nmodel_vgg16.add(Dense(4096, activation='relu'))\nmodel_vgg16.add(BatchNormalization())\nmodel_vgg16.add(Dropout(0.2))\n\nmodel_vgg16.add(Dense(5, activation='softmax'))\nmodel_vgg16.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:42.650057Z","iopub.execute_input":"2025-05-28T11:48:42.650285Z","iopub.status.idle":"2025-05-28T11:48:46.052835Z","shell.execute_reply.started":"2025-05-28T11:48:42.650271Z","shell.execute_reply":"2025-05-28T11:48:46.052096Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### No augmentation","metadata":{}},{"cell_type":"code","source":"model_vgg16.compile(optimizer= Adam(learning_rate=1e-3), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:46.053671Z","iopub.execute_input":"2025-05-28T11:48:46.053954Z","iopub.status.idle":"2025-05-28T11:48:46.065910Z","shell.execute_reply.started":"2025-05-28T11:48:46.053930Z","shell.execute_reply":"2025-05-28T11:48:46.065356Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stop = EarlyStopping(\n    monitor='val_loss',   \n    patience=16,      \n    restore_best_weights=True \n)\n\nhistory_vgg16 = model_vgg16.fit(X_train, y_train\n                       , validation_data = (X_valid, y_valid)\n                       , batch_size = 64, epochs = 100\n                       , callbacks = [early_stop])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:48:46.066624Z","iopub.execute_input":"2025-05-28T11:48:46.066928Z","iopub.status.idle":"2025-05-28T11:56:58.545065Z","shell.execute_reply.started":"2025-05-28T11:48:46.066905Z","shell.execute_reply":"2025-05-28T11:56:58.544260Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8, 5))\nplt.plot(history_vgg16.history['loss'], label='Training Loss')\nif 'val_loss' in history_vgg16.history:\n    plt.plot(history_vgg16.history['val_loss'], label='Validation Loss')\nplt.title('Model Loss Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.grid(True)\nplt.show()\n\nif 'accuracy' in history_vgg16.history or 'val_accuracy' in history_vgg16.history:\n    plt.figure(figsize=(8, 5))\n    if 'accuracy' in history_vgg16.history:\n        plt.plot(history_vgg16.history['accuracy'], label='Training Accuracy')\n    if 'val_accuracy' in history_vgg16.history:\n        plt.plot(history_vgg16.history['val_accuracy'], label='Validation Accuracy')\n    plt.title('Model Accuracy Over Epochs')\n    plt.xlabel('Epoch')\n    plt.ylabel('Accuracy')\n    plt.legend()\n    plt.grid(True)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:56:58.546148Z","iopub.execute_input":"2025-05-28T11:56:58.546379Z","iopub.status.idle":"2025-05-28T11:56:58.928154Z","shell.execute_reply.started":"2025-05-28T11:56:58.546358Z","shell.execute_reply":"2025-05-28T11:56:58.927388Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model_vgg16.predict(X_test)\ny_pred = np.argmax(y_pred, axis = 1)\n\nsubmission1 = pd.read_csv('/kaggle/input/4-animal-classification/Sample_submission.csv')\nsubmission1['ID'] = id_sub\nsubmission1['Label'] = y_pred\nsubmission1.to_csv('submission1_1.csv', index = False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T11:56:58.928871Z","iopub.execute_input":"2025-05-28T11:56:58.929066Z","iopub.status.idle":"2025-05-28T11:57:17.372156Z","shell.execute_reply.started":"2025-05-28T11:56:58.929051Z","shell.execute_reply":"2025-05-28T11:57:17.371392Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Augmentation","metadata":{}},{"cell_type":"code","source":"vgg16_aug = VGG16(weights='imagenet',include_top=False, input_tensor= Lambda(preprocess_input)(Input(shape=(224, 224, 3))))\nmodel_vgg16_aug = model(vgg16_aug)\nmodel_vgg16_aug.add(GlobalAveragePooling2D())\nmodel_vgg16_aug.add(Dense(4096, activation='relu'))\nmodel_vgg16_aug.add(BatchNormalization())\nmodel_vgg16_aug.add(Dropout(0.2))\n\nmodel_vgg16_aug.add(Dense(4096, activation='relu'))\nmodel_vgg16_aug.add(BatchNormalization())\nmodel_vgg16_aug.add(Dropout(0.2))\n\nmodel_vgg16_aug.add(Dense(5, activation='softmax'))\nmodel_vgg16_aug.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:06:18.808173Z","iopub.execute_input":"2025-05-28T12:06:18.808794Z","iopub.status.idle":"2025-05-28T12:06:19.576674Z","shell.execute_reply.started":"2025-05-28T12:06:18.808768Z","shell.execute_reply":"2025-05-28T12:06:19.576091Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_vgg16_aug.compile(optimizer= Adam(learning_rate=1e-3), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:07:02.318620Z","iopub.execute_input":"2025-05-28T12:07:02.318923Z","iopub.status.idle":"2025-05-28T12:07:02.328776Z","shell.execute_reply.started":"2025-05-28T12:07:02.318903Z","shell.execute_reply":"2025-05-28T12:07:02.328060Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:07:02.329997Z","iopub.execute_input":"2025-05-28T12:07:02.330411Z","iopub.status.idle":"2025-05-28T12:07:02.339763Z","shell.execute_reply.started":"2025-05-28T12:07:02.330394Z","shell.execute_reply":"2025-05-28T12:07:02.339031Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_generator = train_datagen.flow(\n    X_train, y_train,\n    batch_size=64,\n    shuffle=True,\n    seed=19\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:07:02.340491Z","iopub.execute_input":"2025-05-28T12:07:02.340862Z","iopub.status.idle":"2025-05-28T12:07:02.352107Z","shell.execute_reply.started":"2025-05-28T12:07:02.340841Z","shell.execute_reply":"2025-05-28T12:07:02.351301Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stop = EarlyStopping(\n    monitor='val_loss',   \n    patience=16,      \n    restore_best_weights=True \n)\n\nhistory_vgg16_aug = model_vgg16_aug.fit(train_generator\n                       , validation_data = (X_valid, y_valid)\n                       , batch_size = 64, epochs = 100\n                       , callbacks = [early_stop])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:09:20.462346Z","iopub.execute_input":"2025-05-28T12:09:20.462647Z","iopub.status.idle":"2025-05-28T12:22:02.706172Z","shell.execute_reply.started":"2025-05-28T12:09:20.462626Z","shell.execute_reply":"2025-05-28T12:22:02.705529Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8, 5))\nplt.plot(history_vgg16_aug.history['loss'], label='Training Loss')\nif 'val_loss' in history_vgg16_aug.history:\n    plt.plot(history_vgg16_aug.history['val_loss'], label='Validation Loss')\nplt.title('Model Loss Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.grid(True)\nplt.show()\n\nif 'accuracy' in history_vgg16_aug.history or 'val_accuracy' in history_vgg16_aug.history:\n    plt.figure(figsize=(8, 5))\n    if 'accuracy' in history_vgg16_aug.history:\n        plt.plot(history_vgg16_aug.history['accuracy'], label='Training Accuracy')\n    if 'val_accuracy' in history_vgg16_aug.history:\n        plt.plot(history_vgg16_aug.history['val_accuracy'], label='Validation Accuracy')\n    plt.title('Model Accuracy Over Epochs')\n    plt.xlabel('Epoch')\n    plt.ylabel('Accuracy')\n    plt.legend()\n    plt.grid(True)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:25:48.347128Z","iopub.execute_input":"2025-05-28T12:25:48.347727Z","iopub.status.idle":"2025-05-28T12:25:48.716447Z","shell.execute_reply.started":"2025-05-28T12:25:48.347703Z","shell.execute_reply":"2025-05-28T12:25:48.715806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model_vgg16.predict(X_test)\ny_pred = np.argmax(y_pred, axis = 1)\n\nsubmission2 = pd.read_csv('/kaggle/input/4-animal-classification/Sample_submission.csv')\nsubmission2['ID'] = id_sub\nsubmission2['Label'] = y_pred\nsubmission2.to_csv('submission2_1.csv', index = False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:25:48.717586Z","iopub.execute_input":"2025-05-28T12:25:48.717798Z","iopub.status.idle":"2025-05-28T12:25:54.705367Z","shell.execute_reply.started":"2025-05-28T12:25:48.717782Z","shell.execute_reply":"2025-05-28T12:25:54.704833Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Resnet 50","metadata":{}},{"cell_type":"code","source":"class ResNet:\n    def __init__(self,\n                 input_shape=(224, 224, 3),\n                 lr: float = 1e-3):\n        \n        self.input_shape = input_shape\n        self.lr = lr\n        self.model: tf.keras.Model = None\n\n    def build(self):\n        inputs = Input(shape=self.input_shape)\n\n        x = Lambda(preprocess_input, name=\"preprocessing\")(inputs)\n\n        base = ResNet50(\n            weights='imagenet',\n            include_top=False,\n            input_tensor=x\n        )\n        base.trainable = False\n\n        x = GlobalAveragePooling2D(name=\"gap\")(base.output)\n\n        x = Dense(512, activation='relu')(x)\n        x = BatchNormalization()(x)\n        x = Dropout(rate = 0.2)(x)\n\n        x = Dense(256, activation='relu')(x)\n        x = BatchNormalization()(x)\n        x = Dropout(rate = 0.2)(x)\n        \n        output = Dense(5, activation='softmax', name=\"predictions\")(x)\n\n        self.model = Model(inputs=inputs, outputs=output, name=\"ResNet50_4cls\")\n        self.model.compile(\n            optimizer=tf.keras.optimizers.Adam(learning_rate=self.lr),\n            loss='categorical_crossentropy',\n            metrics=['accuracy']\n        )\n        return self.model\n\n    def summary(self):\n        self.model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:25:54.706122Z","iopub.execute_input":"2025-05-28T12:25:54.706393Z","iopub.status.idle":"2025-05-28T12:25:54.713027Z","shell.execute_reply.started":"2025-05-28T12:25:54.706376Z","shell.execute_reply":"2025-05-28T12:25:54.712469Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### No augmentation","metadata":{}},{"cell_type":"code","source":"resnet50 = ResNet()\nresnet50 = resnet50.build()\nprint(resnet50.summary())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:25:54.713849Z","iopub.execute_input":"2025-05-28T12:25:54.714095Z","iopub.status.idle":"2025-05-28T12:25:56.709318Z","shell.execute_reply.started":"2025-05-28T12:25:54.714074Z","shell.execute_reply":"2025-05-28T12:25:56.708516Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stop = EarlyStopping(\n    monitor='val_loss',   \n    patience=16,      \n    restore_best_weights=True \n)\n\nhistory_resnet50 = resnet50.fit(X_train, y_train\n                       , validation_data = (X_valid, y_valid)\n                       , batch_size = 64, epochs = 100\n                       , callbacks = [early_stop])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:25:56.710837Z","iopub.execute_input":"2025-05-28T12:25:56.711043Z","iopub.status.idle":"2025-05-28T12:30:00.613989Z","shell.execute_reply.started":"2025-05-28T12:25:56.711027Z","shell.execute_reply":"2025-05-28T12:30:00.613380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8, 5))\nplt.plot(history_resnet50.history['loss'], label='Training Loss')\nif 'val_loss' in history_resnet50.history:\n    plt.plot(history_resnet50.history['val_loss'], label='Validation Loss')\nplt.title('Model Loss Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.grid(True)\nplt.show()\n\nif 'accuracy' in history_resnet50.history or 'val_accuracy' in history_resnet50.history:\n    plt.figure(figsize=(8, 5))\n    if 'accuracy' in history_resnet50.history:\n        plt.plot(history_resnet50.history['accuracy'], label='Training Accuracy')\n    if 'val_accuracy' in history_resnet50.history:\n        plt.plot(history_resnet50.history['val_accuracy'], label='Validation Accuracy')\n    plt.title('Model Accuracy Over Epochs')\n    plt.xlabel('Epoch')\n    plt.ylabel('Accuracy')\n    plt.legend()\n    plt.grid(True)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:00.348393Z","iopub.execute_input":"2025-05-28T12:46:00.349243Z","iopub.status.idle":"2025-05-28T12:46:00.704839Z","shell.execute_reply.started":"2025-05-28T12:46:00.349212Z","shell.execute_reply":"2025-05-28T12:46:00.704213Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = resnet50.predict(X_test)\ny_pred = np.argmax(y_pred, axis = 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:42.324455Z","iopub.execute_input":"2025-05-28T12:46:42.325081Z","iopub.status.idle":"2025-05-28T12:46:57.084676Z","shell.execute_reply.started":"2025-05-28T12:46:42.325047Z","shell.execute_reply":"2025-05-28T12:46:57.084111Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission1 = pd.read_csv('/kaggle/input/4-animal-classification/Sample_submission.csv')\nsubmission1['ID'] = id_sub\nsubmission1['Label'] = y_pred\nsubmission1.to_csv('submission1_2.csv', index = False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:57.085806Z","iopub.execute_input":"2025-05-28T12:46:57.086018Z","iopub.status.idle":"2025-05-28T12:46:57.095402Z","shell.execute_reply.started":"2025-05-28T12:46:57.086002Z","shell.execute_reply":"2025-05-28T12:46:57.094637Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Augmentation","metadata":{}},{"cell_type":"code","source":"resnet50_aug = ResNet()\nresnet50_aug = resnet50_aug.build()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:57.096105Z","iopub.execute_input":"2025-05-28T12:46:57.096321Z","iopub.status.idle":"2025-05-28T12:46:58.145438Z","shell.execute_reply.started":"2025-05-28T12:46:57.096298Z","shell.execute_reply":"2025-05-28T12:46:58.144895Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:58.147083Z","iopub.execute_input":"2025-05-28T12:46:58.147301Z","iopub.status.idle":"2025-05-28T12:46:58.151242Z","shell.execute_reply.started":"2025-05-28T12:46:58.147285Z","shell.execute_reply":"2025-05-28T12:46:58.150501Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_generator = train_datagen.flow(\n    X_train, y_train,\n    batch_size=64,\n    shuffle=True,\n    seed=19\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:58.152061Z","iopub.execute_input":"2025-05-28T12:46:58.152281Z","iopub.status.idle":"2025-05-28T12:46:58.163323Z","shell.execute_reply.started":"2025-05-28T12:46:58.152266Z","shell.execute_reply":"2025-05-28T12:46:58.162624Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stop = EarlyStopping(\n    monitor='val_loss',   \n    patience=16,      \n    restore_best_weights=True \n)\n\nhistory_resnet50_aug = resnet50_aug.fit(train_generator\n                           , validation_data = (X_valid, y_valid)\n                           , batch_size = 64, epochs = 100\n                           , callbacks = [early_stop])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T12:46:58.164084Z","iopub.execute_input":"2025-05-28T12:46:58.164270Z","iopub.status.idle":"2025-05-28T13:00:06.617363Z","shell.execute_reply.started":"2025-05-28T12:46:58.164256Z","shell.execute_reply":"2025-05-28T13:00:06.616807Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8, 5))\nplt.plot(history_resnet50_aug.history['loss'], label='Training Loss')\nif 'val_loss' in history_resnet50_aug.history:\n    plt.plot(history_resnet50_aug.history['val_loss'], label='Validation Loss')\nplt.title('Model Loss Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.grid(True)\nplt.show()\n\nif 'accuracy' in history_resnet50_aug.history or 'val_accuracy' in history_resnet50_aug.history:\n    plt.figure(figsize=(8, 5))\n    if 'accuracy' in history_resnet50_aug.history:\n        plt.plot(history_resnet50_aug.history['accuracy'], label='Training Accuracy')\n    if 'val_accuracy' in history_resnet50_aug.history:\n        plt.plot(history_resnet50_aug.history['val_accuracy'], label='Validation Accuracy')\n    plt.title('Model Accuracy Over Epochs')\n    plt.xlabel('Epoch')\n    plt.ylabel('Accuracy')\n    plt.legend()\n    plt.grid(True)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:00:06.618382Z","iopub.execute_input":"2025-05-28T13:00:06.618655Z","iopub.status.idle":"2025-05-28T13:00:06.940476Z","shell.execute_reply.started":"2025-05-28T13:00:06.618638Z","shell.execute_reply":"2025-05-28T13:00:06.939811Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = resnet50.predict(X_test)\ny_pred = np.argmax(y_pred, axis = 1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:00:06.941213Z","iopub.execute_input":"2025-05-28T13:00:06.941391Z","iopub.status.idle":"2025-05-28T13:00:10.287163Z","shell.execute_reply.started":"2025-05-28T13:00:06.941377Z","shell.execute_reply":"2025-05-28T13:00:10.286635Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission2 = pd.read_csv('/kaggle/input/4-animal-classification/Sample_submission.csv')\nsubmission2['ID'] = id_sub\nsubmission2['Label'] = y_pred\nsubmission2.to_csv('submission2_2.csv', index = False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:00:10.287903Z","iopub.execute_input":"2025-05-28T13:00:10.288154Z","iopub.status.idle":"2025-05-28T13:00:10.304107Z","shell.execute_reply.started":"2025-05-28T13:00:10.288132Z","shell.execute_reply":"2025-05-28T13:00:10.303410Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Compare model**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nhistories = {\n    'VGG16': history_vgg16,\n    'VGG16 + Aug': history_vgg16_aug,\n    'ResNet50': history_resnet50,\n    'ResNet50 + Aug': history_resnet50_aug\n}\n\ndef plot_metric(metric, title, ylabel):\n    plt.figure(figsize=(10, 6))\n    for name, history in histories.items():\n        if metric in history.history:\n            plt.plot(history.history[metric], label=name)\n    plt.title(title)\n    plt.xlabel('Epoch')\n    plt.ylabel(ylabel)\n    plt.legend()\n    plt.grid(True)\n    plt.show()\n\n# Vẽ 4 biểu đồ\nplot_metric('loss', 'Training Loss Comparison', 'Loss')\nplot_metric('val_loss', 'Validation Loss Comparison', 'Loss')\nplot_metric('accuracy', 'Training Accuracy Comparison', 'Accuracy')\nplot_metric('val_accuracy', 'Validation Accuracy Comparison', 'Accuracy')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:04:33.217399Z","iopub.execute_input":"2025-05-28T13:04:33.217708Z","iopub.status.idle":"2025-05-28T13:04:33.901673Z","shell.execute_reply.started":"2025-05-28T13:04:33.217686Z","shell.execute_reply":"2025-05-28T13:04:33.901019Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Make fun predict","metadata":{}},{"cell_type":"code","source":"def predict_image(link):\n    img = imread(link)\n    if img.ndim == 2:\n        img = np.stack([img]*3, axis=-1)\n    elif img.ndim == 3 and img.shape[2] == 4:\n        img = img[..., :3]\n    elif img.ndim != 3 or img.shape[2] != 3:\n        print(f\"Unexpected shape {img.shape} at {file}, skipping.\")\n        return 0\n    img = resize(img, (224, 224), preserve_range=True)\n    img = img.astype(np.float32)\n    img = np.array(img)\n    \n    plt.imshow(img / 255)\n    \n    img = np.expand_dims(img, 0)\n    \n    print(img.shape)\n    \n    mp = {0: 'cat'\n          , 1: 'deer'\n          , 2:'dog'\n          , 3:'horse'\n          , 4: 'other'}\n\n    pred_vgg16 = model_vgg16.predict(img)\n    lab = np.argmax(pred_vgg16, axis = 1)\n    lab = [mp[x] for x in lab]\n    print('Predicted by VGG16')\n    print('label: ', lab, ' Accuracy: ', pred_vgg16.max(axis = 1))\n    \n    pred_vgg16_aug = model_vgg16_aug.predict(img)\n    lab = np.argmax(pred_vgg16_aug, axis = 1)\n    lab = [mp[x] for x in lab]\n    print('Predicted by VGG16 with augmentation')\n    print('label: ', lab, ' Accuracy: ', pred_vgg16_aug.max(axis = 1))\n    \n    pred_resnet50 = resnet50.predict(img)\n    lab = np.argmax(pred_resnet50, axis = 1)\n    lab = [mp[x] for x in lab]\n    print('Predicted by resnet50')\n    print('label: ', lab, ' Accuracy: ', pred_resnet50.max(axis = 1))\n    \n    pred_resnet50_aug = resnet50_aug.predict(img)\n    lab = np.argmax(pred_resnet50_aug, axis = 1)\n    lab = [mp[x] for x in lab]\n    print('Predicted by resnet with augmentation')\n    print('label: ', lab, ' Accuracy: ', pred_resnet50_aug.max(axis = 1))\n    return 0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:14.073882Z","iopub.execute_input":"2025-05-28T13:35:14.074786Z","iopub.status.idle":"2025-05-28T13:35:14.083031Z","shell.execute_reply.started":"2025-05-28T13:35:14.074763Z","shell.execute_reply":"2025-05-28T13:35:14.082330Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/conho2/de4abe63-4b99-4d63-8d7b-332c44981369.jpeg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:14.084479Z","iopub.execute_input":"2025-05-28T13:35:14.084708Z","iopub.status.idle":"2025-05-28T13:35:14.684833Z","shell.execute_reply.started":"2025-05-28T13:35:14.084690Z","shell.execute_reply":"2025-05-28T13:35:14.684177Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/lmessi/images.jpeg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:14.685728Z","iopub.execute_input":"2025-05-28T13:35:14.686313Z","iopub.status.idle":"2025-05-28T13:35:15.276713Z","shell.execute_reply.started":"2025-05-28T13:35:14.686288Z","shell.execute_reply":"2025-05-28T13:35:15.275938Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/thay123/MaiTienDung-300x300.png')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:15.277480Z","iopub.execute_input":"2025-05-28T13:35:15.277770Z","iopub.status.idle":"2025-05-28T13:35:15.850385Z","shell.execute_reply.started":"2025-05-28T13:35:15.277746Z","shell.execute_reply":"2025-05-28T13:35:15.849620Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/3animal/indoor-photo-dog-cat-horse-260nw-2524143355.webp')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:15.851942Z","iopub.execute_input":"2025-05-28T13:35:15.852153Z","iopub.status.idle":"2025-05-28T13:35:16.575890Z","shell.execute_reply.started":"2025-05-28T13:35:15.852136Z","shell.execute_reply":"2025-05-28T13:35:16.575133Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/3horse/images (1).jpeg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:16.576651Z","iopub.execute_input":"2025-05-28T13:35:16.576873Z","iopub.status.idle":"2025-05-28T13:35:17.166224Z","shell.execute_reply.started":"2025-05-28T13:35:16.576856Z","shell.execute_reply":"2025-05-28T13:35:17.165459Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/doglikecat/shutterstock_478338919_huge.jpg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:17.166986Z","iopub.execute_input":"2025-05-28T13:35:17.167190Z","iopub.status.idle":"2025-05-28T13:35:17.800756Z","shell.execute_reply.started":"2025-05-28T13:35:17.167174Z","shell.execute_reply":"2025-05-28T13:35:17.799954Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/superdog/ba33f562-5a7e-4d20-a0e3-744746315edf.jpeg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:17.801564Z","iopub.execute_input":"2025-05-28T13:35:17.801847Z","iopub.status.idle":"2025-05-28T13:35:18.399184Z","shell.execute_reply.started":"2025-05-28T13:35:17.801825Z","shell.execute_reply":"2025-05-28T13:35:18.398531Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/pokemon/ti xung.jpeg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:18.399944Z","iopub.execute_input":"2025-05-28T13:35:18.400411Z","iopub.status.idle":"2025-05-28T13:35:18.934321Z","shell.execute_reply.started":"2025-05-28T13:35:18.400391Z","shell.execute_reply":"2025-05-28T13:35:18.933628Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/cat-pokemon/images (2).jpeg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:18.935126Z","iopub.execute_input":"2025-05-28T13:35:18.935330Z","iopub.status.idle":"2025-05-28T13:35:19.464655Z","shell.execute_reply.started":"2025-05-28T13:35:18.935314Z","shell.execute_reply":"2025-05-28T13:35:19.463892Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict_image('/kaggle/input/deer123/White-tailed_deer_(Odocoileus_virginianus)_grazing_-_20050809.jpg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-28T13:35:19.465428Z","iopub.execute_input":"2025-05-28T13:35:19.465698Z","iopub.status.idle":"2025-05-28T13:35:20.148508Z","shell.execute_reply.started":"2025-05-28T13:35:19.465678Z","shell.execute_reply":"2025-05-28T13:35:20.147714Z"}},"outputs":[],"execution_count":null}]}