{"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":30887,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:28.946307Z","iopub.execute_input":"2025-02-10T11:55:28.946597Z","iopub.status.idle":"2025-02-10T11:55:28.956319Z","shell.execute_reply.started":"2025-02-10T11:55:28.946576Z","shell.execute_reply":"2025-02-10T11:55:28.955342Z"}},"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:28.957369Z","iopub.execute_input":"2025-02-10T11:55:28.957664Z","iopub.status.idle":"2025-02-10T11:55:38.049902Z","shell.execute_reply.started":"2025-02-10T11:55:28.957644Z","shell.execute_reply":"2025-02-10T11:55:38.049223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# plot dog 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 + '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":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:38.051273Z","iopub.execute_input":"2025-02-10T11:55:38.051564Z","iopub.status.idle":"2025-02-10T11:55:39.917261Z","shell.execute_reply.started":"2025-02-10T11:55:38.051521Z","shell.execute_reply":"2025-02-10T11:55:39.916436Z"}},"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:39.918550Z","iopub.execute_input":"2025-02-10T11:55:39.918829Z","iopub.status.idle":"2025-02-10T11:55:40.745975Z","shell.execute_reply.started":"2025-02-10T11:55:39.918803Z","shell.execute_reply":"2025-02-10T11:55:40.744972Z"}},"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\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:40.746926Z","iopub.execute_input":"2025-02-10T11:55:40.747234Z","iopub.status.idle":"2025-02-10T11:55:40.751942Z","shell.execute_reply.started":"2025-02-10T11:55:40.747207Z","shell.execute_reply":"2025-02-10T11:55:40.751220Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:40.752875Z","iopub.execute_input":"2025-02-10T11:55:40.753174Z","iopub.status.idle":"2025-02-10T11:55:40.771317Z","shell.execute_reply.started":"2025-02-10T11:55:40.753145Z","shell.execute_reply":"2025-02-10T11:55:40.770621Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# create directories\ndataset_home = 'dataset_dogs_vs_cats/'\nsubdirs = ['train/', 'test/']\nfor subdir in subdirs:\n\t# create label subdirectories\n\tlabeldirs = ['dogs/', 'cats/']\n\tfor labldir in labeldirs:\n\t\tnewdir = dataset_home + subdir + labldir\n\t\tmakedirs(newdir, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:40.772136Z","iopub.execute_input":"2025-02-10T11:55:40.772440Z","iopub.status.idle":"2025-02-10T11:55:40.787275Z","shell.execute_reply.started":"2025-02-10T11:55:40.772394Z","shell.execute_reply":"2025-02-10T11:55:40.786525Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# seed random number generator\nseed(1)\n# define ratio of pictures to use for validation\nval_ratio = 0.25\n# copy training dataset images into subdirectories\nsrc_directory = 'train/'\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":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:40.789250Z","iopub.execute_input":"2025-02-10T11:55:40.789464Z","iopub.status.idle":"2025-02-10T11:55:44.154376Z","shell.execute_reply.started":"2025-02-10T11:55:40.789446Z","shell.execute_reply":"2025-02-10T11:55:44.153395Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/dogs | wc -l\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:44.155991Z","iopub.execute_input":"2025-02-10T11:55:44.156251Z","iopub.status.idle":"2025-02-10T11:55:44.852144Z","shell.execute_reply.started":"2025-02-10T11:55:44.156231Z","shell.execute_reply":"2025-02-10T11:55:44.850987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/cats | wc -l\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:44.853566Z","iopub.execute_input":"2025-02-10T11:55:44.853833Z","iopub.status.idle":"2025-02-10T11:55:46.821761Z","shell.execute_reply.started":"2025-02-10T11:55:44.853810Z","shell.execute_reply":"2025-02-10T11:55:46.820878Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip -q install livelossplot\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:46.823189Z","iopub.execute_input":"2025-02-10T11:55:46.823543Z","iopub.status.idle":"2025-02-10T11:55:50.557483Z","shell.execute_reply.started":"2025-02-10T11:55:46.823507Z","shell.execute_reply":"2025-02-10T11:55:50.556395Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from livelossplot import PlotLossesKeras\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:50.558911Z","iopub.execute_input":"2025-02-10T11:55:50.559187Z","iopub.status.idle":"2025-02-10T11:55:50.562966Z","shell.execute_reply.started":"2025-02-10T11:55:50.559164Z","shell.execute_reply":"2025-02-10T11:55:50.562155Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**เตรียม data **","metadata":{}},{"cell_type":"code","source":"# save the final model to file\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.xception import Xception\nfrom keras.models import Model\nfrom keras.layers import Dense\nfrom keras.layers import Flatten\nfrom keras.optimizers import SGD\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:50.563909Z","iopub.execute_input":"2025-02-10T11:55:50.564215Z","iopub.status.idle":"2025-02-10T11:55:50.585535Z","shell.execute_reply.started":"2025-02-10T11:55:50.564187Z","shell.execute_reply":"2025-02-10T11:55:50.584730Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n# create data generator\ndatagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\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    fill_mode='nearest'\n)\n# prepare iterator\ntrain_it = datagen.flow_from_directory('dataset_dogs_vs_cats/train/',\n    class_mode='binary', batch_size=64, target_size=(224, 224))\ntest_it = datagen.flow_from_directory('dataset_dogs_vs_cats/test/',\n    class_mode='binary', batch_size=64, target_size=(224, 224))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:50.586288Z","iopub.execute_input":"2025-02-10T11:55:50.586505Z","iopub.status.idle":"2025-02-10T11:55:51.305890Z","shell.execute_reply.started":"2025-02-10T11:55:50.586486Z","shell.execute_reply":"2025-02-10T11:55:51.305240Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def summarize_diagnostics(history):\n    # ตัวอย่างการสร้างกราฟจากประวัติการฝึก\n    import matplotlib.pyplot as plt\n    \n    # Plot training & validation accuracy\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.title('Model accuracy')\n    plt.xlabel('Epochs')\n    plt.ylabel('Accuracy')\n    plt.legend(['Train', 'Test'], loc='upper left')\n    plt.show()\n\n    # Plot training & validation loss\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.title('Model loss')\n    plt.xlabel('Epochs')\n    plt.ylabel('Loss')\n    plt.legend(['Train', 'Test'], loc='upper left')\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:51.306758Z","iopub.execute_input":"2025-02-10T11:55:51.307009Z","iopub.status.idle":"2025-02-10T11:55:51.312250Z","shell.execute_reply.started":"2025-02-10T11:55:51.306987Z","shell.execute_reply":"2025-02-10T11:55:51.311458Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# VGG16","metadata":{}},{"cell_type":"code","source":"# load model\nmodel = VGG16(\n    include_top=False,\n    input_shape=(224, 224, 3)\n    )\nprint(model.summary())\n#model = Xception(include_top=False, input_shape=(299, 299, 3))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:51.313118Z","iopub.execute_input":"2025-02-10T11:55:51.313401Z","iopub.status.idle":"2025-02-10T11:55:51.629923Z","shell.execute_reply.started":"2025-02-10T11:55:51.313371Z","shell.execute_reply":"2025-02-10T11:55:51.629096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# mark loaded layers as not trainable\nfor index, layer in enumerate(model.layers[:15]):\n    # ตรวจสอบว่าเลเยอร์มีคุณสมบัติ output_shape ก่อนพิมพ์\n    if hasattr(layer, 'output shape'):\n        print(index, layer.name, layer.output_shape)\n    layer.trainable = False\n\nfor index, layer in enumerate(model.layers[15:]):\n    # ตรวจสอบว่าเลเยอร์มีคุณสมบัติ output_shape ก่อนพิมพ์\n    if hasattr(layer, 'output shape'):\n        print(index, layer.name, layer.output_shape)\n\n    layer.trainable = True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:51.630919Z","iopub.execute_input":"2025-02-10T11:55:51.631266Z","iopub.status.idle":"2025-02-10T11:55:51.636229Z","shell.execute_reply.started":"2025-02-10T11:55:51.631234Z","shell.execute_reply":"2025-02-10T11:55:51.635387Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.layers[-1].output\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:51.637301Z","iopub.execute_input":"2025-02-10T11:55:51.637589Z","iopub.status.idle":"2025-02-10T11:55:51.656219Z","shell.execute_reply.started":"2025-02-10T11:55:51.637561Z","shell.execute_reply":"2025-02-10T11:55:51.655499Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.layers import Flatten, Dense\nfrom tensorflow.keras.optimizers import SGD\nfrom tensorflow.keras.models import Model\n\n# add new classifier layers\nflat1 = Flatten()(model.layers[-1].output)  # ใช้ output จากเลเยอร์สุดท้าย\nclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)  # ReLU และ He initializer\noutput = Dense(1, activation='sigmoid')(class1)  # Layer สุดท้ายสำหรับ binary classification\n\n# define new model\nmy_model = Model(inputs=model.inputs, outputs=output)\n\n# compile model\nopt = SGD(learning_rate=0.0001, momentum=0.9)  # ใช้ learning_rate แทน lr\nmy_model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n\n# display model summary\nmy_model.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:51.657139Z","iopub.execute_input":"2025-02-10T11:55:51.657426Z","iopub.status.idle":"2025-02-10T11:55:51.716621Z","shell.execute_reply.started":"2025-02-10T11:55:51.657398Z","shell.execute_reply":"2025-02-10T11:55:51.715810Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# fit model\nhistory = my_model.fit(\n    train_it, \n    validation_data=test_it, \n    epochs=2,  # ปรับเป็นจำนวน epochs ที่ต้องการ\n    verbose=1,\n    callbacks=[PlotLossesKeras()]  # สามารถตัดออกหากไม่ต้องการการแสดงผลกราฟ\n)\n\n# evaluate model\n_, acc = my_model.evaluate(test_it, verbose=1)  # ใช้ evaluate แทน evaluate_generator\nprint('> %.3f' % (acc * 100.0))\n\n# learning curves\nsummarize_diagnostics(history)\n\n# save model\nbest_model = 'vgg16_model.hdf5'\nmy_model.save(best_model)\nprint(f'Model saved to {best_model}')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:55:51.717516Z","iopub.execute_input":"2025-02-10T11:55:51.717807Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import load_model\n\n# โหลดโมเดลที่เทรนเสร็จแล้ว\nmodel = load_model('vgg16_model.hdf5')  # เปลี่ยนเป็น path ของโมเดลที่เซฟไว้\n\n# เตรียม ImageDataGenerator สำหรับ test set\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลจากโฟลเดอร์ test\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=1,  # โหลดทีละ 1 รูป\n    target_size=(224, 224),\n    shuffle=True  # สุ่มลำดับของภาพ\n)\n\n# ดึงรูปจาก test set (สุ่ม 10 รูป คลาสละ 5 รูป)\nnum_samples = 10\nselected_images = []\nselected_labels = []\n\n# จำนวนรูปที่ต้องการจากแต่ละคลาส\nnum_dogs = 0\nnum_cats = 0\n\n# เลือกรูป 10 รูป โดย 5 รูปจากสุนัขและ 5 รูปจากแมว\nwhile len(selected_images) < num_samples:\n    img, label = next(test_it)  # ดึงรูปจาก test_it\n    if label[0] == 1 and num_dogs < 5:  # เลือกสุนัข\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_dogs += 1\n    elif label[0] == 0 and num_cats < 5:  # เลือกแมว\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_cats += 1\n\n# แปลงข้อมูลภาพให้เป็น numpy array\nselected_images = np.array(selected_images)\n\n# ใช้โมเดลทำนาย\npredictions = model.predict(selected_images)\n\n# เปลี่ยนค่าผลลัพธ์จาก sigmoid ให้เป็น 0 หรือ 1\npred_labels = (predictions > 0.5).astype(int)\n\n# แสดงผลลัพธ์\nfig, axes = plt.subplots(2, 5, figsize=(12, 6))\naxes = axes.ravel()\n\nfor i in range(num_samples):\n    axes[i].imshow(selected_images[i])  # แสดงรูปภาพ\n    true_label = \"Dog\" if selected_labels[i] == 1 else \"Cat\"  # ป้ายจริง\n    pred_label = \"Dog\" if pred_labels[i] == 1 else \"Cat\"  # ป้ายที่ทำนาย\n    pred_confidence = predictions[i][0] * 100  # ความมั่นใจของการทำนาย\n    axes[i].set_title(f\"True: {true_label}\\nPred: {pred_label} ({pred_confidence:.2f}%)\")  # แสดงผลลัพธ์\n    axes[i].axis('off')\n\nplt.tight_layout()  # ปรับการจัดตำแหน่งภาพ\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Model Xception**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import Xception\nfrom tensorflow.keras.layers import Flatten, Dense\nfrom tensorflow.keras.optimizers import SGD\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom livelossplot import PlotLossesKeras\n\n# โหลดโมเดล Xception\nmodel = Xception(\n    include_top=False, \n    input_shape=(299, 299, 3)  # ใช้ขนาด input ที่ Xception ต้องการ\n)\n\n# พิมพ์ summary ของโมเดล Xception\nprint(model.summary())\n\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# mark loaded layers as not trainable (freeze layers)\nfor index, layer in enumerate(model.layers[:15]):\n    if hasattr(layer, 'output_shape'):\n        print(index, layer.name, layer.output_shape)\n    layer.trainable = False\n\n# unfreeze the remaining layers\nfor index, layer in enumerate(model.layers[15:]):\n    if hasattr(layer, 'output_shape'):\n        print(index, layer.name, layer.output_shape)\n    layer.trainable = True","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# เพิ่ม new classifier layers\nflat1 = Flatten()(model.layers[-1].output)  # ใช้ output จากเลเยอร์สุดท้าย\nclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)  # ReLU และ He initializer\noutput = Dense(1, activation='sigmoid')(class1)  # Layer สุดท้ายสำหรับ binary classification","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# define new model\nmy_model = Model(inputs=model.inputs, outputs=output)\n\n# compile model\nopt = SGD(learning_rate=0.0001, momentum=0.9)  # ใช้ learning_rate แทน lr\nmy_model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n\n# display model summary\nmy_model.summary()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# เตรียม ImageDataGenerator สำหรับการฝึก\ntrain_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_it = train_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',  # โฟลเดอร์ train set\n    class_mode='binary',\n    batch_size=32,  # ปรับ batch size ตามที่ต้องการ\n    target_size=(299, 299),  # ปรับขนาดให้ตรงกับที่ Xception ต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=32,  # ปรับ batch size ตามที่ต้องการ\n    target_size=(299, 299),  # ปรับขนาดให้ตรงกับที่ Xception ต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# fit model\nhistory = my_model.fit(\n    train_it, \n    validation_data=test_it, \n    epochs=3,  # ปรับเป็นจำนวน epochs ที่ต้องการ\n    verbose=1,\n)\n\n# evaluate model\n_, acc = my_model.evaluate(test_it, verbose=1)  # ใช้ evaluate แทน evaluate_generator\nprint('> %.3f' % (acc * 100.0))\n\n# learning curves\nsummarize_diagnostics(history)\n\n# save model\nbest_model = 'xception_model.hdf5'  # เปลี่ยนชื่อไฟล์เป็นของ Xception\nmy_model.save(best_model)\nprint(f'Model saved to {best_model}')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import load_model\n\n# โหลดโมเดล Xception ที่ฝึกเสร็จแล้ว\nmodel = load_model('xception_model.hdf5')  # เปลี่ยนเป็น path ของโมเดลที่เซฟไว้\n\n# เตรียม ImageDataGenerator สำหรับ test set\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลจากโฟลเดอร์ test\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=1,  # โหลดทีละ 1 รูป\n    target_size=(299, 299),  # ปรับขนาดให้ตรงกับที่ Xception ต้องการ\n    shuffle=True  # สุ่มลำดับของภาพ\n)\n\n# ดึงรูปจาก test set (สุ่ม 10 รูป คลาสละ 5 รูป)\nnum_samples = 10\nselected_images = []\nselected_labels = []\n\n# จำนวนรูปที่ต้องการจากแต่ละคลาส\nnum_dogs = 0\nnum_cats = 0\n\n# เลือกรูป 10 รูป โดย 5 รูปจากสุนัขและ 5 รูปจากแมว\nwhile len(selected_images) < num_samples:\n    img, label = next(test_it)  # ดึงรูปจาก test_it\n    if label[0] == 1 and num_dogs < 5:  # เลือกสุนัข\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_dogs += 1\n    elif label[0] == 0 and num_cats < 5:  # เลือกแมว\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_cats += 1\n\n# แปลงข้อมูลภาพให้เป็น numpy array\nselected_images = np.array(selected_images)\n\n# ใช้โมเดลทำนาย\npredictions = model.predict(selected_images)\n\n# เปลี่ยนค่าผลลัพธ์จาก sigmoid ให้เป็น 0 หรือ 1\npred_labels = (predictions > 0.5).astype(int)\n\n# แสดงผลลัพธ์\nfig, axes = plt.subplots(2, 5, figsize=(12, 6))\naxes = axes.ravel()\n\nfor i in range(num_samples):\n    axes[i].imshow(selected_images[i])  # แสดงรูปภาพ\n    true_label = \"Dog\" if selected_labels[i] == 1 else \"Cat\"  # ป้ายจริง\n    pred_label = \"Dog\" if pred_labels[i] == 1 else \"Cat\"  # ป้ายที่ทำนาย\n    pred_confidence = predictions[i][0] * 100  # ความมั่นใจของการทำนาย\n    axes[i].set_title(f\"True: {true_label}\\nPred: {pred_label} ({pred_confidence:.2f}%)\")  # แสดงผลลัพธ์\n    axes[i].axis('off')\n\nplt.tight_layout()  # ปรับการจัดตำแหน่งภาพ\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **InceptionV3**# # ","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import InceptionV3\nfrom tensorflow.keras.layers import Flatten, Dense\nfrom tensorflow.keras.optimizers import SGD\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom livelossplot import PlotLossesKeras\n\n# โหลดโมเดล InceptionV3\nmodel = InceptionV3(\n    include_top=False, \n    input_shape=(299, 299, 3)  # ขนาดที่โมเดล InceptionV3 ต้องการ\n)\n\n# พิมพ์ summary ของโมเดล InceptionV3\nprint(model.summary())\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# mark loaded layers as not trainable (freeze layers)\nfor index, layer in enumerate(model.layers[:15]):\n    if hasattr(layer, 'output_shape'):\n        print(index, layer.name, layer.output_shape)\n    layer.trainable = False\n\n# unfreeze the remaining layers\nfor index, layer in enumerate(model.layers[15:]):\n    if hasattr(layer, 'output_shape'):\n        print(index, layer.name, layer.output_shape)\n    layer.trainable = True\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# เพิ่ม new classifier layers\nflat1 = Flatten()(model.layers[-1].output)  # ใช้ output จากเลเยอร์สุดท้าย\nclass1 = Dense(128, activation='relu', kernel_initializer='he_uniform')(flat1)  # ReLU และ He initializer\noutput = Dense(1, activation='sigmoid')(class1)  # Layer สุดท้ายสำหรับ binary classification","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# define new model\nmy_model = Model(inputs=model.inputs, outputs=output)\n\n# compile model\nopt = SGD(learning_rate=0.0001, momentum=0.9)  # ใช้ learning_rate แทน lr\nmy_model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n\n# display model summary\nmy_model.summary()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# เตรียม ImageDataGenerator สำหรับการฝึก\ntrain_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_it = train_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',  # โฟลเดอร์ train set\n    class_mode='binary',\n    batch_size=32,  # ปรับ batch size ตามที่ต้องการ\n    target_size=(299, 299),  # ปรับขนาดให้ตรงกับที่ InceptionV3 ต้องการ\n)\n\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=32,  # ปรับ batch size ตามที่ต้องการ\n    target_size=(299, 299),  # ปรับขนาดให้ตรงกับที่ InceptionV3 ต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# fit model\nhistory = my_model.fit(\n    train_it, \n    validation_data=test_it, \n    epochs=3,  # ปรับเป็นจำนวน epochs ที่ต้องการ\n    verbose=1,\n)\n\n# evaluate model\n_, acc = my_model.evaluate(test_it, verbose=1)  # ใช้ evaluate แทน evaluate_generator\nprint('> %.3f' % (acc * 100.0))\n\n# learning curves\nsummarize_diagnostics(history)\n\n# save model\nbest_model = 'inceptionv3_model.hdf5'  # เปลี่ยนชื่อไฟล์เป็นของ InceptionV3\nmy_model.save(best_model)\nprint(f'Model saved to {best_model}')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import load_model\n\n# โหลดโมเดล InceptionV3 ที่ฝึกเสร็จแล้ว\nmodel = load_model('inceptionv3_model.hdf5')  # เปลี่ยนเป็น path ของโมเดลที่เซฟไว้\n\n# เตรียม ImageDataGenerator สำหรับ test set\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลจากโฟลเดอร์ test\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=1,  # โหลดทีละ 1 รูป\n    target_size=(299, 299),  # ปรับขนาดให้ตรงกับที่ InceptionV3 ต้องการ\n    shuffle=True  # สุ่มลำดับของภาพ\n)\n\n# ดึงรูปจาก test set (สุ่ม 10 รูป คลาสละ 5 รูป)\nnum_samples = 10\nselected_images = []\nselected_labels = []\n\n# จำนวนรูปที่ต้องการจากแต่ละคลาส\nnum_dogs = 0\nnum_cats = 0\n\n# เลือกรูป 10 รูป โดย 5 รูปจากสุนัขและ 5 รูปจากแมว\nwhile len(selected_images) < num_samples:\n    img, label = next(test_it)  # ดึงรูปจาก test_it\n    if label[0] == 1 and num_dogs < 5:  # เลือกสุนัข\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_dogs += 1\n    elif label[0] == 0 and num_cats < 5:  # เลือกแมว\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_cats += 1\n\n# แปลงข้อมูลภาพให้เป็น numpy array\nselected_images = np.array(selected_images)\n\n# ใช้โมเดลทำนาย\npredictions = model.predict(selected_images)\n\n# เปลี่ยนค่าผลลัพธ์จาก sigmoid ให้เป็น 0 หรือ 1\npred_labels = (predictions > 0.5).astype(int)\n\n# แสดงผลลัพธ์\nfig, axes = plt.subplots(2, 5, figsize=(12, 6))\naxes = axes.ravel()\n\nfor i in range(num_samples):\n    axes[i].imshow(selected_images[i])  # แสดงรูปภาพ\n    true_label = \"Dog\" if selected_labels[i] == 1 else \"Cat\"  # ป้ายจริง\n    pred_label = \"Dog\" if pred_labels[i] == 1 else \"Cat\"  # ป้ายที่ทำนาย\n    pred_confidence = predictions[i][0] * 100  # ความมั่นใจของการทำนาย\n    axes[i].set_title(f\"True: {true_label}\\nPred: {pred_label} ({pred_confidence:.2f}%)\")  # แสดงผลลัพธ์\n    axes[i].axis('off')\n\nplt.tight_layout()  # ปรับการจัดตำแหน่งภาพ\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# MobileNetV2","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.layers import Flatten, Dense\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\n\n# โหลด MobileNetV2 model โดยไม่รวม top layers\nbase_model = MobileNetV2(\n    include_top=False,  # ลบ fully connected layer ที่ใช้ในการจำแนก\n    input_shape=(224, 224, 3)  # ขนาดที่โมเดลต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ทำให้ layer ของ base model ไม่สามารถฝึกได้ (freeze)\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# เพิ่ม classifier layer สำหรับโมเดลที่ใช้กับงาน binary classification\nx = Flatten()(base_model.output)  # แปลงข้อมูลเป็น 1D\nx = Dense(128, activation='relu')(x)  # Dense layer แรก\nx = Dense(1, activation='sigmoid')(x)  # สุดท้ายเป็น sigmoid สำหรับ binary classification (แมวหรือสุนัข)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# สร้างโมเดลใหม่โดยใช้ base model และ classifier ที่เราเพิ่ม\nmodel = Model(inputs=base_model.input, outputs=x)\n\n# คอมไพล์โมเดล\nmodel.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# เตรียม ImageDataGenerator สำหรับ train และ test sets\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\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    fill_mode='nearest'\n)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลการฝึกและการทดสอบ\ntrain_it = train_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',  # เปลี่ยนเป็น path ของ train set\n    class_mode='binary',\n    batch_size=32,\n    target_size=(224, 224)  # ขนาดที่โมเดลต้องการ\n)\n\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # เปลี่ยนเป็น path ของ test set\n    class_mode='binary',\n    batch_size=32,\n    target_size=(224, 224)  # ขนาดที่โมเดลต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ฝึกโมเดล\nhistory = model.fit(\n    train_it,\n    validation_data=test_it,\n    epochs=10,  # ปรับจำนวน epochs ตามที่ต้องการ\n    verbose=1\n)\n\n# ประเมินโมเดล\n_, acc = model.evaluate(test_it, verbose=1)\nprint(f'Model Accuracy: {acc * 100:.2f}%')\n\n# แสดงผลการฝึก\nplt.plot(history.history['accuracy'], label='Train Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Model Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\n# บันทึกโมเดลที่ฝึกเสร็จแล้ว\nmodel.save('mobilenetv2_model.hdf5')\nprint(\"Model saved to 'mobilenetv2_model.hdf5'\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.applications import MobileNetV2\n\n# โหลดโมเดล MobileNetV2 ที่ฝึกเสร็จแล้ว\nmodel = load_model('mobilenetv2_model.hdf5')  # เปลี่ยนเป็น path ของโมเดลที่เซฟไว้\n\n# เตรียม ImageDataGenerator สำหรับ test set\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลจากโฟลเดอร์ test\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=1,  # โหลดทีละ 1 รูป\n    target_size=(224, 224),  # ปรับขนาดให้ตรงกับที่ MobileNetV2 ต้องการ\n    shuffle=True  # สุ่มลำดับของภาพ\n)\n\n# ดึงรูปจาก test set (สุ่ม 10 รูป คลาสละ 5 รูป)\nnum_samples = 10\nselected_images = []\nselected_labels = []\n\n# จำนวนรูปที่ต้องการจากแต่ละคลาส\nnum_dogs = 0\nnum_cats = 0\n\n# เลือกรูป 10 รูป โดย 5 รูปจากสุนัขและ 5 รูปจากแมว\nwhile len(selected_images) < num_samples:\n    img, label = next(test_it)  # ดึงรูปจาก test_it\n    if label[0] == 1 and num_dogs < 5:  # เลือกสุนัข\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_dogs += 1\n    elif label[0] == 0 and num_cats < 5:  # เลือกแมว\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_cats += 1\n\n# แปลงข้อมูลภาพให้เป็น numpy array\nselected_images = np.array(selected_images)\n\n# ใช้โมเดลทำนาย\npredictions = model.predict(selected_images)\n\n# เปลี่ยนค่าผลลัพธ์จาก sigmoid ให้เป็น 0 หรือ 1\npred_labels = (predictions > 0.5).astype(int)\n\n# แสดงผลลัพธ์\nfig, axes = plt.subplots(2, 5, figsize=(12, 6))\naxes = axes.ravel()\n\nfor i in range(num_samples):\n    axes[i].imshow(selected_images[i])  # แสดงรูปภาพ\n    true_label = \"Dog\" if selected_labels[i] == 1 else \"Cat\"  # ป้ายจริง\n    pred_label = \"Dog\" if pred_labels[i] == 1 else \"Cat\"  # ป้ายที่ทำนาย\n    pred_confidence = predictions[i][0] * 100  # ความมั่นใจของการทำนาย\n    axes[i].set_title(f\"True: {true_label}\\nPred: {pred_label} ({pred_confidence:.2f}%)\")  # แสดงผลลัพธ์\n    axes[i].axis('off')\n\nplt.tight_layout()  # ปรับการจัดตำแหน่งภาพ\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# DenseNet121","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import DenseNet121\nfrom tensorflow.keras.layers import Flatten, Dense\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\n\n# โหลดโมเดล DenseNet121 โดยไม่รวม top layers (จะใช้ classifier ของตัวเอง)\nbase_model = DenseNet121(\n    include_top=False,  # ลบ fully connected layers\n    input_shape=(224, 224, 3)  # ขนาดที่โมเดลต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ทำให้ layer ของ base model ไม่สามารถฝึกได้ (freeze)\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# เพิ่ม classifier layer สำหรับโมเดลที่ใช้กับงาน binary classification\nx = Flatten()(base_model.output)  # แปลงข้อมูลเป็น 1D\nx = Dense(128, activation='relu')(x)  # Dense layer แรก\nx = Dense(1, activation='sigmoid')(x)  # สุดท้ายเป็น sigmoid สำหรับ binary classification (แมวหรือสุนัข)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# สร้างโมเดลใหม่โดยใช้ base model และ classifier ที่เราเพิ่ม\nmodel = Model(inputs=base_model.input, outputs=x)\n\n# คอมไพล์โมเดล\nmodel.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# เตรียม ImageDataGenerator สำหรับ train และ test sets\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\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    fill_mode='nearest'\n)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลการฝึกและการทดสอบ\ntrain_it = train_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',  # เปลี่ยนเป็น path ของ train set\n    class_mode='binary',\n    batch_size=32,\n    target_size=(224, 224)  # ขนาดที่โมเดลต้องการ\n)\n\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # เปลี่ยนเป็น path ของ test set\n    class_mode='binary',\n    batch_size=32,\n    target_size=(224, 224)  # ขนาดที่โมเดลต้องการ\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ฝึกโมเดล\nhistory = model.fit(\n    train_it,\n    validation_data=test_it,\n    epochs=10,  # ปรับจำนวน epochs ตามที่ต้องการ\n    verbose=1\n)\n\n# ประเมินโมเดล\n_, acc = model.evaluate(test_it, verbose=1)\nprint(f'Model Accuracy: {acc * 100:.2f}%')\n\n# แสดงผลการฝึก\nplt.plot(history.history['accuracy'], label='Train Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Model Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()\n\n# บันทึกโมเดลที่ฝึกเสร็จแล้ว\nmodel.save('densenet121_model.hdf5')\nprint(\"Model saved to 'densenet121_model.hdf5'\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.applications import DenseNet121  # เปลี่ยนจาก MobileNetV2 เป็น DenseNet121\n\n# โหลดโมเดล DenseNet121 ที่ฝึกเสร็จแล้ว\nmodel = load_model('densenet121_model.hdf5')  # เปลี่ยนเป็น path ของโมเดลที่เซฟไว้\n\n# เตรียม ImageDataGenerator สำหรับ test set\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# โหลดข้อมูลจากโฟลเดอร์ test\ntest_it = test_datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/test/',  # โฟลเดอร์ test set\n    class_mode='binary',\n    batch_size=1,  # โหลดทีละ 1 รูป\n    target_size=(224, 224),  # ปรับขนาดให้ตรงกับที่ DenseNet121 ต้องการ\n    shuffle=True  # สุ่มลำดับของภาพ\n)\n\n# ดึงรูปจาก test set (สุ่ม 10 รูป คลาสละ 5 รูป)\nnum_samples = 10\nselected_images = []\nselected_labels = []\n\n# จำนวนรูปที่ต้องการจากแต่ละคลาส\nnum_dogs = 0\nnum_cats = 0\n\n# เลือกรูป 10 รูป โดย 5 รูปจากสุนัขและ 5 รูปจากแมว\nwhile len(selected_images) < num_samples:\n    img, label = next(test_it)  # ดึงรูปจาก test_it\n    if label[0] == 1 and num_dogs < 5:  # เลือกสุนัข\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_dogs += 1\n    elif label[0] == 0 and num_cats < 5:  # เลือกแมว\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n        num_cats += 1\n\n# แปลงข้อมูลภาพให้เป็น numpy array\nselected_images = np.array(selected_images)\n\n# ใช้โมเดลทำนาย\npredictions = model.predict(selected_images)\n\n# เปลี่ยนค่าผลลัพธ์จาก sigmoid ให้เป็น 0 หรือ 1\npred_labels = (predictions > 0.5).astype(int)\n\n# แสดงผลลัพธ์\nfig, axes = plt.subplots(2, 5, figsize=(12, 6))\naxes = axes.ravel()\n\nfor i in range(num_samples):\n    axes[i].imshow(selected_images[i])  # แสดงรูปภาพ\n    true_label = \"Dog\" if selected_labels[i] == 1 else \"Cat\"  # ป้ายจริง\n    pred_label = \"Dog\" if pred_labels[i] == 1 else \"Cat\"  # ป้ายที่ทำนาย\n    pred_confidence = predictions[i][0] * 100  # ความมั่นใจของการทำนาย\n    axes[i].set_title(f\"True: {true_label}\\nPred: {pred_label} ({pred_confidence:.2f}%)\")  # แสดงผลลัพธ์\n    axes[i].axis('off')\n\nplt.tight_layout()  # ปรับการจัดตำแหน่งภาพ\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}