{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30887,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":7845.256739,"end_time":"2025-02-10T14:07:03.843087","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-02-10T11:56:18.586348","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"67665f7f","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":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2025-02-11T13:28:39.234910Z","iopub.execute_input":"2025-02-11T13:28:39.235156Z","iopub.status.idle":"2025-02-11T13:28:39.982241Z","shell.execute_reply.started":"2025-02-11T13:28:39.235119Z","shell.execute_reply":"2025-02-11T13:28:39.981374Z"},"papermill":{"duration":0.755033,"end_time":"2025-02-10T11:56:22.118574","exception":false,"start_time":"2025-02-10T11:56:21.363541","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"4e79f8d4","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":"2025-02-11T13:28:39.983073Z","iopub.execute_input":"2025-02-11T13:28:39.983527Z","iopub.status.idle":"2025-02-11T13:28:53.190417Z","shell.execute_reply.started":"2025-02-11T13:28:39.983503Z","shell.execute_reply":"2025-02-11T13:28:53.189308Z"},"papermill":{"duration":14.799001,"end_time":"2025-02-10T11:56:36.926518","exception":false,"start_time":"2025-02-10T11:56:22.127517","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"7e70b326","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":{"execution":{"iopub.status.busy":"2025-02-11T13:28:53.191387Z","iopub.execute_input":"2025-02-11T13:28:53.191701Z","iopub.status.idle":"2025-02-11T13:28:54.166008Z","shell.execute_reply.started":"2025-02-11T13:28:53.191669Z","shell.execute_reply":"2025-02-11T13:28:54.165160Z"},"papermill":{"duration":1.058237,"end_time":"2025-02-10T11:56:37.993504","exception":false,"start_time":"2025-02-10T11:56:36.935267","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"e2e9a38b","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":"2025-02-11T13:28:54.167779Z","iopub.execute_input":"2025-02-11T13:28:54.167985Z","iopub.status.idle":"2025-02-11T13:28:55.067406Z","shell.execute_reply.started":"2025-02-11T13:28:54.167967Z","shell.execute_reply":"2025-02-11T13:28:55.066446Z"},"papermill":{"duration":0.968178,"end_time":"2025-02-10T11:56:38.976708","exception":false,"start_time":"2025-02-10T11:56:38.008530","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"52fe9ab8","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":{"execution":{"iopub.status.busy":"2025-02-11T13:28:55.068910Z","iopub.execute_input":"2025-02-11T13:28:55.069224Z","iopub.status.idle":"2025-02-11T13:29:07.388941Z","shell.execute_reply.started":"2025-02-11T13:28:55.069197Z","shell.execute_reply":"2025-02-11T13:29:07.387987Z"},"papermill":{"duration":13.353298,"end_time":"2025-02-10T11:56:52.351406","exception":false,"start_time":"2025-02-10T11:56:38.998108","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"9ca37bc2","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":"2025-02-11T13:29:07.389963Z","iopub.execute_input":"2025-02-11T13:29:07.390443Z","iopub.status.idle":"2025-02-11T13:29:07.394417Z","shell.execute_reply.started":"2025-02-11T13:29:07.390401Z","shell.execute_reply":"2025-02-11T13:29:07.393541Z"},"papermill":{"duration":0.02633,"end_time":"2025-02-10T11:56:52.399321","exception":false,"start_time":"2025-02-10T11:56:52.372991","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"35ec2029","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:07.395235Z","iopub.execute_input":"2025-02-11T13:29:07.395556Z","iopub.status.idle":"2025-02-11T13:29:07.423733Z","shell.execute_reply.started":"2025-02-11T13:29:07.395533Z","shell.execute_reply":"2025-02-11T13:29:07.422891Z"},"papermill":{"duration":0.028916,"end_time":"2025-02-10T11:56:52.450305","exception":false,"start_time":"2025-02-10T11:56:52.421389","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"07299450","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:07.424548Z","iopub.execute_input":"2025-02-11T13:29:07.424772Z","iopub.status.idle":"2025-02-11T13:29:09.820775Z","shell.execute_reply.started":"2025-02-11T13:29:07.424753Z","shell.execute_reply":"2025-02-11T13:29:09.819811Z"},"papermill":{"duration":2.631093,"end_time":"2025-02-10T11:56:55.102027","exception":false,"start_time":"2025-02-10T11:56:52.470934","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"26771a87","cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/dogs | wc -l\n","metadata":{"execution":{"iopub.status.busy":"2025-02-11T13:29:09.821701Z","iopub.execute_input":"2025-02-11T13:29:09.821954Z","iopub.status.idle":"2025-02-11T13:29:10.062157Z","shell.execute_reply.started":"2025-02-11T13:29:09.821933Z","shell.execute_reply":"2025-02-11T13:29:10.061226Z"},"papermill":{"duration":0.294066,"end_time":"2025-02-10T11:56:55.418239","exception":false,"start_time":"2025-02-10T11:56:55.124173","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3302638d","cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/cats | wc -l\n\n","metadata":{"execution":{"iopub.status.busy":"2025-02-11T13:29:10.063285Z","iopub.execute_input":"2025-02-11T13:29:10.063646Z","iopub.status.idle":"2025-02-11T13:29:10.291028Z","shell.execute_reply.started":"2025-02-11T13:29:10.063614Z","shell.execute_reply":"2025-02-11T13:29:10.289970Z"},"papermill":{"duration":0.253282,"end_time":"2025-02-10T11:56:55.692995","exception":false,"start_time":"2025-02-10T11:56:55.439713","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"f40db836","cell_type":"code","source":"!pip -q install livelossplot\n","metadata":{"execution":{"iopub.status.busy":"2025-02-11T13:29:10.292113Z","iopub.execute_input":"2025-02-11T13:29:10.292452Z","iopub.status.idle":"2025-02-11T13:29:14.929649Z","shell.execute_reply.started":"2025-02-11T13:29:10.292420Z","shell.execute_reply":"2025-02-11T13:29:14.928667Z"},"papermill":{"duration":4.920396,"end_time":"2025-02-10T11:57:00.634204","exception":false,"start_time":"2025-02-10T11:56:55.713808","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"53d72a78","cell_type":"code","source":"from livelossplot import PlotLossesKeras\n","metadata":{"execution":{"iopub.status.busy":"2025-02-11T13:29:14.930849Z","iopub.execute_input":"2025-02-11T13:29:14.931206Z","iopub.status.idle":"2025-02-11T13:29:14.945695Z","shell.execute_reply.started":"2025-02-11T13:29:14.931177Z","shell.execute_reply":"2025-02-11T13:29:14.945038Z"},"papermill":{"duration":0.035124,"end_time":"2025-02-10T11:57:00.690121","exception":false,"start_time":"2025-02-10T11:57:00.654997","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"c2345634","cell_type":"markdown","source":"**เตรียม data **","metadata":{"papermill":{"duration":0.019585,"end_time":"2025-02-10T11:57:00.729645","exception":false,"start_time":"2025-02-10T11:57:00.710060","status":"completed"},"tags":[]}},{"id":"cb685c6d","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:14.949636Z","iopub.execute_input":"2025-02-11T13:29:14.949859Z","iopub.status.idle":"2025-02-11T13:29:15.014034Z","shell.execute_reply.started":"2025-02-11T13:29:14.949840Z","shell.execute_reply":"2025-02-11T13:29:15.013358Z"},"papermill":{"duration":0.088889,"end_time":"2025-02-10T11:57:00.838153","exception":false,"start_time":"2025-02-10T11:57:00.749264","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"89160183","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:15.015690Z","iopub.execute_input":"2025-02-11T13:29:15.016022Z","iopub.status.idle":"2025-02-11T13:29:15.842750Z","shell.execute_reply.started":"2025-02-11T13:29:15.015986Z","shell.execute_reply":"2025-02-11T13:29:15.841810Z"},"papermill":{"duration":0.949315,"end_time":"2025-02-10T11:57:01.807979","exception":false,"start_time":"2025-02-10T11:57:00.858664","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"019ee909","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:15.843674Z","iopub.execute_input":"2025-02-11T13:29:15.843920Z","iopub.status.idle":"2025-02-11T13:29:15.849127Z","shell.execute_reply.started":"2025-02-11T13:29:15.843898Z","shell.execute_reply":"2025-02-11T13:29:15.848318Z"},"papermill":{"duration":0.026667,"end_time":"2025-02-10T11:57:01.855583","exception":false,"start_time":"2025-02-10T11:57:01.828916","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"1230664e","cell_type":"markdown","source":"# VGG16","metadata":{"papermill":{"duration":0.019381,"end_time":"2025-02-10T11:57:01.894921","exception":false,"start_time":"2025-02-10T11:57:01.875540","status":"completed"},"tags":[]}},{"id":"f031349f","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:15.849982Z","iopub.execute_input":"2025-02-11T13:29:15.850186Z","iopub.status.idle":"2025-02-11T13:29:19.071464Z","shell.execute_reply.started":"2025-02-11T13:29:15.850167Z","shell.execute_reply":"2025-02-11T13:29:19.070755Z"},"papermill":{"duration":3.601142,"end_time":"2025-02-10T11:57:05.515312","exception":false,"start_time":"2025-02-10T11:57:01.914170","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"1168602d","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:19.072238Z","iopub.execute_input":"2025-02-11T13:29:19.072546Z","iopub.status.idle":"2025-02-11T13:29:19.077170Z","shell.execute_reply.started":"2025-02-11T13:29:19.072522Z","shell.execute_reply":"2025-02-11T13:29:19.076536Z"},"papermill":{"duration":0.028755,"end_time":"2025-02-10T11:57:05.566821","exception":false,"start_time":"2025-02-10T11:57:05.538066","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"b2d1ee29","cell_type":"code","source":"model.layers[-1].output\n","metadata":{"execution":{"iopub.status.busy":"2025-02-11T13:29:19.077961Z","iopub.execute_input":"2025-02-11T13:29:19.078188Z","iopub.status.idle":"2025-02-11T13:29:19.092858Z","shell.execute_reply.started":"2025-02-11T13:29:19.078168Z","shell.execute_reply":"2025-02-11T13:29:19.092134Z"},"papermill":{"duration":0.029017,"end_time":"2025-02-10T11:57:05.617420","exception":false,"start_time":"2025-02-10T11:57:05.588403","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"f95b434c","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:19.093620Z","iopub.execute_input":"2025-02-11T13:29:19.093803Z","iopub.status.idle":"2025-02-11T13:29:19.160537Z","shell.execute_reply.started":"2025-02-11T13:29:19.093786Z","shell.execute_reply":"2025-02-11T13:29:19.159690Z"},"papermill":{"duration":0.081523,"end_time":"2025-02-10T11:57:05.720448","exception":false,"start_time":"2025-02-10T11:57:05.638925","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"7eb37c42","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":{"execution":{"iopub.status.busy":"2025-02-11T13:29:19.161443Z","iopub.execute_input":"2025-02-11T13:29:19.161763Z","iopub.status.idle":"2025-02-11T13:40:42.030681Z","shell.execute_reply.started":"2025-02-11T13:29:19.161722Z","shell.execute_reply":"2025-02-11T13:40:42.029705Z"},"papermill":{"duration":739.955497,"end_time":"2025-02-10T12:09:25.698587","exception":false,"start_time":"2025-02-10T11:57:05.743090","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"db6375f1","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:42.031798Z","iopub.execute_input":"2025-02-11T13:40:42.032486Z","iopub.status.idle":"2025-02-11T13:40:50.501543Z","shell.execute_reply.started":"2025-02-11T13:40:42.032439Z","shell.execute_reply":"2025-02-11T13:40:50.500663Z"},"papermill":{"duration":8.94878,"end_time":"2025-02-10T12:09:34.680153","exception":false,"start_time":"2025-02-10T12:09:25.731373","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"7e16f3a8","cell_type":"markdown","source":"# **Model Xception**","metadata":{"papermill":{"duration":0.057996,"end_time":"2025-02-10T12:09:34.809605","exception":false,"start_time":"2025-02-10T12:09:34.751609","status":"completed"},"tags":[]}},{"id":"d7524d24","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:50.502486Z","iopub.execute_input":"2025-02-11T13:40:50.502723Z","iopub.status.idle":"2025-02-11T13:40:52.114190Z","shell.execute_reply.started":"2025-02-11T13:40:50.502700Z","shell.execute_reply":"2025-02-11T13:40:52.113246Z"},"papermill":{"duration":1.977852,"end_time":"2025-02-10T12:09:36.841382","exception":false,"start_time":"2025-02-10T12:09:34.863530","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"eab18168","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:52.115176Z","iopub.execute_input":"2025-02-11T13:40:52.115512Z","iopub.status.idle":"2025-02-11T13:40:52.121634Z","shell.execute_reply.started":"2025-02-11T13:40:52.115478Z","shell.execute_reply":"2025-02-11T13:40:52.120903Z"},"papermill":{"duration":0.063886,"end_time":"2025-02-10T12:09:36.964542","exception":false,"start_time":"2025-02-10T12:09:36.900656","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"e3906c71","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:52.122373Z","iopub.execute_input":"2025-02-11T13:40:52.122646Z","iopub.status.idle":"2025-02-11T13:40:52.148856Z","shell.execute_reply.started":"2025-02-11T13:40:52.122627Z","shell.execute_reply":"2025-02-11T13:40:52.147936Z"},"papermill":{"duration":0.075794,"end_time":"2025-02-10T12:09:37.094819","exception":false,"start_time":"2025-02-10T12:09:37.019025","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"52eb6537","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:52.149748Z","iopub.execute_input":"2025-02-11T13:40:52.150005Z","iopub.status.idle":"2025-02-11T13:40:52.285694Z","shell.execute_reply.started":"2025-02-11T13:40:52.149974Z","shell.execute_reply":"2025-02-11T13:40:52.284812Z"},"papermill":{"duration":0.208657,"end_time":"2025-02-10T12:09:37.359354","exception":false,"start_time":"2025-02-10T12:09:37.150697","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"6d633372","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:52.286548Z","iopub.execute_input":"2025-02-11T13:40:52.286747Z","iopub.status.idle":"2025-02-11T13:40:52.797769Z","shell.execute_reply.started":"2025-02-11T13:40:52.286723Z","shell.execute_reply":"2025-02-11T13:40:52.796901Z"},"papermill":{"duration":0.623428,"end_time":"2025-02-10T12:09:38.045308","exception":false,"start_time":"2025-02-10T12:09:37.421880","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"42704e41","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:52.798672Z","iopub.execute_input":"2025-02-11T13:40:52.799164Z","iopub.status.idle":"2025-02-11T13:40:52.966095Z","shell.execute_reply.started":"2025-02-11T13:40:52.799129Z","shell.execute_reply":"2025-02-11T13:40:52.965282Z"},"papermill":{"duration":0.370237,"end_time":"2025-02-10T12:09:38.479274","exception":false,"start_time":"2025-02-10T12:09:38.109037","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"13d6e2e2","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":{"execution":{"iopub.status.busy":"2025-02-11T13:40:52.966908Z","iopub.execute_input":"2025-02-11T13:40:52.967126Z","iopub.status.idle":"2025-02-11T14:05:05.635331Z","shell.execute_reply.started":"2025-02-11T13:40:52.967096Z","shell.execute_reply":"2025-02-11T14:05:05.634610Z"},"papermill":{"duration":1532.883301,"end_time":"2025-02-10T12:35:11.426943","exception":false,"start_time":"2025-02-10T12:09:38.543642","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"75b12bf8","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:05.636252Z","iopub.execute_input":"2025-02-11T14:05:05.636575Z","iopub.status.idle":"2025-02-11T14:05:18.465815Z","shell.execute_reply.started":"2025-02-11T14:05:05.636538Z","shell.execute_reply":"2025-02-11T14:05:18.464833Z"},"papermill":{"duration":13.725129,"end_time":"2025-02-10T12:35:25.320185","exception":false,"start_time":"2025-02-10T12:35:11.595056","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"c2498f85","cell_type":"markdown","source":"# **InceptionV3**# # ","metadata":{"papermill":{"duration":0.183328,"end_time":"2025-02-10T12:35:25.691851","exception":false,"start_time":"2025-02-10T12:35:25.508523","status":"completed"},"tags":[]}},{"id":"d2558ed2","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:18.466814Z","iopub.execute_input":"2025-02-11T14:05:18.467105Z","iopub.status.idle":"2025-02-11T14:05:21.222611Z","shell.execute_reply.started":"2025-02-11T14:05:18.467078Z","shell.execute_reply":"2025-02-11T14:05:21.221775Z"},"papermill":{"duration":3.10747,"end_time":"2025-02-10T12:35:28.978182","exception":false,"start_time":"2025-02-10T12:35:25.870712","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2ef5db2f","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:21.223450Z","iopub.execute_input":"2025-02-11T14:05:21.223677Z","iopub.status.idle":"2025-02-11T14:05:21.230059Z","shell.execute_reply.started":"2025-02-11T14:05:21.223657Z","shell.execute_reply":"2025-02-11T14:05:21.229200Z"},"papermill":{"duration":0.197279,"end_time":"2025-02-10T12:35:29.408539","exception":false,"start_time":"2025-02-10T12:35:29.211260","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2ad3f000","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:21.231015Z","iopub.execute_input":"2025-02-11T14:05:21.231240Z","iopub.status.idle":"2025-02-11T14:05:21.258435Z","shell.execute_reply.started":"2025-02-11T14:05:21.231222Z","shell.execute_reply":"2025-02-11T14:05:21.257611Z"},"papermill":{"duration":0.213087,"end_time":"2025-02-10T12:35:29.809808","exception":false,"start_time":"2025-02-10T12:35:29.596721","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"455bfaeb","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:21.259251Z","iopub.execute_input":"2025-02-11T14:05:21.259543Z","iopub.status.idle":"2025-02-11T14:05:21.539412Z","shell.execute_reply.started":"2025-02-11T14:05:21.259515Z","shell.execute_reply":"2025-02-11T14:05:21.538594Z"},"papermill":{"duration":0.501077,"end_time":"2025-02-10T12:35:30.495395","exception":false,"start_time":"2025-02-10T12:35:29.994318","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"9198f16f","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:21.540307Z","iopub.execute_input":"2025-02-11T14:05:21.540598Z","iopub.status.idle":"2025-02-11T14:05:22.331659Z","shell.execute_reply.started":"2025-02-11T14:05:21.540571Z","shell.execute_reply":"2025-02-11T14:05:22.330819Z"},"papermill":{"duration":0.984775,"end_time":"2025-02-10T12:35:31.681170","exception":false,"start_time":"2025-02-10T12:35:30.696395","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"568a1b72","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":{"execution":{"iopub.status.busy":"2025-02-11T14:05:22.332579Z","iopub.execute_input":"2025-02-11T14:05:22.332897Z","iopub.status.idle":"2025-02-11T14:18:51.512915Z","shell.execute_reply.started":"2025-02-11T14:05:22.332866Z","shell.execute_reply":"2025-02-11T14:18:51.512007Z"},"papermill":{"duration":838.884647,"end_time":"2025-02-10T12:49:30.758984","exception":false,"start_time":"2025-02-10T12:35:31.874337","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"ebed3343","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":{"execution":{"iopub.status.busy":"2025-02-11T14:18:51.513943Z","iopub.execute_input":"2025-02-11T14:18:51.514196Z","iopub.status.idle":"2025-02-11T14:19:02.380098Z","shell.execute_reply.started":"2025-02-11T14:18:51.514172Z","shell.execute_reply":"2025-02-11T14:19:02.379037Z"},"papermill":{"duration":11.605511,"end_time":"2025-02-10T12:49:42.670598","exception":false,"start_time":"2025-02-10T12:49:31.065087","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"e87d625b","cell_type":"markdown","source":"# MobileNetV2","metadata":{"papermill":{"duration":0.316275,"end_time":"2025-02-10T12:49:43.309964","exception":false,"start_time":"2025-02-10T12:49:42.993689","status":"completed"},"tags":[]}},{"id":"7b6a1296","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":{"execution":{"iopub.status.busy":"2025-02-11T14:19:02.380992Z","iopub.execute_input":"2025-02-11T14:19:02.381283Z","iopub.status.idle":"2025-02-11T14:19:03.955127Z","shell.execute_reply.started":"2025-02-11T14:19:02.381256Z","shell.execute_reply":"2025-02-11T14:19:03.954500Z"},"papermill":{"duration":1.993903,"end_time":"2025-02-10T12:49:45.616470","exception":false,"start_time":"2025-02-10T12:49:43.622567","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"ebfaa02e","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":{"execution":{"iopub.status.busy":"2025-02-11T14:19:03.956080Z","iopub.execute_input":"2025-02-11T14:19:03.956382Z","iopub.status.idle":"2025-02-11T14:19:03.977214Z","shell.execute_reply.started":"2025-02-11T14:19:03.956334Z","shell.execute_reply":"2025-02-11T14:19:03.976665Z"},"papermill":{"duration":0.344315,"end_time":"2025-02-10T12:49:46.272521","exception":false,"start_time":"2025-02-10T12:49:45.928206","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"cc99d528","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":{"execution":{"iopub.status.busy":"2025-02-11T14:19:03.977994Z","iopub.execute_input":"2025-02-11T14:19:03.978180Z","iopub.status.idle":"2025-02-11T14:19:03.993556Z","shell.execute_reply.started":"2025-02-11T14:19:03.978163Z","shell.execute_reply":"2025-02-11T14:19:03.992671Z"},"papermill":{"duration":0.343953,"end_time":"2025-02-10T12:49:46.983498","exception":false,"start_time":"2025-02-10T12:49:46.639545","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"bdcb5746","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":{"execution":{"iopub.status.busy":"2025-02-11T14:19:03.998052Z","iopub.execute_input":"2025-02-11T14:19:03.998269Z","iopub.status.idle":"2025-02-11T14:19:04.763306Z","shell.execute_reply.started":"2025-02-11T14:19:03.998250Z","shell.execute_reply":"2025-02-11T14:19:04.762615Z"},"papermill":{"duration":1.13886,"end_time":"2025-02-10T12:49:48.453653","exception":false,"start_time":"2025-02-10T12:49:47.314793","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"02e37874","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":{"execution":{"iopub.status.busy":"2025-02-11T14:19:04.764737Z","iopub.execute_input":"2025-02-11T14:19:04.765071Z","iopub.status.idle":"2025-02-11T14:53:17.007677Z","shell.execute_reply.started":"2025-02-11T14:19:04.765032Z","shell.execute_reply":"2025-02-11T14:53:17.006777Z"},"papermill":{"duration":2250.318631,"end_time":"2025-02-10T13:27:19.088877","exception":false,"start_time":"2025-02-10T12:49:48.770246","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"1ca87fc3","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":{"execution":{"iopub.status.busy":"2025-02-11T14:53:17.008734Z","iopub.execute_input":"2025-02-11T14:53:17.009049Z","iopub.status.idle":"2025-02-11T14:53:22.671200Z","shell.execute_reply.started":"2025-02-11T14:53:17.009017Z","shell.execute_reply":"2025-02-11T14:53:22.669998Z"},"papermill":{"duration":6.713363,"end_time":"2025-02-10T13:27:26.440010","exception":false,"start_time":"2025-02-10T13:27:19.726647","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"6ef7d290","cell_type":"markdown","source":"# DenseNet121","metadata":{"papermill":{"duration":0.643241,"end_time":"2025-02-10T13:27:27.793667","exception":false,"start_time":"2025-02-10T13:27:27.150426","status":"completed"},"tags":[]}},{"id":"6efc74eb","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":{"execution":{"iopub.status.busy":"2025-02-11T14:53:22.672058Z","iopub.execute_input":"2025-02-11T14:53:22.672520Z","iopub.status.idle":"2025-02-11T14:53:25.178805Z","shell.execute_reply.started":"2025-02-11T14:53:22.672493Z","shell.execute_reply":"2025-02-11T14:53:25.177807Z"},"papermill":{"duration":3.150908,"end_time":"2025-02-10T13:27:31.599453","exception":false,"start_time":"2025-02-10T13:27:28.448545","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"eeac5eeb","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":{"execution":{"iopub.status.busy":"2025-02-11T14:53:25.180109Z","iopub.execute_input":"2025-02-11T14:53:25.180390Z","iopub.status.idle":"2025-02-11T14:53:25.205683Z","shell.execute_reply.started":"2025-02-11T14:53:25.180357Z","shell.execute_reply":"2025-02-11T14:53:25.205014Z"},"papermill":{"duration":0.684097,"end_time":"2025-02-10T13:27:32.996878","exception":false,"start_time":"2025-02-10T13:27:32.312781","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"7819fc07","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":{"execution":{"iopub.status.busy":"2025-02-11T14:53:25.206490Z","iopub.execute_input":"2025-02-11T14:53:25.206758Z","iopub.status.idle":"2025-02-11T14:53:25.234498Z","shell.execute_reply.started":"2025-02-11T14:53:25.206720Z","shell.execute_reply":"2025-02-11T14:53:25.233846Z"},"papermill":{"duration":0.721315,"end_time":"2025-02-10T13:27:34.449368","exception":false,"start_time":"2025-02-10T13:27:33.728053","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"25eeeff2","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":{"execution":{"iopub.status.busy":"2025-02-11T14:53:25.235200Z","iopub.execute_input":"2025-02-11T14:53:25.235480Z","iopub.status.idle":"2025-02-11T14:53:26.056873Z","shell.execute_reply.started":"2025-02-11T14:53:25.235459Z","shell.execute_reply":"2025-02-11T14:53:26.056216Z"},"papermill":{"duration":1.429255,"end_time":"2025-02-10T13:27:36.571008","exception":false,"start_time":"2025-02-10T13:27:35.141753","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"bbbbd0b4","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":{"execution":{"iopub.status.busy":"2025-02-11T14:53:26.057654Z","iopub.execute_input":"2025-02-11T14:53:26.057916Z","iopub.status.idle":"2025-02-11T15:29:30.636366Z","shell.execute_reply.started":"2025-02-11T14:53:26.057894Z","shell.execute_reply":"2025-02-11T15:29:30.634968Z"},"papermill":{"duration":2342.689436,"end_time":"2025-02-10T14:06:39.903138","exception":false,"start_time":"2025-02-10T13:27:37.213702","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"c2c6edc2","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":{"execution":{"iopub.status.busy":"2025-02-11T15:29:30.637605Z","iopub.execute_input":"2025-02-11T15:29:30.637974Z","iopub.status.idle":"2025-02-11T15:29:43.890216Z","shell.execute_reply.started":"2025-02-11T15:29:30.637935Z","shell.execute_reply":"2025-02-11T15:29:43.889338Z"},"papermill":{"duration":14.85626,"end_time":"2025-02-10T14:06:55.791594","exception":false,"start_time":"2025-02-10T14:06:40.935334","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"67a38cfc","cell_type":"code","source":"","metadata":{"papermill":{"duration":1.054252,"end_time":"2025-02-10T14:06:57.846193","exception":false,"start_time":"2025-02-10T14:06:56.791941","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null}]}