{"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"}],"dockerImageVersionId":30627,"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","execution":{"iopub.status.busy":"2026-09-10T11:09:44.397880Z","iopub.execute_input":"2026-09-10T11:09:44.398928Z","iopub.status.idle":"2026-09-10T11:09:44.409634Z","shell.execute_reply.started":"2026-09-10T11:09:44.398895Z","shell.execute_reply":"2026-09-10T11:09:44.408423Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python --version","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:44.411523Z","iopub.execute_input":"2026-09-10T11:09:44.411925Z","iopub.status.idle":"2026-09-10T11:09:45.465210Z","shell.execute_reply.started":"2026-09-10T11:09:44.411889Z","shell.execute_reply":"2026-09-10T11:09:45.464228Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!uname --all","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:45.466894Z","iopub.execute_input":"2026-09-10T11:09:45.467225Z","iopub.status.idle":"2026-09-10T11:09:46.506584Z","shell.execute_reply.started":"2026-09-10T11:09:45.467198Z","shell.execute_reply":"2026-09-10T11:09:46.505617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nprint(os.listdir(\"../input\"))\n\nimport zipfile\n\nwith zipfile.ZipFile(\"/kaggle/input/dogs-vs-cats/test1.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"/kaggle/input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:09:46.508946Z","iopub.execute_input":"2026-09-10T11:09:46.509387Z","iopub.status.idle":"2026-09-10T11:09:56.600591Z","shell.execute_reply.started":"2026-09-10T11:09:46.509360Z","shell.execute_reply":"2026-09-10T11:09:56.599446Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:56.601843Z","iopub.execute_input":"2026-09-10T11:09:56.602168Z","iopub.status.idle":"2026-09-10T11:09:57.677075Z","shell.execute_reply.started":"2026-09-10T11:09:56.602141Z","shell.execute_reply":"2026-09-10T11:09:57.675743Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:57.678874Z","iopub.execute_input":"2026-09-10T11:09:57.679242Z","iopub.status.idle":"2026-09-10T11:09:58.781045Z","shell.execute_reply.started":"2026-09-10T11:09:57.679214Z","shell.execute_reply":"2026-09-10T11:09:58.779822Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#ls test1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:58.782839Z","iopub.execute_input":"2026-09-10T11:09:58.783250Z","iopub.status.idle":"2026-09-10T11:09:58.788237Z","shell.execute_reply.started":"2026-09-10T11:09:58.783216Z","shell.execute_reply":"2026-09-10T11:09:58.787329Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls test1/ | wc -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:58.789474Z","iopub.execute_input":"2026-09-10T11:09:58.789842Z","iopub.status.idle":"2026-09-10T11:09:59.878176Z","shell.execute_reply.started":"2026-09-10T11:09:58.789810Z","shell.execute_reply":"2026-09-10T11:09:59.877268Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls train/ | wc -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:09:59.879820Z","iopub.execute_input":"2026-09-10T11:09:59.880216Z","iopub.status.idle":"2026-09-10T11:10:00.994210Z","shell.execute_reply.started":"2026-09-10T11:09:59.880180Z","shell.execute_reply":"2026-09-10T11:10:00.993172Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#ls train/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:00.997933Z","iopub.execute_input":"2026-09-10T11:10:00.998207Z","iopub.status.idle":"2026-09-10T11:10:01.002732Z","shell.execute_reply.started":"2026-09-10T11:10:00.998183Z","shell.execute_reply":"2026-09-10T11:10:01.001696Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pwd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:01.003888Z","iopub.execute_input":"2026-09-10T11:10:01.004723Z","iopub.status.idle":"2026-09-10T11:10:01.015163Z","shell.execute_reply.started":"2026-09-10T11:10:01.004684Z","shell.execute_reply":"2026-09-10T11:10:01.014183Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:01.016269Z","iopub.execute_input":"2026-09-10T11:10:01.016576Z","iopub.status.idle":"2026-09-10T11:10:02.058180Z","shell.execute_reply.started":"2026-09-10T11:10:01.016553Z","shell.execute_reply":"2026-09-10T11:10:02.056984Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -U train | head -n 10","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:02.059727Z","iopub.execute_input":"2026-09-10T11:10:02.060151Z","iopub.status.idle":"2026-09-10T11:10:03.176422Z","shell.execute_reply.started":"2026-09-10T11:10:02.060124Z","shell.execute_reply":"2026-09-10T11:10:03.175025Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -U test1 | head -n 10","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:03.178434Z","iopub.execute_input":"2026-09-10T11:10:03.178880Z","iopub.status.idle":"2026-09-10T11:10:04.261569Z","shell.execute_reply.started":"2026-09-10T11:10:03.178840Z","shell.execute_reply":"2026-09-10T11:10:04.260314Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# plot dog photos from the dogs vs cats dataset\nfrom matplotlib import pyplot\n# from matplotlib import pyplot as plt\nfrom matplotlib.image import imread\n# define location of dataset\nfolder = 'train/'\n# plot first few images\nfor i in range(9):\n\t# define subplot\n\tpyplot.subplot(330 + 1 + i)\n\t# define filename\n\tfilename = folder + 'dog.' + str(i) + '.jpg'\n\t# load image pixels\n\timage = imread(filename)\n\t# plot raw pixel data\n\tpyplot.imshow(image)\n# show the figure\npyplot.show()","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:04.263856Z","iopub.execute_input":"2026-09-10T11:10:04.264248Z","iopub.status.idle":"2026-09-10T11:10:05.307252Z","shell.execute_reply.started":"2026-09-10T11:10:04.264214Z","shell.execute_reply":"2026-09-10T11:10:05.306356Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# plot cat photos from the dogs vs cats dataset\nfrom matplotlib import pyplot\nfrom matplotlib.image import imread\n# define location of dataset\nfolder = 'train/'\n# plot first few images\nfor i in range(9):\n\t# define subplot\n\tpyplot.subplot(330 + 1 + i)\n\t# define filename\n\tfilename = folder + 'cat.' + str(i) + '.jpg'\n\t# load image pixels\n\timage = imread(filename)\n\t# plot raw pixel data\n\tpyplot.imshow(image)\n# show the figure\npyplot.show()","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:05.308777Z","iopub.execute_input":"2026-09-10T11:10:05.309155Z","iopub.status.idle":"2026-09-10T11:10:06.277290Z","shell.execute_reply.started":"2026-09-10T11:10:05.309119Z","shell.execute_reply":"2026-09-10T11:10:06.276322Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python --version","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:06.278343Z","iopub.execute_input":"2026-09-10T11:10:06.278589Z","iopub.status.idle":"2026-09-10T11:10:07.321225Z","shell.execute_reply.started":"2026-09-10T11:10:06.278568Z","shell.execute_reply":"2026-09-10T11:10:07.320051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow\nprint(tensorflow.__version__)\n\nimport keras\nprint(keras.__version__)\n\nimport tensorflow.keras\nprint(tensorflow.__version__)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:07.323172Z","iopub.execute_input":"2026-09-10T11:10:07.323616Z","iopub.status.idle":"2026-09-10T11:10:07.329204Z","shell.execute_reply.started":"2026-09-10T11:10:07.323577Z","shell.execute_reply":"2026-09-10T11:10:07.328440Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load dogs vs cats dataset, reshape and save to a new file\nfrom os import listdir\nfrom numpy import asarray\nfrom numpy import save\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import img_to_array","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:07.330606Z","iopub.execute_input":"2026-09-10T11:10:07.331330Z","iopub.status.idle":"2026-09-10T11:10:07.338538Z","shell.execute_reply.started":"2026-09-10T11:10:07.331296Z","shell.execute_reply":"2026-09-10T11:10:07.337858Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# define location of dataset\nfolder = 'train/'\nphotos, labels = list(), list()\n# enumerate files in the directory\nfor file in listdir(folder):\n\t# determine class\n\toutput = 0.0\n\tif file.startswith('dog'):\n\t\toutput = 1.0\n\t# load image\n\tphoto = load_img(folder + file, target_size=(200, 200))\n\t# convert to numpy array\n\tphoto = img_to_array(photo)\n\t# store\n\tphotos.append(photo)\n\tlabels.append(output)\n# convert to a numpy arrays\nphotos = asarray(photos)\nlabels = asarray(labels)\nprint(photos.shape, labels.shape)\n# save the reshaped photos\nsave('dogs_vs_cats_photos.npy', photos)\nsave('dogs_vs_cats_labels.npy', labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-27T03:36:15.416611Z","iopub.execute_input":"2024-01-27T03:36:15.417128Z","iopub.status.idle":"2024-01-27T03:36:38.886396Z","shell.execute_reply.started":"2024-01-27T03:36:15.417101Z","shell.execute_reply":"2024-01-27T03:36:38.883149Z"}}},{"cell_type":"markdown","source":"# load and confirm the shape\nfrom numpy import load\nphotos = load('dogs_vs_cats_photos.npy')\nlabels = load('dogs_vs_cats_labels.npy')","metadata":{"execution":{"iopub.status.busy":"2024-01-27T03:36:38.88711Z","iopub.status.idle":"2024-01-27T03:36:38.887458Z","shell.execute_reply.started":"2024-01-27T03:36:38.887281Z","shell.execute_reply":"2024-01-27T03:36:38.887296Z"}}},{"cell_type":"code","source":"# organize dataset into a useful structure\nfrom os import makedirs\nfrom os import listdir\nfrom shutil import copyfile\nfrom random import seed\nfrom random import random","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:07.340959Z","iopub.execute_input":"2026-09-10T11:10:07.341486Z","iopub.status.idle":"2026-09-10T11:10:07.351578Z","shell.execute_reply.started":"2026-09-10T11:10:07.341451Z","shell.execute_reply":"2026-09-10T11:10:07.350861Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# create directories\ndataset_home = 'dataset_dogs_vs_cats/'\nsubdirs = ['train/', 'test/'] #test==>validation\nfor subdir in subdirs:\n    # create label subdirectories\n    labeldirs = ['dogs/', 'cats/']\n    for labldir in labeldirs:\n        newdir = dataset_home + subdir + labldir       \n        makedirs(newdir, exist_ok=True)\n        print(newdir)","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:07.352624Z","iopub.execute_input":"2026-09-10T11:10:07.353324Z","iopub.status.idle":"2026-09-10T11:10:07.369548Z","shell.execute_reply.started":"2026-09-10T11:10:07.353299Z","shell.execute_reply":"2026-09-10T11:10:07.368866Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -l dataset_dogs_vs_cats/train/dogs/ | wc -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:07.370763Z","iopub.execute_input":"2026-09-10T11:10:07.371044Z","iopub.status.idle":"2026-09-10T11:10:08.463294Z","shell.execute_reply.started":"2026-09-10T11:10:07.371021Z","shell.execute_reply":"2026-09-10T11:10:08.461916Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:08.465266Z","iopub.execute_input":"2026-09-10T11:10:08.465990Z","iopub.status.idle":"2026-09-10T11:10:09.516597Z","shell.execute_reply.started":"2026-09-10T11:10:08.465959Z","shell.execute_reply":"2026-09-10T11:10:09.515517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -l dataset_dogs_vs_cats/train","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:09.518100Z","iopub.execute_input":"2026-09-10T11:10:09.518426Z","iopub.status.idle":"2026-09-10T11:10:10.559168Z","shell.execute_reply.started":"2026-09-10T11:10:09.518399Z","shell.execute_reply":"2026-09-10T11:10:10.558018Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls -l dataset_dogs_vs_cats/test #validation","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:10.560830Z","iopub.execute_input":"2026-09-10T11:10:10.561164Z","iopub.status.idle":"2026-09-10T11:10:11.601474Z","shell.execute_reply.started":"2026-09-10T11:10:10.561137Z","shell.execute_reply":"2026-09-10T11:10:11.600046Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# seed random number generator\nseed(1337)\n# define ratio of pictures to use for validation\nval_ratio = 0.25 #changable\n# copy training dataset images into subdirectories\nsrc_directory = 'train/'\n\nfor file in listdir(src_directory):\n\tsrc = src_directory + '/' + file\n\tdst_dir = 'train/'\n\tif random() < val_ratio:\n\t\tdst_dir = 'test/'\n\tif file.startswith('cat'):\n\t\tdst = dataset_home + dst_dir + 'cats/'  + file\n\t\tcopyfile(src, dst)\n\telif file.startswith('dog'):\n\t\tdst = dataset_home + dst_dir + 'dogs/'  + file\n\t\tcopyfile(src, dst)","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:11.603402Z","iopub.execute_input":"2026-09-10T11:10:11.604304Z","iopub.status.idle":"2026-09-10T11:10:13.697593Z","shell.execute_reply.started":"2026-09-10T11:10:11.604274Z","shell.execute_reply":"2026-09-10T11:10:13.696762Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(src)\nprint(dst)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:13.698920Z","iopub.execute_input":"2026-09-10T11:10:13.699270Z","iopub.status.idle":"2026-09-10T11:10:13.705916Z","shell.execute_reply.started":"2026-09-10T11:10:13.699242Z","shell.execute_reply":"2026-09-10T11:10:13.704751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/dogs | wc -l\n!ls -l dataset_dogs_vs_cats/train/cats | wc -l","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:13.714050Z","iopub.execute_input":"2026-09-10T11:10:13.714687Z","iopub.status.idle":"2026-09-10T11:10:15.939166Z","shell.execute_reply.started":"2026-09-10T11:10:13.714645Z","shell.execute_reply":"2026-09-10T11:10:15.937922Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#validation set\n!ls -l dataset_dogs_vs_cats/test/dogs | wc -l\n!ls -l dataset_dogs_vs_cats/test/cats | wc -l","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:15.941114Z","iopub.execute_input":"2026-09-10T11:10:15.941392Z","iopub.status.idle":"2026-09-10T11:10:18.108643Z","shell.execute_reply.started":"2026-09-10T11:10:15.941367Z","shell.execute_reply":"2026-09-10T11:10:18.107673Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip -q install livelossplot==0.5.5","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:18.110247Z","iopub.execute_input":"2026-09-10T11:10:18.110962Z","iopub.status.idle":"2026-09-10T11:10:30.938741Z","shell.execute_reply.started":"2026-09-10T11:10:18.110934Z","shell.execute_reply":"2026-09-10T11:10:30.937320Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from livelossplot import PlotLossesKeras","metadata":{"execution":{"iopub.status.busy":"2026-09-10T11:10:30.940347Z","iopub.execute_input":"2026-09-10T11:10:30.940680Z","iopub.status.idle":"2026-09-10T11:10:30.958453Z","shell.execute_reply.started":"2026-09-10T11:10:30.940634Z","shell.execute_reply":"2026-09-10T11:10:30.957476Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Prepare Final Dataset","metadata":{}},{"cell_type":"markdown","source":"# Start tutorial\n# Develop a Baseline CNN Model","metadata":{}},{"cell_type":"code","source":"# https://keras.io/api/applications/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T11:10:30.959973Z","iopub.execute_input":"2026-09-10T11:10:30.960572Z","iopub.status.idle":"2026-09-10T11:10:30.965620Z","shell.execute_reply.started":"2026-09-10T11:10:30.960547Z","shell.execute_reply":"2026-09-10T11:10:30.964922Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# baseline model for the dogs vs cats dataset\nimport sys\nfrom matplotlib import pyplot\nfrom keras.utils import to_categorical\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D\nfrom keras.layers import MaxPooling2D\nfrom keras.layers import Dense\nfrom keras.layers import Dropout\nfrom keras.layers import Flatten\nfrom keras.optimizers import SGD\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\nfrom tensorflow.keras.preprocessing import image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:47:24.788574Z","iopub.execute_input":"2026-09-10T15:47:24.789424Z","iopub.status.idle":"2026-09-10T15:47:24.796339Z","shell.execute_reply.started":"2026-09-10T15:47:24.789380Z","shell.execute_reply":"2026-09-10T15:47:24.795094Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"callbacks = [\n    EarlyStopping(\n        monitor='val_accuracy',\n        mode='max',\n        patience=5,\n        restore_best_weights=True\n    ),\n    PlotLossesKeras()\n]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.061114Z","iopub.execute_input":"2026-09-10T15:12:22.061432Z","iopub.status.idle":"2026-09-10T15:12:22.080961Z","shell.execute_reply.started":"2026-09-10T15:12:22.061406Z","shell.execute_reply":"2026-09-10T15:12:22.080029Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = Sequential()\ntype(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.082181Z","iopub.execute_input":"2026-09-10T15:12:22.082493Z","iopub.status.idle":"2026-09-10T15:12:22.104477Z","shell.execute_reply.started":"2026-09-10T15:12:22.082450Z","shell.execute_reply":"2026-09-10T15:12:22.103221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = Sequential()\n\nmodel.add(Conv2D(32,\n                 (3, 3),\n                 activation='relu',\n                 input_shape=(200, 200, 3)\n                )\n         )\n\nmodel.add(MaxPooling2D((2, 2)))\n\nmodel.add(Flatten())\n\nmodel.add(Dense(128, activation='relu'))\n\nmodel.add(Dense(1, activation='sigmoid'))\n\nprint(model.summary())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.106701Z","iopub.execute_input":"2026-09-10T15:12:22.107162Z","iopub.status.idle":"2026-09-10T15:12:22.181911Z","shell.execute_reply.started":"2026-09-10T15:12:22.107133Z","shell.execute_reply":"2026-09-10T15:12:22.180962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = Sequential()\n\n# Layer 1\nmodel.add(Conv2D(\n    32,\n    (3, 3),\n    activation='relu',\n    padding='same',\n    input_shape=(200, 200, 3)\n))\nmodel.add(MaxPooling2D((2, 2)))\n\n# Layer 2\nmodel.add(Conv2D(\n    64,\n    (3, 3),\n    activation='relu',\n    padding='same'\n))\nmodel.add(MaxPooling2D((2, 2)))\n\n# Layer 3\nmodel.add(Conv2D(\n    128,\n    (3, 3),\n    activation='relu',\n    padding='same'\n))\nmodel.add(MaxPooling2D((2, 2)))\n\n# Classification\nmodel.add(Flatten())\n\nmodel.add(Dense(128, activation='relu'))\n\nmodel.add(Dense(2, activation='softmax'))\n\nprint(model.summary())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.183601Z","iopub.execute_input":"2026-09-10T15:12:22.184040Z","iopub.status.idle":"2026-09-10T15:12:22.294936Z","shell.execute_reply.started":"2026-09-10T15:12:22.184002Z","shell.execute_reply":"2026-09-10T15:12:22.293904Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# define cnn model\ndef define_model_1():\n    model = Sequential()\n\n    model.add(Conv2D(32, (3, 3),\n                     activation='relu',\n                     kernel_initializer='he_uniform',\n                     padding='same',\n                     input_shape=(200, 200, 3)))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Dropout(0.10))\n\n    model.add(Conv2D(64, (3, 3),\n                     activation='relu',\n                     kernel_initializer='he_uniform',\n                     padding='same'))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Dropout(0.10))\n\n    model.add(Conv2D(64, (3, 3),\n                     activation='relu',\n                     kernel_initializer='he_uniform',\n                     padding='same'))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Dropout(0.10))\n\n    model.add(Conv2D(128, (3, 3),\n                     activation='relu',\n                     kernel_initializer='he_uniform',\n                     padding='same'))\n    model.add(MaxPooling2D((2, 2)))\n    model.add(Dropout(0.10))\n\n    model.add(Flatten())\n\n    model.add(Dense(128,\n                    activation='relu',\n                    kernel_initializer='he_uniform'))\n    model.add(Dropout(0.20))\n\n    model.add(Dense(1, activation='sigmoid'))\n\n    # compile model\n    opt = SGD(learning_rate=0.001, momentum=0.9)\n\n    model.compile(\n        optimizer='adam',\n        loss='binary_crossentropy',\n        metrics=['accuracy']\n    )\n\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.296506Z","iopub.execute_input":"2026-09-10T15:12:22.296930Z","iopub.status.idle":"2026-09-10T15:12:22.311122Z","shell.execute_reply.started":"2026-09-10T15:12:22.296891Z","shell.execute_reply":"2026-09-10T15:12:22.310247Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_1 = define_model_1()\nprint(model_1.summary())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.312396Z","iopub.execute_input":"2026-09-10T15:12:22.313205Z","iopub.status.idle":"2026-09-10T15:12:22.483147Z","shell.execute_reply.started":"2026-09-10T15:12:22.313178Z","shell.execute_reply":"2026-09-10T15:12:22.478532Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# plot diagnostic learning curves\ndef summarize_diagnostics(history):\n    # plot loss\n    pyplot.subplot(211)\n    pyplot.title('Cross Entropy Loss')\n    pyplot.plot(history.history['loss'], color='blue', label='train')\n    pyplot.plot(history.history['val_loss'], color='orange', label='test')\n    # plot accuracy\n    pyplot.subplot(212)\n    pyplot.title('Classification Accuracy')\n    pyplot.plot(history.history['accuracy'], color='blue', label='train')\n    pyplot.plot(history.history['val_accuracy'], color='orange', label='test')\n    pyplot.show()\n    \n    # save plot to file\n    filename = sys.argv[0].split('/')[-1]\n    pyplot.savefig(filename + '_plot.png') \n    pyplot.close()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.484696Z","iopub.execute_input":"2026-09-10T15:12:22.485205Z","iopub.status.idle":"2026-09-10T15:12:22.491743Z","shell.execute_reply.started":"2026-09-10T15:12:22.485151Z","shell.execute_reply":"2026-09-10T15:12:22.490736Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# run the test harness for evaluating a model, not recommend to call this function\ndef run_test_harness():\n\t# define model\n\tmodel = define_model()\n\t# create data generator\n\tdatagen = ImageDataGenerator(rescale=1.0/255.0)\n\t# prepare iterators\n\ttrain_it = datagen.flow_from_directory('dataset_dogs_vs_cats/train/',\n\t\tclass_mode='binary', batch_size=64, target_size=(200, 200))\n\ttest_it = datagen.flow_from_directory('dataset_dogs_vs_cats/test/',\n\t\tclass_mode='binary', batch_size=64, target_size=(200, 200))\n\t# fit model\n\thistory = model.fit_generator(train_it, steps_per_epoch=len(train_it),\n\t\tvalidation_data=test_it, validation_steps=len(test_it), epochs=20, verbose=0)\n\t# evaluate model\n\t_, acc = model.evaluate_generator(test_it, steps=len(test_it), verbose=0)\n\tprint('> %.3f' % (acc * 100.0))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.496230Z","iopub.execute_input":"2026-09-10T15:12:22.496709Z","iopub.status.idle":"2026-09-10T15:12:22.510421Z","shell.execute_reply.started":"2026-09-10T15:12:22.496652Z","shell.execute_reply":"2026-09-10T15:12:22.509201Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_1 = define_model_1()\nprint(model_1.summary())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.511764Z","iopub.execute_input":"2026-09-10T15:12:22.512149Z","iopub.status.idle":"2026-09-10T15:12:22.672513Z","shell.execute_reply.started":"2026-09-10T15:12:22.512123Z","shell.execute_reply":"2026-09-10T15:12:22.671516Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"datagen = ImageDataGenerator(\n    rescale=1.0/255.0,  \n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.674086Z","iopub.execute_input":"2026-09-10T15:12:22.674484Z","iopub.status.idle":"2026-09-10T15:12:22.679909Z","shell.execute_reply.started":"2026-09-10T15:12:22.674443Z","shell.execute_reply":"2026-09-10T15:12:22.678821Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(train_it.class_indices)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T16:11:37.937414Z","iopub.execute_input":"2026-09-10T16:11:37.938166Z","iopub.status.idle":"2026-09-10T16:11:37.943229Z","shell.execute_reply.started":"2026-09-10T16:11:37.938131Z","shell.execute_reply":"2026-09-10T16:11:37.942068Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls dataset_dogs_vs_cats/train/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:22.681228Z","iopub.execute_input":"2026-09-10T15:12:22.681874Z","iopub.status.idle":"2026-09-10T15:12:23.842323Z","shell.execute_reply.started":"2026-09-10T15:12:22.681838Z","shell.execute_reply":"2026-09-10T15:12:23.841062Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Hyperparameter => changable\nIMAGE_SIZE = (200, 200)\nBATCH_SIE = 64\nEPOCHS = 20","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:23.844427Z","iopub.execute_input":"2026-09-10T15:12:23.844899Z","iopub.status.idle":"2026-09-10T15:12:23.851103Z","shell.execute_reply.started":"2026-09-10T15:12:23.844856Z","shell.execute_reply":"2026-09-10T15:12:23.850163Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_it = datagen.flow_from_directory('dataset_dogs_vs_cats/train/',\n\t\tclass_mode='binary',\n        batch_size=BATCH_SIE, \n        target_size=IMAGE_SIZE\n)\ntype(train_it)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:23.852454Z","iopub.execute_input":"2026-09-10T15:12:23.852969Z","iopub.status.idle":"2026-09-10T15:12:24.406873Z","shell.execute_reply.started":"2026-09-10T15:12:23.852941Z","shell.execute_reply":"2026-09-10T15:12:24.405717Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(train_it), len(train_it.classes), train_it.classes[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:24.408241Z","iopub.execute_input":"2026-09-10T15:12:24.408891Z","iopub.status.idle":"2026-09-10T15:12:24.416699Z","shell.execute_reply.started":"2026-09-10T15:12:24.408852Z","shell.execute_reply":"2026-09-10T15:12:24.415347Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_it = datagen.flow_from_directory('dataset_dogs_vs_cats/test/',\n\t\tclass_mode='binary',\n        batch_size=BATCH_SIE,\n        target_size=IMAGE_SIZE\n)\ntype(val_it)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:24.418160Z","iopub.execute_input":"2026-09-10T15:12:24.418561Z","iopub.status.idle":"2026-09-10T15:12:24.636215Z","shell.execute_reply.started":"2026-09-10T15:12:24.418533Z","shell.execute_reply":"2026-09-10T15:12:24.635323Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(val_it), len(val_it.classes), val_it.classes[-10:]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:24.637570Z","iopub.execute_input":"2026-09-10T15:12:24.637992Z","iopub.status.idle":"2026-09-10T15:12:24.646024Z","shell.execute_reply.started":"2026-09-10T15:12:24.637958Z","shell.execute_reply":"2026-09-10T15:12:24.644722Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# fit model\nmodel_1.reset_states()\nhistory_1 = model_1.fit(\n    train_it,\n    steps_per_epoch=len(train_it),\n    validation_data=val_it,\n    validation_steps=len(val_it),\n    epochs=25,\n    verbose=2,\n    callbacks = callbacks\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:12:24.647525Z","iopub.execute_input":"2026-09-10T15:12:24.647852Z","iopub.status.idle":"2026-09-10T15:29:59.223031Z","shell.execute_reply.started":"2026-09-10T15:12:24.647826Z","shell.execute_reply":"2026-09-10T15:29:59.221891Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"best_epoch = np.argmax(history_1.history['val_accuracy']) + 1\nbest_val_acc = max(history_1.history['val_accuracy'])\n\nprint(\"Best Epoch:\", best_epoch)\nprint(\"Best Validation Accuracy:\", best_val_acc)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:29:59.224460Z","iopub.execute_input":"2026-09-10T15:29:59.224865Z","iopub.status.idle":"2026-09-10T15:29:59.231792Z","shell.execute_reply.started":"2026-09-10T15:29:59.224817Z","shell.execute_reply":"2026-09-10T15:29:59.231004Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\n# สุ่ม 10 รูป\nindices = np.random.choice(len(test_images), 10, replace=False)\n\n# Predict\npredictions = model_1.predict(test_images[indices])\n\n# แปลงผลเป็น class 0 หรือ 1\npredicted_classes = (predictions.ravel() >= 0.5).astype(int)\n\n# แสดงรูป\nfig, axs = plt.subplots(2, 5, figsize=(15, 6))\n\nfor i in range(10):\n    axs[i // 5, i % 5].imshow(test_images[indices[i]])\n    axs[i // 5, i % 5].set_title(\n        f\"Pred: {predicted_classes[i]}\"\n    )\n    axs[i // 5, i % 5].axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T16:16:16.662520Z","iopub.execute_input":"2026-09-10T16:16:16.662934Z","iopub.status.idle":"2026-09-10T16:16:18.165106Z","shell.execute_reply.started":"2026-09-10T16:16:16.662904Z","shell.execute_reply":"2026-09-10T16:16:18.163769Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# learning curves\nsummarize_diagnostics(history_1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:29:59.233101Z","iopub.execute_input":"2026-09-10T15:29:59.233848Z","iopub.status.idle":"2026-09-10T15:29:59.658969Z","shell.execute_reply.started":"2026-09-10T15:29:59.233817Z","shell.execute_reply":"2026-09-10T15:29:59.658078Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# evaluate model\n_, acc = model_1.evaluate(val_it, steps=len(val_it), verbose=1)\nprint('> %.3f' % (acc * 100.0))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:29:59.660719Z","iopub.execute_input":"2026-09-10T15:29:59.661033Z","iopub.status.idle":"2026-09-10T15:30:12.503507Z","shell.execute_reply.started":"2026-09-10T15:29:59.661007Z","shell.execute_reply":"2026-09-10T15:30:12.502567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:12.509276Z","iopub.execute_input":"2026-09-10T15:30:12.509577Z","iopub.status.idle":"2026-09-10T15:30:13.634613Z","shell.execute_reply.started":"2026-09-10T15:30:12.509553Z","shell.execute_reply":"2026-09-10T15:30:13.633254Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pwd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.636402Z","iopub.execute_input":"2026-09-10T15:30:13.636816Z","iopub.status.idle":"2026-09-10T15:30:13.646038Z","shell.execute_reply.started":"2026-09-10T15:30:13.636786Z","shell.execute_reply":"2026-09-10T15:30:13.644938Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom glob import glob\n\n# Define the image folder path\nimage_folder = '/kaggle/working/test1'\n\n# List all .jpg files in the directory (adjust the pattern if needed)\nimage_files = glob(os.path.join(image_folder, '*.jpg'))\n\n# Check if images were found\nif not image_files:\n    print(\"No images found. Please verify the directory and file extensions.\")\n    \n# Create a DataFrame with the file paths\ndf = pd.DataFrame({'filename': image_files})\n\n# If your use-case doesn't require labels (for example, during testing), you can leave out the label column.\n# Otherwise, if you need a dummy label, you can add one:\n# df['class'] = 'dummy_label'\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.647599Z","iopub.execute_input":"2026-09-10T15:30:13.647939Z","iopub.status.idle":"2026-09-10T15:30:13.690814Z","shell.execute_reply.started":"2026-09-10T15:30:13.647915Z","shell.execute_reply":"2026-09-10T15:30:13.689952Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.691829Z","iopub.execute_input":"2026-09-10T15:30:13.692197Z","iopub.status.idle":"2026-09-10T15:30:13.699219Z","shell.execute_reply.started":"2026-09-10T15:30:13.692173Z","shell.execute_reply":"2026-09-10T15:30:13.697941Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image_files[:5], type(image_files), len(image_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.700520Z","iopub.execute_input":"2026-09-10T15:30:13.700901Z","iopub.status.idle":"2026-09-10T15:30:13.713394Z","shell.execute_reply.started":"2026-09-10T15:30:13.700877Z","shell.execute_reply":"2026-09-10T15:30:13.712296Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.715041Z","iopub.execute_input":"2026-09-10T15:30:13.715432Z","iopub.status.idle":"2026-09-10T15:30:13.738620Z","shell.execute_reply.started":"2026-09-10T15:30:13.715398Z","shell.execute_reply":"2026-09-10T15:30:13.737641Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.loc[1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.740086Z","iopub.execute_input":"2026-09-10T15:30:13.740829Z","iopub.status.idle":"2026-09-10T15:30:13.748033Z","shell.execute_reply.started":"2026-09-10T15:30:13.740799Z","shell.execute_reply":"2026-09-10T15:30:13.746973Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.sample(5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.749458Z","iopub.execute_input":"2026-09-10T15:30:13.750180Z","iopub.status.idle":"2026-09-10T15:30:13.762176Z","shell.execute_reply.started":"2026-09-10T15:30:13.750150Z","shell.execute_reply":"2026-09-10T15:30:13.761114Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df['filename']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.763490Z","iopub.execute_input":"2026-09-10T15:30:13.763905Z","iopub.status.idle":"2026-09-10T15:30:13.776965Z","shell.execute_reply.started":"2026-09-10T15:30:13.763856Z","shell.execute_reply":"2026-09-10T15:30:13.775762Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_SIZE = (200, 200)\n\n# datagen = ImageDataGenerator(rescale=1.0/255.0,\n#                             horizontal_flip=True,)\n# print(IMAGE_SIZE)\n# # prepare iterators\n# train_it = datagen.flow_from_directory('dataset_dogs_vs_cats/train/',\n#     class_mode='binary', batch_size=64, target_size=IMAGE_SIZE )\n\n# val_it = datagen.flow_from_directory('dataset_dogs_vs_cats/test/',\n#     class_mode='binary', batch_size=64, target_size=IMAGE_SIZE )\n\n# Prediction\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Initialize your ImageDataGenerator (modify parameters as needed)\ndatagen_test = ImageDataGenerator(rescale=1./255,\n                                 vertical_flip=True)\n\n# Create the data generator using the DataFrame\ntest_it = datagen_test.flow_from_dataframe(\n    dataframe=df,\n    x_col='filename',\n    y_col=None,            # No labels for testing, so set to None\n    target_size=IMAGE_SIZE,\n    batch_size=64,\n    class_mode=None,       # Since there are no labels\n    # shuffle=True,         # Usually testing data should not be shuffled\n    shuffle=False,\n)\n\ntype(test_it)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.778198Z","iopub.execute_input":"2026-09-10T15:30:13.778718Z","iopub.status.idle":"2026-09-10T15:30:13.876203Z","shell.execute_reply.started":"2026-09-10T15:30:13.778648Z","shell.execute_reply":"2026-09-10T15:30:13.875277Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n\ndef plot_exmaple(images, labels):\n    # Assuming images shape is (64, height, width, channels)\n    fig, axes = plt.subplots(8, 8, figsize=(16, 16))\n    axes = axes.flatten()  # Flatten the 8x8 grid into a 1D array for easy iteration\n\n    for i, ax in enumerate(axes):\n        if i < len(images):\n            ax.imshow(images[i])\n            ax.set_title(str(labels[i]))  # Fixed: set_title instead of title\n            ax.axis(\"off\")  # Turn off axis ticks/labels for clarity\n        else:\n            ax.axis(\"off\")  # Hide unused subplots if images < 64\n\n    plt.tight_layout()\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.877371Z","iopub.execute_input":"2026-09-10T15:30:13.877736Z","iopub.status.idle":"2026-09-10T15:30:13.884288Z","shell.execute_reply.started":"2026-09-10T15:30:13.877698Z","shell.execute_reply":"2026-09-10T15:30:13.883142Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_images, train_labels = train_it.__next__()\nprint(train_images.shape, len(train_labels))\nplot_exmaple(train_images, train_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:13.885777Z","iopub.execute_input":"2026-09-10T15:30:13.887906Z","iopub.status.idle":"2026-09-10T15:30:20.148865Z","shell.execute_reply.started":"2026-09-10T15:30:13.887866Z","shell.execute_reply":"2026-09-10T15:30:20.147569Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_images, val_labels = val_it.__next__()\nval_images.shape\nplot_exmaple(val_images, val_labels)\nval_labels[:8]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:20.150354Z","iopub.execute_input":"2026-09-10T15:30:20.150741Z","iopub.status.idle":"2026-09-10T15:30:26.362390Z","shell.execute_reply.started":"2026-09-10T15:30:20.150713Z","shell.execute_reply":"2026-09-10T15:30:26.361012Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_exmaple_test(images, indices):\n    # Assuming images shape is (64, height, width, channels)\n    fig, axes = plt.subplots(8, 8, figsize=(16, 16))\n    axes = axes.flatten()  # Flatten the 8x8 grid into a 1D array for easy iteration\n\n    for i, ax in enumerate(axes):\n        if i < len(images):\n            ax.imshow(images[i])\n            ax.set_title(str(indices[i]))  # ตั้งค่า title ด้วย index จาก list/array indices\n            ax.axis(\"off\")  # Turn off axis ticks/labels for clarity\n        else:\n            ax.axis(\"off\")  # Hide unused subplots if images < 64\n\n    plt.tight_layout()\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:26.363979Z","iopub.execute_input":"2026-09-10T15:30:26.364345Z","iopub.status.idle":"2026-09-10T15:30:26.370963Z","shell.execute_reply.started":"2026-09-10T15:30:26.364317Z","shell.execute_reply":"2026-09-10T15:30:26.369618Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_images = test_it.__next__()  # หรือ next(test_it)\n\n# สร้าง list เลขดัชนีตามจำนวนภาพที่มี\nindices = list(range(len(test_images)))\n\nplot_exmaple_test(test_images, indices)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:26.372250Z","iopub.execute_input":"2026-09-10T15:30:26.372838Z","iopub.status.idle":"2026-09-10T15:30:31.837990Z","shell.execute_reply.started":"2026-09-10T15:30:26.372808Z","shell.execute_reply":"2026-09-10T15:30:31.835399Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Predict\npreds = model_1.predict(test_it, verbose=1)\ntype(preds), preds.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:31.839706Z","iopub.execute_input":"2026-09-10T15:30:31.840070Z","iopub.status.idle":"2026-09-10T15:30:55.034719Z","shell.execute_reply.started":"2026-09-10T15:30:31.840039Z","shell.execute_reply":"2026-09-10T15:30:55.033523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preds[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:55.036224Z","iopub.execute_input":"2026-09-10T15:30:55.036618Z","iopub.status.idle":"2026-09-10T15:30:55.045208Z","shell.execute_reply.started":"2026-09-10T15:30:55.036580Z","shell.execute_reply":"2026-09-10T15:30:55.044287Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(np.unique(preds, return_counts=True))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T16:00:47.872810Z","iopub.execute_input":"2026-09-10T16:00:47.873148Z","iopub.status.idle":"2026-09-10T16:00:47.885269Z","shell.execute_reply.started":"2026-09-10T16:00:47.873126Z","shell.execute_reply":"2026-09-10T16:00:47.884026Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\n\nclass_names = [\"Cat\", \"Dog\"]\n# 1. สุ่ม index มา 10 ตัวจากชุดข้อมูล\nsample_indices = np.random.choice(len(test_images), size=10, replace=False)\nsample_images = test_images[sample_indices]\n\n# 2. Predict \npredictions = model_1.predict(sample_images)\npredicted_classes = (predictions.ravel() >= 0.5).astype(int)  # ดึง class ที่ได้คะแนนสูงสุด\n\n# 3. แสดงผล 10 ภาพ (ปรับเป็น grid 2x5)\nfig, axes = plt.subplots(2, 5, figsize=(15, 6))\naxes = axes.flatten()\n\nfor i, ax in enumerate(axes):\n    ax.imshow(sample_images[i])\n    # แสดง Index เดิม และ Class ที่ทายได้\n    ax.set_title(\n    f\"Idx: {sample_indices[i]}\\n\"\n    f\"Pred: {class_names[predicted_classes[i]]}\"\n)\n    ax.axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T16:13:49.394530Z","iopub.execute_input":"2026-09-10T16:13:49.395568Z","iopub.status.idle":"2026-09-10T16:13:50.807840Z","shell.execute_reply.started":"2026-09-10T16:13:49.395531Z","shell.execute_reply":"2026-09-10T16:13:50.806758Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# end of 2026-09-06\nstop here","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.369957Z","iopub.execute_input":"2026-09-10T15:30:56.370317Z","iopub.status.idle":"2026-09-10T15:30:56.377924Z","shell.execute_reply.started":"2026-09-10T15:30:56.370285Z","shell.execute_reply":"2026-09-10T15:30:56.375877Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Transfer Learning","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.378953Z","iopub.status.idle":"2026-09-10T15:30:56.379337Z","shell.execute_reply.started":"2026-09-10T15:30:56.379169Z","shell.execute_reply":"2026-09-10T15:30:56.379186Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Create transfer learning model for VGG16\nimport sys\nfrom matplotlib import pyplot\nfrom keras.utils import to_categorical\nfrom keras.applications.vgg16 import VGG16\nfrom keras.models import Model\nfrom keras.layers import Dense\nfrom keras.layers import Flatten\nfrom keras.optimizers import SGD\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# define cnn model\ndef define_model_vgg16():\n\t# load model\n\tmodel = VGG16(include_top=False, input_shape=(224, 224, 3))\n\t# mark loaded layers as not trainable\n\tfor layer in model.layers:\n\t\tlayer.trainable = False\n\t# add new classifier layers\n\tflat1 = Flatten()(model.layers[-1].output)\n\tclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)\n\toutput = Dense(1, activation='sigmoid')(class1)\n\t# define new model\n\tmodel = Model(inputs=model.inputs, outputs=output)\n\t# compile model\n\topt = SGD(lr=0.001, momentum=0.9)\n\tmodel.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n\treturn model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.381353Z","iopub.status.idle":"2026-09-10T15:30:56.382013Z","shell.execute_reply.started":"2026-09-10T15:30:56.381829Z","shell.execute_reply":"2026-09-10T15:30:56.381849Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load model\n# model = VGG16(include_top=False, input_shape=(224, 224, 3))\n# mark loaded layers as not trainable\n# for layer in model.layers:\n#     layer.trainable = False\n\n# print(model.layers[-1].output)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.383256Z","iopub.status.idle":"2026-09-10T15:30:56.384481Z","shell.execute_reply.started":"2026-09-10T15:30:56.384197Z","shell.execute_reply":"2026-09-10T15:30:56.384225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load model\n# model_16_feature_extractor = VGG16(include_top=False, input_shape=(224, 224, 3))\n# model_16_feature_extractor.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.385478Z","iopub.status.idle":"2026-09-10T15:30:56.386002Z","shell.execute_reply.started":"2026-09-10T15:30:56.385735Z","shell.execute_reply":"2026-09-10T15:30:56.385760Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# for index, layer in enumerate(model_16_feature_extractor.layers):\n# \t\tprint(index, layer.trainable)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.387021Z","iopub.status.idle":"2026-09-10T15:30:56.387514Z","shell.execute_reply.started":"2026-09-10T15:30:56.387257Z","shell.execute_reply":"2026-09-10T15:30:56.387281Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load model\n# model_16_top = VGG16(include_top=True, input_shape=(224, 224, 3))\n# model_16_top.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.389017Z","iopub.status.idle":"2026-09-10T15:30:56.389482Z","shell.execute_reply.started":"2026-09-10T15:30:56.389229Z","shell.execute_reply":"2026-09-10T15:30:56.389251Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"vgg16_model = define_model_vgg16()\nvgg16_model.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.390898Z","iopub.status.idle":"2026-09-10T15:30:56.391182Z","shell.execute_reply.started":"2026-09-10T15:30:56.391044Z","shell.execute_reply":"2026-09-10T15:30:56.391058Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# for index, layer in enumerate(vgg16_model.layers):\n#     print(index, layer.name, layer.trainable)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.392205Z","iopub.status.idle":"2026-09-10T15:30:56.392548Z","shell.execute_reply.started":"2026-09-10T15:30:56.392394Z","shell.execute_reply":"2026-09-10T15:30:56.392410Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# for index, layer in enumerate(vgg16_model.layers[-7:]):\n#     print(index, layer.name, layer.trainable)\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.393942Z","iopub.status.idle":"2026-09-10T15:30:56.394457Z","shell.execute_reply.started":"2026-09-10T15:30:56.394202Z","shell.execute_reply":"2026-09-10T15:30:56.394226Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# for index, layer in enumerate(vgg16_model.layers[-7:]):\n#     layer.trainable = True\n#     print(index, layer.name, layer.trainable)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.396060Z","iopub.status.idle":"2026-09-10T15:30:56.396571Z","shell.execute_reply.started":"2026-09-10T15:30:56.396295Z","shell.execute_reply":"2026-09-10T15:30:56.396324Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# for index, layer in enumerate(vgg16_model.layers):\n#     if index >= 15:\n#         layer.trainable = True\n\n# for index, layer in enumerate(vgg16_model.layers):\n#     print(index, layer.name, layer.trainable)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.397845Z","iopub.status.idle":"2026-09-10T15:30:56.398297Z","shell.execute_reply.started":"2026-09-10T15:30:56.398066Z","shell.execute_reply":"2026-09-10T15:30:56.398088Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"id(vgg16_model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.400009Z","iopub.status.idle":"2026-09-10T15:30:56.400456Z","shell.execute_reply.started":"2026-09-10T15:30:56.400225Z","shell.execute_reply":"2026-09-10T15:30:56.400247Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# fit model\nprint(id(vgg16_model))\nvgg16_model.reset_states()\nvgg16_model_history = vgg16_model.fit(\n    train_it, \n    steps_per_epoch=len(train_it),\n    validation_data=val_it,\n    validation_steps=len(val_it),\n    epochs=3, verbose=1,\n    callbacks = [PlotLossesKeras()]\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.402369Z","iopub.status.idle":"2026-09-10T15:30:56.402932Z","shell.execute_reply.started":"2026-09-10T15:30:56.402625Z","shell.execute_reply":"2026-09-10T15:30:56.402687Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# learning curves\nsummarize_diagnostics(vgg16_model_history)\n\n# evaluate model\n_, acc = vgg16_model.evaluate_generator(val_it, steps=len(val_it), verbose=1)\nprint('Val: > %.3f' % (acc * 100.0))\n\n# evaluate model\n_, acc = vgg16_model.evaluate_generator(test_it, steps=len(test_it), verbose=1)\nprint('Test: > %.3f' % (acc * 100.0))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.404100Z","iopub.status.idle":"2026-09-10T15:30:56.404569Z","shell.execute_reply.started":"2026-09-10T15:30:56.404322Z","shell.execute_reply":"2026-09-10T15:30:56.404345Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from keras.applications.inception_v3 import InceptionV3\n\ndef define_model_inceptionv3():\n    # load model\n    model = InceptionV3(include_top=False, input_shape=(299, 299, 3))\n    # mark loaded layers as not trainable\n    for layer in model.layers:\n        layer.trainable = False\n        # layer.trainable = True #try to test\n    \n    # add new classifier layers\n    flat1 = Flatten()(model.layers[-1].output)\n    class1 = Dense(1024, activation='relu', kernel_initializer='he_uniform')(flat1)\n    class2 = Dense(512, activation='relu', kernel_initializer='he_uniform')(class1)\n    class3 = Dense(256, activation='relu', kernel_initializer='he_uniform')(class2)\n    class4 = Dense(128, activation='relu', kernel_initializer='he_uniform')(class3)\n    # output = Dense(1, activation='sigmoid')(flat1)\n    output = Dense(2, activation='softmax')(class4)\n    # define new model\n    model = Model(inputs=model.inputs, outputs=output)\n    # compile model\n    opt = SGD(lr=0.001, momentum=0.9)\n    model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.406166Z","iopub.status.idle":"2026-09-10T15:30:56.406688Z","shell.execute_reply.started":"2026-09-10T15:30:56.406407Z","shell.execute_reply":"2026-09-10T15:30:56.406430Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_inceptionv3 = define_model_inceptionv3()\nprint(id(model_inceptionv3))\n# model_inceptionv3.summary()","metadata":{"execution":{"iopub.status.busy":"2026-09-10T15:30:56.408220Z","iopub.status.idle":"2026-09-10T15:30:56.408737Z","shell.execute_reply.started":"2026-09-10T15:30:56.408448Z","shell.execute_reply":"2026-09-10T15:30:56.408470Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom tensorflow.keras import backend as K\n\ntrainable_params = int(np.sum([K.count_params(w) for w in model_inceptionv3.trainable_weights]))\nprint(trainable_params)\n","metadata":{"trusted":true,"scrolled":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.410310Z","iopub.status.idle":"2026-09-10T15:30:56.410827Z","shell.execute_reply.started":"2026-09-10T15:30:56.410534Z","shell.execute_reply":"2026-09-10T15:30:56.410557Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import backend as K\n\nfor w in model_inceptionv3.trainable_weights:\n    print(w.name, K.count_params(w))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.412970Z","iopub.status.idle":"2026-09-10T15:30:56.413319Z","shell.execute_reply.started":"2026-09-10T15:30:56.413168Z","shell.execute_reply":"2026-09-10T15:30:56.413184Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# fit model\nmodel_inceptionv3.reset_states()\nhistory_inceptionv3 = model_inceptionv3.fit(\n    train_it, \n    steps_per_epoch=len(train_it),\n    validation_data=val_it,\n    validation_steps=len(val_it),\n    epochs=3, verbose=1,\n    callbacks = [PlotLossesKeras()]\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.414476Z","iopub.status.idle":"2026-09-10T15:30:56.414831Z","shell.execute_reply.started":"2026-09-10T15:30:56.414616Z","shell.execute_reply":"2026-09-10T15:30:56.414637Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\ndef plot_images_with_labels(images, labels, train_log, set_label, save=False):\n    \"\"\"\n    Plots a grid of images with their corresponding labels and saves the figure.\n    \n    Args:\n    - images (list or np.array): List of images to be displayed.\n    - labels (np.array): Array of one-hot encoded labels.\n    - train_log (str): The directory or log name to save the plot.\n    - set_label (str): The specific set label (e.g., \"train\", \"validation\", etc.).\n    - config (dict): Configuration dictionary containing image dimensions.\n    \n    Returns:\n    - None: Displays and saves the plot.\n    \"\"\"\n    # Convert one-hot encoded labels to class indices\n    class_indices = labels\n\n    # Create subplots\n    fig, axes = plt.subplots(3, 4, figsize=(14, 10), dpi=120)\n    axes = axes.flatten()\n\n    for img, label_idx, ax in zip(images, class_indices, axes):\n        # Undo any preprocessing (like rescaling for pre-trained models)\n        if np.max(img) == 1:\n            img = img * 255\n\n        # Display the image\n        img_shape = (224, 224, 3)\n        ax.imshow(img.astype(\"uint8\"))\n        # ax.imshow(img)\n\n        # Set the title to the corresponding class label\n        ax.set_title(f\"Label: {label_idx}\", fontsize=18)\n        ax.axis('on')\n\n    # Set the overall title for the figure\n    plot_title = f\"{train_log}-{set_label}\"\n    plt.suptitle(plot_title, fontsize=18)\n\n    # Show the plot\n    plt.show()\n\n    # Save the figure\n    if save:\n        plot_file = os.path.join(train_log, f\"{plot_title}.png\")\n        fig.savefig(plot_file, dpi=120)\n        print(f'Saved {plot_file}')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.416220Z","iopub.status.idle":"2026-09-10T15:30:56.416539Z","shell.execute_reply.started":"2026-09-10T15:30:56.416385Z","shell.execute_reply":"2026-09-10T15:30:56.416400Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# plot_images_with_labels(images, labels, \"Dog-Cat\", \"Training\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.418303Z","iopub.status.idle":"2026-09-10T15:30:56.418579Z","shell.execute_reply.started":"2026-09-10T15:30:56.418445Z","shell.execute_reply":"2026-09-10T15:30:56.418459Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# for index, layer in enumerate(model.layers):\n#     print(index, layer.output.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.420033Z","iopub.status.idle":"2026-09-10T15:30:56.420369Z","shell.execute_reply.started":"2026-09-10T15:30:56.420218Z","shell.execute_reply":"2026-09-10T15:30:56.420233Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # mark loaded layers as not trainable\n# for index, layer in enumerate(model.layers[:15]):\n#     print(index, layer.name, layer.output_shape)\n#     layer.trainable = False\n    \n# for index, layer in enumerate(model.layers[15:]):\n#     print(index, layer.name, layer.output_shape)\n#     layer.trainable = True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.421870Z","iopub.status.idle":"2026-09-10T15:30:56.422208Z","shell.execute_reply.started":"2026-09-10T15:30:56.422058Z","shell.execute_reply":"2026-09-10T15:30:56.422073Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# evaluate model\n_, acc = model_inceptionv3.evaluate(test_it, steps=len(test_it), verbose=1)\nprint('> %.3f' % (acc * 100.0))\n# learning curves\n# summarize_diagnostics(history)\n\n# best_model = 'vgg16_model.hdf5'\n# my_model.save(best_model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.423938Z","iopub.status.idle":"2026-09-10T15:30:56.424233Z","shell.execute_reply.started":"2026-09-10T15:30:56.424090Z","shell.execute_reply":"2026-09-10T15:30:56.424104Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images = test_it.__next__()\nimages.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.425465Z","iopub.status.idle":"2026-09-10T15:30:56.425812Z","shell.execute_reply.started":"2026-09-10T15:30:56.425606Z","shell.execute_reply":"2026-09-10T15:30:56.425619Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 5 first img: 1, 0, 1, 1, 0\nimages_to_predict = images[:5]\nimages_to_predict.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.427191Z","iopub.status.idle":"2026-09-10T15:30:56.427563Z","shell.execute_reply.started":"2026-09-10T15:30:56.427388Z","shell.execute_reply":"2026-09-10T15:30:56.427405Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"probs = model_inceptionv3.predict(images_to_predict, verbose=1)\nprobs","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-10T15:30:56.429575Z","iopub.status.idle":"2026-09-10T15:30:56.429942Z","shell.execute_reply.started":"2026-09-10T15:30:56.429786Z","shell.execute_reply":"2026-09-10T15:30:56.429802Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Make Prediction","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}