{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":7288715,"sourceType":"datasetVersion","datasetId":4226945}],"dockerImageVersionId":30627,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import Library","metadata":{}},{"cell_type":"code","source":"import cv2\nfrom PIL import Image\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt \nimport seaborn as sns","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:13:56.679948Z","iopub.execute_input":"2023-12-27T10:13:56.680692Z","iopub.status.idle":"2023-12-27T10:13:58.537731Z","shell.execute_reply.started":"2023-12-27T10:13:56.680649Z","shell.execute_reply":"2023-12-27T10:13:58.536578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\nimport itertools\nimport pathlib","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:13:58.539912Z","iopub.execute_input":"2023-12-27T10:13:58.540466Z","iopub.status.idle":"2023-12-27T10:13:58.545635Z","shell.execute_reply.started":"2023-12-27T10:13:58.540427Z","shell.execute_reply":"2023-12-27T10:13:58.544480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, BatchNormalization, Dropout, Flatten, Activation\nfrom tensorflow.keras.optimizers import Adam, Adamax","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:13:58.547465Z","iopub.execute_input":"2023-12-27T10:13:58.547828Z","iopub.status.idle":"2023-12-27T10:14:12.153541Z","shell.execute_reply.started":"2023-12-27T10:13:58.547792Z","shell.execute_reply":"2023-12-27T10:14:12.152674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix , classification_report, ConfusionMatrixDisplay\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:12.155648Z","iopub.execute_input":"2023-12-27T10:14:12.156216Z","iopub.status.idle":"2023-12-27T10:14:12.327691Z","shell.execute_reply.started":"2023-12-27T10:14:12.156187Z","shell.execute_reply":"2023-12-27T10:14:12.326490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:12.329160Z","iopub.execute_input":"2023-12-27T10:14:12.329531Z","iopub.status.idle":"2023-12-27T10:14:12.334521Z","shell.execute_reply.started":"2023-12-27T10:14:12.329499Z","shell.execute_reply":"2023-12-27T10:14:12.333354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Get data","metadata":{}},{"cell_type":"code","source":"# Only use training data from origin dataset for both training and testing \n!unzip /kaggle/input/dogs-vs-cats/train.zip","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path, dirs, files = next(os.walk('/kaggle/working/train'))\nfile_count = len(files)\nprint('path:', path)\nprint('num_of_dir:', len(dirs))\nprint('num_of_file:', file_count)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.665712Z","iopub.execute_input":"2023-12-27T10:14:22.666083Z","iopub.status.idle":"2023-12-27T10:14:22.705114Z","shell.execute_reply.started":"2023-12-27T10:14:22.666049Z","shell.execute_reply":"2023-12-27T10:14:22.704157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Store small version dataset\n# shutil.rmtree(base_dir)\nbase_dir = '/kaggle/working/dogs_vs_cats_small_dataset'\nos.mkdir(base_dir)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.706189Z","iopub.execute_input":"2023-12-27T10:14:22.706515Z","iopub.status.idle":"2023-12-27T10:14:22.711454Z","shell.execute_reply.started":"2023-12-27T10:14:22.706489Z","shell.execute_reply":"2023-12-27T10:14:22.710485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create Directories for Train, Val and Test","metadata":{}},{"cell_type":"code","source":"# Create dataset dir script\ndef create_dataset_dir(parent, dir):\n    dir = os.path.join(parent, dir)\n    os.mkdir(dir)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.712715Z","iopub.execute_input":"2023-12-27T10:14:22.713013Z","iopub.status.idle":"2023-12-27T10:14:22.721191Z","shell.execute_reply.started":"2023-12-27T10:14:22.712989Z","shell.execute_reply":"2023-12-27T10:14:22.720357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create train, val, test dir\nfor dir_name in ['train', 'valid', 'test']:\n    create_dataset_dir(base_dir, dir_name)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.725939Z","iopub.execute_input":"2023-12-27T10:14:22.726219Z","iopub.status.idle":"2023-12-27T10:14:22.732203Z","shell.execute_reply.started":"2023-12-27T10:14:22.726193Z","shell.execute_reply":"2023-12-27T10:14:22.731440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create dogs, cats dir inside train, val, test dir\nfor dir_name in ['train', 'valid', 'test']:\n    for class_name in ['cats', 'dogs']:\n        create_dataset_dir(base_dir, dir_name + '/' + class_name)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.733176Z","iopub.execute_input":"2023-12-27T10:14:22.733511Z","iopub.status.idle":"2023-12-27T10:14:22.743235Z","shell.execute_reply.started":"2023-12-27T10:14:22.733485Z","shell.execute_reply":"2023-12-27T10:14:22.742451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set dir name\ntrain_dir = os.path.join(base_dir, 'train')\nvalid_dir = os.path.join(base_dir, 'valid')\ntest_dir = os.path.join(base_dir, 'test')\ntrain_cats_dir = os.path.join(base_dir, 'train/cats')\nvalid_cats_dir = os.path.join(base_dir, 'valid/cats') \ntest_cats_dir = os.path.join(base_dir, 'test/cats')\ntrain_dogs_dir = os.path.join(base_dir, 'train/dogs')\nvalid_dogs_dir = os.path.join(base_dir, 'valid/dogs') \ntest_dogs_dir = os.path.join(base_dir, 'test/dogs')  ","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.744546Z","iopub.execute_input":"2023-12-27T10:14:22.744899Z","iopub.status.idle":"2023-12-27T10:14:22.754017Z","shell.execute_reply.started":"2023-12-27T10:14:22.744864Z","shell.execute_reply":"2023-12-27T10:14:22.753206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Move data to structured dir","metadata":{}},{"cell_type":"code","source":"# Class counting\ndir_path = '/kaggle/working/train'\n\ncat_count = 0\ndog_count= 0\nfor i in os.listdir(dir_path):\n    if i.startswith('cat.'):\n        cat_count += 1\n    elif i.startswith('dog.'):\n        dog_count += 1\n        \nprint(f\"Number of cat images: {cat_count}\")\nprint(f\"Number of dog images: {dog_count}\")","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.755093Z","iopub.execute_input":"2023-12-27T10:14:22.755347Z","iopub.status.idle":"2023-12-27T10:14:22.795560Z","shell.execute_reply.started":"2023-12-27T10:14:22.755325Z","shell.execute_reply":"2023-12-27T10:14:22.794658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"original_dataset_dir = '/kaggle/working/train'\n\n# Move data script\ndef move_data_to_dir(class_name, dir, start_idx, end_idx):\n    fnames = ['{}.{}.jpg'.format(class_name, i) for i in range(start_idx, end_idx)]\n    for fname in fnames:\n        src = os.path.join(original_dataset_dir, fname)\n        dst = os.path.join(dir, fname)\n        shutil.copyfile(src, dst)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.796722Z","iopub.execute_input":"2023-12-27T10:14:22.797079Z","iopub.status.idle":"2023-12-27T10:14:22.803115Z","shell.execute_reply.started":"2023-12-27T10:14:22.797051Z","shell.execute_reply":"2023-12-27T10:14:22.801984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 80% train : 10% valid : 10% test\n\n# Move cats\nmove_data_to_dir('cat', train_cats_dir, 0, 10000)\nmove_data_to_dir('cat', valid_cats_dir, 10000, 11250)\nmove_data_to_dir('cat', test_cats_dir, 11250, 12500)\n\n# Move dogs\nmove_data_to_dir('dog', train_dogs_dir, 0, 10000)\nmove_data_to_dir('dog', valid_dogs_dir, 10000, 11250)\nmove_data_to_dir('dog', test_dogs_dir, 11250, 12500)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:22.804394Z","iopub.execute_input":"2023-12-27T10:14:22.804756Z","iopub.status.idle":"2023-12-27T10:14:25.520750Z","shell.execute_reply.started":"2023-12-27T10:14:22.804722Z","shell.execute_reply":"2023-12-27T10:14:25.519872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check number\nprint(f'Total training cat images: {len(os.listdir(train_cats_dir))}')\nprint(f'Total validation cat images: {len(os.listdir(valid_cats_dir))}')\nprint(f'Total test cat images: {len(os.listdir(test_cats_dir))}')\nprint('\\n')\nprint(f'Total training dog images: {len(os.listdir(train_dogs_dir))}')\nprint(f'Total validation cat images: {len(os.listdir(valid_dogs_dir))}')\nprint(f'Total test cat images: {len(os.listdir(test_dogs_dir))}')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:25.521931Z","iopub.execute_input":"2023-12-27T10:14:25.522220Z","iopub.status.idle":"2023-12-27T10:14:25.543517Z","shell.execute_reply.started":"2023-12-27T10:14:25.522193Z","shell.execute_reply":"2023-12-27T10:14:25.542611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Image Data Generator","metadata":{}},{"cell_type":"code","source":"img_size = (224, 224)\nimg_shape = (img_size[0], img_size[1], 3)\nbatch_size = 32","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:25.544671Z","iopub.execute_input":"2023-12-27T10:14:25.545132Z","iopub.status.idle":"2023-12-27T10:14:25.549483Z","shell.execute_reply.started":"2023-12-27T10:14:25.545104Z","shell.execute_reply":"2023-12-27T10:14:25.548612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_gen = ImageDataGenerator().flow_from_directory(\n    train_dir, target_size = img_size ,class_mode = 'binary',\n    color_mode = 'rgb', shuffle = True, batch_size = batch_size)\n\nvalid_gen = ImageDataGenerator().flow_from_directory(\n    valid_dir, target_size = img_size, class_mode = 'binary',\n    color_mode = 'rgb', shuffle = True, batch_size = batch_size)\n\ntest_gen = ImageDataGenerator().flow_from_directory(\n    test_dir, target_size = img_size, class_mode = 'binary',\n    color_mode = 'rgb', shuffle = False, batch_size = batch_size)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:25.550656Z","iopub.execute_input":"2023-12-27T10:14:25.550959Z","iopub.status.idle":"2023-12-27T10:14:26.283526Z","shell.execute_reply.started":"2023-12-27T10:14:25.550933Z","shell.execute_reply":"2023-12-27T10:14:26.282672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Show Sample From Train Data","metadata":{}},{"cell_type":"code","source":"# Get class\ng_dict = train_gen.class_indices\nclasses = list(g_dict.keys())\n\n# Get a batch\nimages, labels = next(train_gen)\nnum_samples = len(images)\n\nplt.figure(figsize=(20, 10))\n\nfor i in range(min(8, num_samples)):\n    plt.subplot(2, 4, i + 1)\n    image = images[i] / 255\n    plt.imshow(image)\n    \n    # Set class name title     \n    class_index = int(labels[i])\n    class_name = classes[class_index]\n    plt.title(class_name, fontsize=16)\n    plt.grid(False)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:26.284792Z","iopub.execute_input":"2023-12-27T10:14:26.285667Z","iopub.status.idle":"2023-12-27T10:14:28.681454Z","shell.execute_reply.started":"2023-12-27T10:14:26.285624Z","shell.execute_reply":"2023-12-27T10:14:28.680145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modeling","metadata":{}},{"cell_type":"code","source":"# Get base_model and freeze it\nbase_model = tf.keras.applications.efficientnet.EfficientNetB5(\n    include_top= False, \n    weights= 'imagenet',\n    input_shape= img_shape,pooling= 'max'\n)\nbase_model.trainable= False","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:28.682922Z","iopub.execute_input":"2023-12-27T10:14:28.683264Z","iopub.status.idle":"2023-12-27T10:14:39.551690Z","shell.execute_reply.started":"2023-12-27T10:14:28.683234Z","shell.execute_reply":"2023-12-27T10:14:39.550823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Customize model\nmodel = Sequential([\n    base_model,\n    Dense(256, activation = 'relu'),\n    Dropout(rate = 0.4 , seed = 40),\n    Dense(1, activation = 'sigmoid')\n])\n\nmodel.compile(\n    optimizer = Adamax(learning_rate = 0.001), \n    loss = 'binary_crossentropy', \n    metrics= ['accuracy'])\n \nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:39.552864Z","iopub.execute_input":"2023-12-27T10:14:39.553171Z","iopub.status.idle":"2023-12-27T10:14:41.810350Z","shell.execute_reply.started":"2023-12-27T10:14:39.553144Z","shell.execute_reply":"2023-12-27T10:14:41.809307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"history = model.fit(\n    x = train_gen, \n    validation_data = valid_gen, \n    epochs = 10, \n    verbose = 1, \n    validation_steps = None, \n    shuffle = False\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:14:41.811828Z","iopub.execute_input":"2023-12-27T10:14:41.812618Z","iopub.status.idle":"2023-12-27T10:39:23.597798Z","shell.execute_reply.started":"2023-12-27T10:14:41.812576Z","shell.execute_reply":"2023-12-27T10:39:23.596735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Performance","metadata":{}},{"cell_type":"code","source":"# history of acc & loss\ntrain_acc = history.history['accuracy']\ntrain_loss = history.history['loss']\n\nval_acc = history.history['val_accuracy']\nval_loss = history.history['val_loss']\n\n# min loss, max acc\nindex_loss = np.argmin(val_loss)\nindex_acc = np.argmax(val_acc)\n\nval_lowest = val_loss[index_loss]\nval_highest = val_acc[index_acc]\n\nEpochs = [i+1 for i in range(len(train_acc))]","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:39:23.599639Z","iopub.execute_input":"2023-12-27T10:39:23.600161Z","iopub.status.idle":"2023-12-27T10:39:23.606197Z","shell.execute_reply.started":"2023-12-27T10:39:23.600122Z","shell.execute_reply":"2023-12-27T10:39:23.605352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize= (20,8))\n\n# Plot Loss\nplt.subplot(1,2,1)\nplt.plot(Epochs, train_loss, 'r', label = 'Training Loss')\nplt.plot(Epochs, val_loss, 'g', label = 'Validation Loss')\nloss_label = f'Best Epoch = {str(index_loss + 1)}'\nplt.scatter(index_loss +1 , val_lowest , s = 150 , c = 'blue' , label = loss_label)\nplt.title('Training vs Validation (loss)')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\n# Plot Accuracy\nplt.subplot(1,2,2)\nplt.plot(Epochs, train_acc, 'r', label = 'Training Accuracy')\nplt.plot(Epochs, val_acc, 'g', label = 'Validation Accuracy')\nacc_label = f'Best Epoch = {str(index_acc + 1)}'\nplt.scatter(index_acc + 1, val_highest, s = 150 , c = 'blue', label= acc_label)\nplt.title('Training vs Validation (Accuracy)')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:39:23.607736Z","iopub.execute_input":"2023-12-27T10:39:23.608441Z","iopub.status.idle":"2023-12-27T10:39:24.239777Z","shell.execute_reply.started":"2023-12-27T10:39:23.608402Z","shell.execute_reply":"2023-12-27T10:39:24.238776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model evaluation","metadata":{}},{"cell_type":"code","source":"val_score = model.evaluate(valid_gen, verbose = 1)\nprint(f'Validation loss = {val_score[0]}')\nprint(f'Validation Accuracy = {val_score[1]}')\nprint(\"\\n\") \ntest_score = model.evaluate(test_gen, verbose = 1)\nprint(f'Test loss = {test_score[0]}')\nprint(f'Test Accuracy = {test_score[1]}')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:39:24.241016Z","iopub.execute_input":"2023-12-27T10:39:24.241303Z","iopub.status.idle":"2023-12-27T10:39:56.053553Z","shell.execute_reply.started":"2023-12-27T10:39:24.241258Z","shell.execute_reply":"2023-12-27T10:39:56.052623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = model.predict(test_gen)\n\n# Convert the predictions to binary classes (0 or 1)\npredicted_classes = (preds > 0.5).astype(int)\npredicted_classes","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:39:56.054778Z","iopub.execute_input":"2023-12-27T10:39:56.055467Z","iopub.status.idle":"2023-12-27T10:40:15.555367Z","shell.execute_reply.started":"2023-12-27T10:39:56.055431Z","shell.execute_reply":"2023-12-27T10:40:15.554444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Confusion matrix\ndef plot_cm(y_test, y_pred):\n    plt.figure(figsize=(5, 3))\n    cm = confusion_matrix(y_test, y_pred)\n    sns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\")\n    plt.xlabel('Prediction classes');\n    plt.ylabel('True classes');","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:15.557937Z","iopub.execute_input":"2023-12-27T10:40:15.558230Z","iopub.status.idle":"2023-12-27T10:40:15.563643Z","shell.execute_reply.started":"2023-12-27T10:40:15.558202Z","shell.execute_reply":"2023-12-27T10:40:15.562735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"true_classes = test_gen.classes\nplot_cm(true_classes, predicted_classes)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:15.568878Z","iopub.execute_input":"2023-12-27T10:40:15.569207Z","iopub.status.idle":"2023-12-27T10:40:15.858558Z","shell.execute_reply.started":"2023-12-27T10:40:15.569176Z","shell.execute_reply":"2023-12-27T10:40:15.857675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate and print the classification report\nclassification_rep = classification_report(true_classes, predicted_classes, target_names=test_gen.class_indices)\nprint(\"\\nClassification Report:\")\nprint(classification_rep)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:15.859931Z","iopub.execute_input":"2023-12-27T10:40:15.860305Z","iopub.status.idle":"2023-12-27T10:40:15.878182Z","shell.execute_reply.started":"2023-12-27T10:40:15.860254Z","shell.execute_reply":"2023-12-27T10:40:15.877307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Mismatch Visualization","metadata":{}},{"cell_type":"code","source":"mismatch_indices = []\nfor i, (a, b) in enumerate(zip(predicted_classes, true_classes)):\n    if a != b:\n        mismatch_indices.append(i)\nmismatch_indices = np.array(mismatch_indices)\nmismatch_indices","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:15.879373Z","iopub.execute_input":"2023-12-27T10:40:15.879978Z","iopub.status.idle":"2023-12-27T10:40:15.896011Z","shell.execute_reply.started":"2023-12-27T10:40:15.879943Z","shell.execute_reply":"2023-12-27T10:40:15.895234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set grid size\nnum_columns = 5\nnum_rows = 5\nnum_images = num_columns * num_rows\n\nplt.figure(figsize=(20, 20))\n\n# Loop for mismatch_image\nfor i, index in enumerate(mismatch_indices):\n    # Compute batch and image_index\n    batch_index = index // batch_size\n    image_index = index % batch_size\n    \n    images, _ = test_gen[batch_index]\n    plt.subplot(num_rows, num_columns, i + 1)\n    plt.imshow(images[image_index] / 255)\n    plt.title(f\"True: {classes[true_classes[index]]}\\nPredict: {classes[predicted_classes[index][0]]}\", fontsize = 12)\n    plt.subplots_adjust(hspace=0.5)\n    plt.axis('off')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:15.897137Z","iopub.execute_input":"2023-12-27T10:40:15.897401Z","iopub.status.idle":"2023-12-27T10:40:19.268037Z","shell.execute_reply.started":"2023-12-27T10:40:15.897377Z","shell.execute_reply":"2023-12-27T10:40:19.266692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save model","metadata":{}},{"cell_type":"code","source":"model.save('dogvscat.h5')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:19.269381Z","iopub.execute_input":"2023-12-27T10:40:19.270174Z","iopub.status.idle":"2023-12-27T10:40:20.259923Z","shell.execute_reply.started":"2023-12-27T10:40:19.270131Z","shell.execute_reply":"2023-12-27T10:40:20.259038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load model","metadata":{}},{"cell_type":"code","source":"model = tf.keras.models.load_model('/kaggle/working/dogvscat.h5')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:20.261263Z","iopub.execute_input":"2023-12-27T10:40:20.261585Z","iopub.status.idle":"2023-12-27T10:40:27.737125Z","shell.execute_reply.started":"2023-12-27T10:40:20.261557Z","shell.execute_reply":"2023-12-27T10:40:27.736329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test saved model on an image","metadata":{}},{"cell_type":"code","source":"def predict_an_image(img):  \n    # Show image\n    norm_img = img / 255\n    plt.imshow(norm_img)\n    plt.axis('off')\n    \n    # Convert to 4D image     \n    img_4d = img.reshape(1, 224, 224, 3)\n    \n    # Predict  \n    preds = model.predict(img_4d)\n    predicted_classes = (preds > 0.5).astype(int)\n    if predicted_classes == [[0]]:\n        print('This is a cat!')\n    else:\n        print('This is a dog!')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:27.738415Z","iopub.execute_input":"2023-12-27T10:40:27.738706Z","iopub.status.idle":"2023-12-27T10:40:27.744550Z","shell.execute_reply.started":"2023-12-27T10:40:27.738680Z","shell.execute_reply":"2023-12-27T10:40:27.743550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image from batch","metadata":{}},{"cell_type":"code","source":"# Get a batch\nimages, labels = next(test_gen)\n\n# Get an image from the batch\nimg = images[0]\npredict_an_image(img)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:27.745659Z","iopub.execute_input":"2023-12-27T10:40:27.745981Z","iopub.status.idle":"2023-12-27T10:40:32.875751Z","shell.execute_reply.started":"2023-12-27T10:40:27.745946Z","shell.execute_reply":"2023-12-27T10:40:32.874847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Your uploaded image","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing import image\n\npath = '/kaggle/input/mydata/cat.jpg'\nimg = image.load_img(path, target_size=(224, 224))\nimg = np.array(img)\n\npredict_an_image(img)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:32.876948Z","iopub.execute_input":"2023-12-27T10:40:32.877242Z","iopub.status.idle":"2023-12-27T10:40:36.668242Z","shell.execute_reply.started":"2023-12-27T10:40:32.877205Z","shell.execute_reply":"2023-12-27T10:40:36.667320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test saved model on your testing dataset","metadata":{}},{"cell_type":"code","source":"# Dataset structure:\n# test_dir:\n# ___ dogs\n# ___ cats\nsample_test_gen = ImageDataGenerator().flow_from_directory(\n    test_dir, target_size = img_size, class_mode = 'binary',\n    color_mode = 'rgb', shuffle = False, batch_size = batch_size)\ntrue_classes = sample_test_gen.classes","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:36.669421Z","iopub.execute_input":"2023-12-27T10:40:36.669729Z","iopub.status.idle":"2023-12-27T10:40:36.746328Z","shell.execute_reply.started":"2023-12-27T10:40:36.669685Z","shell.execute_reply":"2023-12-27T10:40:36.745430Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict result (without labels)\npreds = model.predict(sample_test_gen)\npredicted_classes = (preds > 0.5).astype(int)\nprint(predicted_classes)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:36.747591Z","iopub.execute_input":"2023-12-27T10:40:36.747948Z","iopub.status.idle":"2023-12-27T10:40:55.753202Z","shell.execute_reply.started":"2023-12-27T10:40:36.747912Z","shell.execute_reply":"2023-12-27T10:40:55.752323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluate (with labels)\ntest_score = model.evaluate(sample_test_gen, verbose = 1)\nprint(f'Test loss = {test_score[0]}')\nprint(f'Test Accuracy = {test_score[1]}')","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:40:55.754363Z","iopub.execute_input":"2023-12-27T10:40:55.754658Z","iopub.status.idle":"2023-12-27T10:41:15.514617Z","shell.execute_reply.started":"2023-12-27T10:40:55.754631Z","shell.execute_reply":"2023-12-27T10:41:15.513711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate and print the classification report\nclassification_rep = classification_report(true_classes, predicted_classes, target_names=sample_test_gen.class_indices)\nprint(\"\\nClassification Report:\")\nprint(classification_rep)","metadata":{"execution":{"iopub.status.busy":"2023-12-27T10:41:15.515882Z","iopub.execute_input":"2023-12-27T10:41:15.516525Z","iopub.status.idle":"2023-12-27T10:41:15.532216Z","shell.execute_reply.started":"2023-12-27T10:41:15.516495Z","shell.execute_reply":"2023-12-27T10:41:15.531400Z"},"trusted":true},"execution_count":null,"outputs":[]}]}