{"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":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30840,"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-10T16:17:11.110295Z","iopub.execute_input":"2025-02-10T16:17:11.110565Z","iopub.status.idle":"2025-02-10T16:17:12.079850Z","shell.execute_reply.started":"2025-02-10T16:17:11.110536Z","shell.execute_reply":"2025-02-10T16:17:12.078986Z"}},"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-10T16:17:12.080664Z","iopub.execute_input":"2025-02-10T16:17:12.081129Z","iopub.status.idle":"2025-02-10T16:17:24.752237Z","shell.execute_reply.started":"2025-02-10T16:17:12.081098Z","shell.execute_reply":"2025-02-10T16:17:24.751298Z"}},"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-10T16:17:24.753200Z","iopub.execute_input":"2025-02-10T16:17:24.753504Z","iopub.status.idle":"2025-02-10T16:17:25.724610Z","shell.execute_reply.started":"2025-02-10T16:17:24.753480Z","shell.execute_reply":"2025-02-10T16:17:25.723711Z"}},"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-10T16:17:25.726996Z","iopub.execute_input":"2025-02-10T16:17:25.727306Z","iopub.status.idle":"2025-02-10T16:17:26.597315Z","shell.execute_reply.started":"2025-02-10T16:17:25.727276Z","shell.execute_reply":"2025-02-10T16:17:26.596487Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load dogs vs cats dataset, reshape and save to a new file\nfrom os import listdir\nfrom numpy import asarray\nfrom numpy import save\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import img_to_array","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:26.598696Z","iopub.execute_input":"2025-02-10T16:17:26.598999Z","iopub.status.idle":"2025-02-10T16:17:39.167004Z","shell.execute_reply.started":"2025-02-10T16:17:26.598972Z","shell.execute_reply":"2025-02-10T16:17:39.166306Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# 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-10T16:17:39.167806Z","iopub.execute_input":"2025-02-10T16:17:39.168320Z","iopub.status.idle":"2025-02-10T16:17:39.172365Z","shell.execute_reply.started":"2025-02-10T16:17:39.168295Z","shell.execute_reply":"2025-02-10T16:17:39.171505Z"}},"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-10T16:17:39.173349Z","iopub.execute_input":"2025-02-10T16:17:39.173691Z","iopub.status.idle":"2025-02-10T16:17:39.210308Z","shell.execute_reply.started":"2025-02-10T16:17:39.173658Z","shell.execute_reply":"2025-02-10T16:17:39.209675Z"}},"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-10T16:17:39.211089Z","iopub.execute_input":"2025-02-10T16:17:39.211315Z","iopub.status.idle":"2025-02-10T16:17:41.503044Z","shell.execute_reply.started":"2025-02-10T16:17:39.211297Z","shell.execute_reply":"2025-02-10T16:17:41.502274Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/dogs | wc -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:41.503899Z","iopub.execute_input":"2025-02-10T16:17:41.504230Z","iopub.status.idle":"2025-02-10T16:17:41.728350Z","shell.execute_reply.started":"2025-02-10T16:17:41.504197Z","shell.execute_reply":"2025-02-10T16:17:41.727349Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -l dataset_dogs_vs_cats/train/cats | wc -l","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:41.729625Z","iopub.execute_input":"2025-02-10T16:17:41.729991Z","iopub.status.idle":"2025-02-10T16:17:41.944538Z","shell.execute_reply.started":"2025-02-10T16:17:41.729955Z","shell.execute_reply":"2025-02-10T16:17:41.943778Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip -q install livelossplot==0.5.5","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:41.945414Z","iopub.execute_input":"2025-02-10T16:17:41.945715Z","iopub.status.idle":"2025-02-10T16:17:46.359488Z","shell.execute_reply.started":"2025-02-10T16:17:41.945676Z","shell.execute_reply":"2025-02-10T16:17:46.358518Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from livelossplot import PlotLossesKeras","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:46.360544Z","iopub.execute_input":"2025-02-10T16:17:46.360884Z","iopub.status.idle":"2025-02-10T16:17:46.374657Z","shell.execute_reply.started":"2025-02-10T16:17:46.360836Z","shell.execute_reply":"2025-02-10T16:17:46.374007Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# save the final model to file\nfrom tensorflow.keras.applications import InceptionV3\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","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:46.377810Z","iopub.execute_input":"2025-02-10T16:17:46.378050Z","iopub.status.idle":"2025-02-10T16:17:46.444948Z","shell.execute_reply.started":"2025-02-10T16:17:46.378031Z","shell.execute_reply":"2025-02-10T16:17:46.444337Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=30,\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    validation_split=0.2  # แบ่งข้อมูล 20% สำหรับ validation\n)\n\ntrain_it = datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',\n    class_mode='binary',\n    batch_size=64,\n    target_size=(224, 224),\n    subset='training'\n)\n\nval_it = datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',\n    class_mode='binary',\n    batch_size=64,\n    target_size=(224, 224),\n    subset='validation'\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:46.446200Z","iopub.execute_input":"2025-02-10T16:17:46.446495Z","iopub.status.idle":"2025-02-10T16:17:46.993500Z","shell.execute_reply.started":"2025-02-10T16:17:46.446465Z","shell.execute_reply":"2025-02-10T16:17:46.992851Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load model\nmodel = InceptionV3(\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\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:46.994251Z","iopub.execute_input":"2025-02-10T16:17:46.994463Z","iopub.status.idle":"2025-02-10T16:17:51.561186Z","shell.execute_reply.started":"2025-02-10T16:17:46.994445Z","shell.execute_reply":"2025-02-10T16:17:51.560371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import keras \nfrom keras import layers\nimport tensorflow as tf\nfrom tensorflow import data as tf_data\nimport matplotlib.pyplot as plt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:51.562121Z","iopub.execute_input":"2025-02-10T16:17:51.562372Z","iopub.status.idle":"2025-02-10T16:17:51.566244Z","shell.execute_reply.started":"2025-02-10T16:17:51.562351Z","shell.execute_reply":"2025-02-10T16:17:51.565385Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Assuming 'model' is already defined and compiled\n\n# Mark loaded layers as not trainable\nfor index, layer in enumerate(model.layers[:15]):\n    # Check if it's not an InputLayer\n    if not isinstance(layer, tf.keras.layers.InputLayer):  \n        # Ensure that the model is built before accessing output_shape\n        print(index, layer.name, layer.output.shape)  # Use .output.shape instead of .output_shape\n        layer.trainable = False\n\nfor index, layer in enumerate(model.layers[15:]):\n    print(index, layer.name, layer.output.shape)  # Use .output.shape here as well\n    layer.trainable = True\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:51.567247Z","iopub.execute_input":"2025-02-10T16:17:51.567533Z","iopub.status.idle":"2025-02-10T16:17:51.711016Z","shell.execute_reply.started":"2025-02-10T16:17:51.567499Z","shell.execute_reply":"2025-02-10T16:17:51.710284Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.layers[-1].output","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:51.711747Z","iopub.execute_input":"2025-02-10T16:17:51.712048Z","iopub.status.idle":"2025-02-10T16:17:51.716989Z","shell.execute_reply.started":"2025-02-10T16:17:51.712026Z","shell.execute_reply":"2025-02-10T16:17:51.716188Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Flatten, Dense, Dropout, BatchNormalization\nfrom tensorflow.keras.optimizers import Adam\n\n# เพิ่ม Fully Connected Layers\nflat1 = Flatten()(model.layers[-1].output)\nclass1 = Dense(512, activation='relu', kernel_initializer='he_uniform')(flat1)\nclass1 = BatchNormalization()(class1)  # ช่วยให้ Training เสถียรขึ้น\nclass1 = Dropout(0.5)(class1)  # ลด Overfitting\n\nclass2 = Dense(256, activation='relu', kernel_initializer='he_uniform')(class1)\nclass2 = BatchNormalization()(class2)\nclass2 = Dropout(0.5)(class2)\n\noutput = Dense(1, activation='sigmoid')(class2)  # Output สำหรับ Binary Classification\n\n# สร้างโมเดลใหม่\nmy_model = Model(inputs=model.inputs, outputs=output)\n\n# ใช้ Adam Optimizer แทน SGD\nopt = Adam(learning_rate=0.0001)\nmy_model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])\n\nmy_model.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:51.717729Z","iopub.execute_input":"2025-02-10T16:17:51.717959Z","iopub.status.idle":"2025-02-10T16:17:52.068136Z","shell.execute_reply.started":"2025-02-10T16:17:51.717940Z","shell.execute_reply":"2025-02-10T16:17:52.067270Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Fit model (ลบบรรทัด reset_states() หากไม่มี stateful RNN)\nhistory = my_model.fit(\n    train_it, \n    validation_data=val_it, \n    epochs=20, \n    verbose=1,\n    callbacks=[PlotLossesKeras()]\n)\n\n# Evaluate model\n_, acc = my_model.evaluate(val_it, verbose=1)  # ใช้ evaluate() แทน evaluate_generator()\nprint(f'> Accuracy: {acc * 100:.3f}%')\n\n# Save model\nbest_model = 'InceptionV3.keras'\nmy_model.save(best_model)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:17:52.069018Z","iopub.execute_input":"2025-02-10T16:17:52.069317Z","iopub.status.idle":"2025-02-10T16:24:01.630799Z","shell.execute_reply.started":"2025-02-10T16:17:52.069288Z","shell.execute_reply":"2025-02-10T16:24:01.629811Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import load_model\nimport os\n\n# บันทึกโมเดล\nsave_path = 'InceptionV3.keras'\nmy_model.save(save_path)\n\n# ตรวจสอบว่าไฟล์ถูกบันทึกหรือไม่\nif os.path.exists(save_path):\n    print(\"Model saved successfully!\")\n\n# โหลดโมเดล\nbest_model = load_model(save_path)\n\n# Evaluate โมเดล\nbest_model.evaluate(val_it, verbose=1)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:24:01.631827Z","iopub.execute_input":"2025-02-10T16:24:01.632504Z","iopub.status.idle":"2025-02-10T16:24:57.932635Z","shell.execute_reply.started":"2025-02-10T16:24:01.632471Z","shell.execute_reply":"2025-02-10T16:24:57.931937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# make a prediction for a new image.\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import img_to_array\nfrom keras.models import load_model\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:24:57.933429Z","iopub.execute_input":"2025-02-10T16:24:57.933667Z","iopub.status.idle":"2025-02-10T16:24:57.937226Z","shell.execute_reply.started":"2025-02-10T16:24:57.933632Z","shell.execute_reply":"2025-02-10T16:24:57.936449Z"}},"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('InceptionV3.keras')  # เปลี่ยนเป็น path ของโมเดลที่เซฟไว้\n\n# เตรียม ImageDataGenerator สำหรับ test set\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\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\nwhile len(selected_images) < num_samples:\n    img, label = next(val_it)  # ใช้ next() หรือ test_it.__next__()\n    if sum(selected_labels) < 5 or label[0] == 0:  # คุมให้ได้ 5 รูปต่อคลาส\n        selected_images.append(img[0])  # ดึงภาพ\n        selected_labels.append(label[0])  # ดึง label\n\n\nselected_images = np.array(selected_images)\n\n# ใช้โมเดล predict\npredictions = model.predict(selected_images)\npred_labels = (predictions > 0.5).astype(int)  # แปลงค่า sigmoid เป็น 0/1\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    axes[i].set_title(f\"True: {true_label}\\nPred: {pred_label}\")\n    axes[i].axis('off')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:24:57.938030Z","iopub.execute_input":"2025-02-10T16:24:57.938338Z","iopub.status.idle":"2025-02-10T16:25:15.663625Z","shell.execute_reply.started":"2025-02-10T16:24:57.938308Z","shell.execute_reply":"2025-02-10T16:25:15.662538Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}