{"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"},{"sourceId":10713718,"sourceType":"datasetVersion","datasetId":6640653},{"sourceId":254818,"sourceType":"modelInstanceVersion","modelInstanceId":217869,"modelId":239582}],"dockerImageVersionId":30627,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-10T16:55:39.433566Z","iopub.execute_input":"2025-02-10T16:55:39.434625Z","iopub.status.idle":"2025-02-10T16:55:39.443579Z","shell.execute_reply.started":"2025-02-10T16:55:39.434586Z","shell.execute_reply":"2025-02-10T16:55:39.442792Z"}},"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-10T13:10:54.374287Z","iopub.execute_input":"2025-02-10T13:10:54.374774Z","iopub.status.idle":"2025-02-10T13:11:08.273000Z","shell.execute_reply.started":"2025-02-10T13:10:54.374741Z","shell.execute_reply":"2025-02-10T13:11:08.272081Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import psutil\nprint(f\"Available Memory: {psutil.virtual_memory().available / 1e9:.2f} GB\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:08.274172Z","iopub.execute_input":"2025-02-10T13:11:08.274493Z","iopub.status.idle":"2025-02-10T13:11:08.279885Z","shell.execute_reply.started":"2025-02-10T13:11:08.274464Z","shell.execute_reply":"2025-02-10T13:11:08.278998Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!fallocate -l 4G /swapfile\n!chmod 600 /swapfile\n!mkswap /swapfile\n!swapon /swapfile\n!free -h  # ตรวจสอบ Swap ที่เพิ่ม\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:08.280929Z","iopub.execute_input":"2025-02-10T13:11:08.281225Z","iopub.status.idle":"2025-02-10T13:11:13.321343Z","shell.execute_reply.started":"2025-02-10T13:11:08.281198Z","shell.execute_reply":"2025-02-10T13:11:13.320244Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"!ls train","metadata":{"execution":{"iopub.status.busy":"2024-01-08T06:57:18.293035Z","iopub.execute_input":"2024-01-08T06:57:18.293457Z","iopub.status.idle":"2024-01-08T06:57:19.311078Z","shell.execute_reply.started":"2024-01-08T06:57:18.293422Z","shell.execute_reply":"2024-01-08T06:57:19.309969Z"}}},{"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-10T13:11:13.322976Z","iopub.execute_input":"2025-02-10T13:11:13.323327Z","iopub.status.idle":"2025-02-10T13:11:14.264940Z","shell.execute_reply.started":"2025-02-10T13:11:13.323292Z","shell.execute_reply":"2025-02-10T13:11:14.264091Z"}},"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-10T13:11:14.266594Z","iopub.execute_input":"2025-02-10T13:11:14.266925Z","iopub.status.idle":"2025-02-10T13:11:15.097449Z","shell.execute_reply.started":"2025-02-10T13:11:14.266893Z","shell.execute_reply":"2025-02-10T13:11:15.096662Z"}},"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-10T13:11:15.100030Z","iopub.execute_input":"2025-02-10T13:11:15.100296Z","iopub.status.idle":"2025-02-10T13:11:26.138363Z","shell.execute_reply.started":"2025-02-10T13:11:15.100273Z","shell.execute_reply":"2025-02-10T13:11:26.137699Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from os import listdir\nfrom numpy import asarray, save\nfrom keras.preprocessing.image import load_img, img_to_array\nimport random\n\n# define location of dataset\nfolder = 'train/'\nphotos, labels = list(), list()\n\n# สุ่มเลือกแค่ 50% ของไฟล์ทั้งหมด\nfiles = listdir(folder)\nrandom.shuffle(files)  # สุ่มลำดับไฟล์\nfiles = files[:len(files) // 2]  # เอาแค่ครึ่งเดียว\n\n# enumerate files in the directory\nfor file in files:\n    # determine class\n    output = 1.0 if file.startswith('dog') else 0.0\n\n    # load image\n    photo = load_img(folder + file, target_size=(100, 100))  # ลดขนาดรูปภาพ\n    photo = img_to_array(photo)\n\n    # store\n    photos.append(photo)\n    labels.append(output)\n\n# convert to a numpy arrays\nphotos = asarray(photos, dtype='float16')  # ใช้ float16 เพื่อลดขนาด\nlabels = asarray(labels, dtype='uint8')    # uint8 ใช้พื้นที่น้อยกว่า float\n\nprint(photos.shape, labels.shape)\n\n# save the reshaped photos\nsave('dogs_vs_cats_photos.npy', photos)\nsave('dogs_vs_cats_labels.npy', labels)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:26.139290Z","iopub.execute_input":"2025-02-10T13:11:26.139752Z","iopub.status.idle":"2025-02-10T13:11:41.587249Z","shell.execute_reply.started":"2025-02-10T13:11:26.139729Z","shell.execute_reply":"2025-02-10T13:11:41.586212Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# # load dogs vs cats dataset, reshape and save to a new file\n# from os import listdir\n# from numpy import asarray\n# from numpy import save\n# from keras.preprocessing.image import load_img\n# from keras.preprocessing.image import img_to_array\n# # define location of dataset\n# folder = 'train/'\n# photos, labels = list(), list()\n# # enumerate files in the directory\n# for file in listdir(folder):\n# \t# determine class\n# \toutput = 0.0\n# \tif file.startswith('dog'):\n# \t\toutput = 1.0\n# \t# load image\n# \tphoto = load_img(folder + file, target_size=(200, 200))\n# \t# convert to numpy array\n# \tphoto = img_to_array(photo)\n# \t# store\n# \tphotos.append(photo)\n# \tlabels.append(output)\n# # convert to a numpy arrays\n# photos = asarray(photos)\n# labels = asarray(labels)\n# print(photos.shape, labels.shape)\n# # save the reshaped photos\n# save('dogs_vs_cats_photos.npy', photos)\n# save('dogs_vs_cats_labels.npy', labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:41.588588Z","iopub.execute_input":"2025-02-10T13:11:41.588944Z","iopub.status.idle":"2025-02-10T13:11:41.593558Z","shell.execute_reply.started":"2025-02-10T13:11:41.588913Z","shell.execute_reply":"2025-02-10T13:11:41.592668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import psutil\nprint(f\"Available Memory: {psutil.virtual_memory().available / 1e9:.2f} GB\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:41.594851Z","iopub.execute_input":"2025-02-10T13:11:41.595477Z","iopub.status.idle":"2025-02-10T13:11:42.145959Z","shell.execute_reply.started":"2025-02-10T13:11:41.595440Z","shell.execute_reply":"2025-02-10T13:11:42.145097Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# load and confirm the shape\nfrom numpy import load\nphotos = load('dogs_vs_cats_photos.npy')\nlabels = load('dogs_vs_cats_labels.npy')\nprint(photos.shape, labels.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:42.147044Z","iopub.execute_input":"2025-02-10T13:11:42.147325Z","iopub.status.idle":"2025-02-10T13:11:42.388890Z","shell.execute_reply.started":"2025-02-10T13:11:42.147302Z","shell.execute_reply":"2025-02-10T13:11:42.387910Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Pre-Process Photos into Standard Directories**","metadata":{}},{"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-10T13:11:42.390115Z","iopub.execute_input":"2025-02-10T13:11:42.390376Z","iopub.status.idle":"2025-02-10T13:11:42.394479Z","shell.execute_reply.started":"2025-02-10T13:11:42.390354Z","shell.execute_reply":"2025-02-10T13:11:42.393648Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create directories\nimport os\ndataset_home = 'dataset_dogs_vs_cats/'\nsubdirs = ['train/', 'test/']\nfor subdir in subdirs:\n    # Create label subdirectories\n    labeldirs = ['dogs/', 'cats/']\n    for labldir in labeldirs:\n        newdir = os.path.join(dataset_home, subdir, labldir)\n        os.makedirs(newdir, exist_ok=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:42.395658Z","iopub.execute_input":"2025-02-10T13:11:42.395982Z","iopub.status.idle":"2025-02-10T13:11:42.404032Z","shell.execute_reply.started":"2025-02-10T13:11:42.395955Z","shell.execute_reply":"2025-02-10T13:11:42.403401Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"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-10T13:11:42.405075Z","iopub.execute_input":"2025-02-10T13:11:42.405903Z","iopub.status.idle":"2025-02-10T13:11:44.716927Z","shell.execute_reply.started":"2025-02-10T13:11:42.405881Z","shell.execute_reply":"2025-02-10T13:11:44.716185Z"}},"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-10T13:11:44.718084Z","iopub.execute_input":"2025-02-10T13:11:44.718748Z","iopub.status.idle":"2025-02-10T13:11:45.839181Z","shell.execute_reply.started":"2025-02-10T13:11:44.718714Z","shell.execute_reply":"2025-02-10T13:11:45.838269Z"}},"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-10T13:11:45.840503Z","iopub.execute_input":"2025-02-10T13:11:45.840775Z","iopub.status.idle":"2025-02-10T13:11:46.955045Z","shell.execute_reply.started":"2025-02-10T13:11:45.840753Z","shell.execute_reply":"2025-02-10T13:11:46.953914Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install livelossplot","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T13:11:46.956761Z","iopub.execute_input":"2025-02-10T13:11:46.957724Z","iopub.status.idle":"2025-02-10T13:11:56.985031Z","shell.execute_reply.started":"2025-02-10T13:11:46.957683Z","shell.execute_reply":"2025-02-10T13:11:56.984112Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from livelossplot import PlotLossesKeras","metadata":{"execution":{"iopub.status.busy":"2025-02-10T13:16:12.133166Z","iopub.execute_input":"2025-02-10T13:16:12.133595Z","iopub.status.idle":"2025-02-10T13:16:12.147944Z","shell.execute_reply.started":"2025-02-10T13:16:12.133559Z","shell.execute_reply":"2025-02-10T13:16:12.147136Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# create data generator with validation split\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    validation_split=0.2  # แบ่ง 20% เป็น validation\n)\n\n# prepare iterators\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\"  # ใช้สำหรับ training\n)\n\nval_it = datagen.flow_from_directory(\n    'dataset_dogs_vs_cats/train/',  # ใช้ dataset เดียวกัน\n    class_mode='binary',\n    batch_size=64,\n    target_size=(224, 224),\n    subset=\"validation\"  # ใช้สำหรับ validation\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Explore Transfer Learning**","metadata":{}},{"cell_type":"markdown","source":"# **Model VGG19**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import VGG19\n\n# โหลดโมเดล VGG19 (ตัด Fully Connected Layers ออก)\nbase_model = VGG19(\n    include_top=False,  # ไม่โหลด Fully Connected Layers\n    weights=\"imagenet\", # ใช้ pretrained weights จาก ImageNet\n    input_shape=(224, 224, 3)\n)\n\nprint(base_model.summary())","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# แช่แข็ง Layers บางส่วน (block1 - block3)\nfor layer in base_model.layers[:15]:  \n    layer.trainable = False","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\n\n\n# ใช้ GlobalAveragePooling2D แทน Flatten\nx = GlobalAveragePooling2D()(base_model.output)\nx = Dense(512, activation=\"relu\")(x)\nx = Dropout(0.5)(x)\nx = Dense(256, activation=\"relu\")(x)\nx = Dropout(0.5)(x)\noutput = Dense(1, activation=\"sigmoid\")(x)\n\n# สร้างโมเดลใหม่\nmodel = Model(inputs=base_model.input, outputs=output)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compile โมเดล\nmodel.compile(\n    loss=\"binary_crossentropy\",\n    optimizer=Adam(learning_rate=1e-4),\n    metrics=[\"accuracy\"]\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau, CSVLogger\n# from livelossplot import PlotLossesKeras\n# import tensorflow as tf\n\n# # Callbacks\n# checkpoint = ModelCheckpoint(\n#     \"best_model_VGG19.keras\", monitor=\"val_loss\", save_best_only=True, mode=\"min\", verbose=1\n# )\n\n# early_stopping = EarlyStopping(\n#     monitor=\"val_loss\", patience=5, restore_best_weights=True, verbose=1\n# )\n# reduce_lr = ReduceLROnPlateau(\n#     monitor=\"val_loss\", factor=0.5, patience=3, min_lr=1e-6, verbose=1\n# )\n# csv_logger = CSVLogger(\"training_log.csv\", append=True)\n\n# # เทรนโมเดล\n# history = model.fit(\n#     train_it,\n#     # steps_per_epoch=len(train_it),\n#     epochs=10,\n#     validation_data=val_it,\n#     # validation_steps=len(val_it),\n#     verbose=1 ,\n#     callbacks=[PlotLossesKeras(), checkpoint, early_stopping, reduce_lr, csv_logger]\n# )","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**ผลลัพธ์จากการเทรนผ่าน Log ของ VGG19**","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Model Resnet152**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet152\n# โหลดโมเดล InceptionV3 (ตัด Fully Connected Layers ออก)\nbase_model = ResNet152(\n    include_top=False, \n    weights=\"imagenet\", \n    input_shape=(224, 224, 3))\n\nprint(base_model.summary())","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 🔹 Freeze 70% ของ Layers (ไม่ให้ weight เปลี่ยนแปลง)\nfor layer in base_model.layers[:360]:  # ResNet152 มี 514 layers\n    layer.trainable = False\n\n# ตรวจสอบว่า layer ไหน trainable บ้าง\nfor layer in base_model.layers:\n    print(f\"{layer.name}: Trainable={layer.trainable}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet152\nfrom tensorflow.keras.models import Model  # ✅ Import Model\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\n\n\n# 🔹 เพิ่ม Fully Connected Layers ด้านบน\nx = GlobalAveragePooling2D()(base_model.output)\nx = Dense(512, activation=\"relu\")(x)\nx = Dropout(0.5)(x)\nx = Dense(1, activation=\"sigmoid\")(x)\n\n# 🔹 สร้างโมเดลใหม่\nmodel = Model(inputs=base_model.input, outputs=x)  # ✅ ใช้ Model ได้แล้ว!\n\n# แสดงโครงสร้างโมเดล\nprint(model.summary())","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\n\n# 🔥 ตั้งค่า Adam optimizer พร้อม learning rate\noptimizer = Adam(learning_rate=5E-5)  # ค่าเริ่มต้น = 0.001\n\n# 🔥 Compile โมเดล\nmodel.compile(\n    optimizer=optimizer,\n    loss='binary_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau, CSVLogger\n# from livelossplot import PlotLossesKeras\n# import tensorflow as tf\n\n# # Callbacks\n# checkpoint = ModelCheckpoint(\n#     \"best_model_ResNet152.keras\", monitor=\"val_loss\", save_best_only=True, mode=\"min\", verbose=1\n# )\n\n# early_stopping = EarlyStopping(\n#     monitor=\"val_loss\", patience=5, restore_best_weights=True, verbose=1\n# )\n# reduce_lr = ReduceLROnPlateau(\n#     monitor=\"val_loss\", factor=0.5, patience=3, min_lr=1e-6, verbose=1\n# )\n# csv_logger = CSVLogger(\"training_log.csv\", append=True)\n\n# # เทรนโมเดล\n# history = model.fit(\n#     train_it,\n#     # steps_per_epoch=len(train_it),\n#     epochs=60,\n#     validation_data=val_it,\n#     # validation_steps=len(val_it),\n#     verbose=1 ,\n#     callbacks=[PlotLossesKeras(), checkpoint, early_stopping, reduce_lr, csv_logger]\n# )","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**ผลลัพธ์จากการเทรนผ่าน Log ของ ResNet152**","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Model InceptionV3**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import InceptionV3\n\n# โหลดโมเดล InceptionV3 (ตัด Fully Connected Layers ออก)\nbase_model = InceptionV3(\n    include_top=False,  # ไม่โหลด Fully Connected Layers\n    weights=\"imagenet\",  # ใช้ pretrained weights จาก ImageNet\n    input_shape=(224, 224, 3)\n)\n\nprint(base_model.summary())","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Model\n\n# โหลดโมเดล \n# 🔹 Freeze เฉพาะ block1 - block3 (ไม่อัพเดต weight)\nfor layer in base_model.layers[:15]:  # หรือใช้ base_model.layers[:]\n    layer.trainable = False\n\n# 🔹 Unfreeze เฉพาะ block4 - block5 (สามารถเรียนรู้ต่อ)\nfor layer in base_model.layers[15:]:\n    layer.trainable = True\n\n# ตรวจสอบว่า layer ไหน trainable บ้าง\nfor layer in base_model.layers:\n    print(f\"{layer.name}: Trainable={layer.trainable}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, models\n\n# ดึง feature maps จาก base_model\nx = base_model.output  \n\n# 🔹 ใช้ GlobalAveragePooling2D แทน Flatten\nx = layers.GlobalAveragePooling2D()(x)  \n\n# 🔹 Fully Connected Layers\nx = layers.Dense(512, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\nx = layers.Dense(256, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\n\n# 🔹 Output Layer\noutput_layer = layers.Dense(1, activation='sigmoid')(x)\n\n# 🔥 สร้างโมเดลใหม่\nmodel = models.Model(inputs=base_model.input, outputs=output_layer)\n\n# 🔍 ดูโครงสร้างโมเดล\nmodel.summary()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.optimizers import Adam\n\n# # 🔥 ตั้งค่า Adam optimizer พร้อม learning rate\n# optimizer = Adam(learning_rate=0.0001)  # ค่าเริ่มต้น = 0.001\n\n# # 🔥 Compile โมเดล\n# model.compile(\n#     optimizer=optimizer,\n#     loss='binary_crossentropy',\n#     metrics=['accuracy']\n# )","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau, CSVLogger\n# from livelossplot import PlotLossesKeras\n# import tensorflow as tf\n\n# # Callbacks\n# checkpoint = ModelCheckpoint(\n#     \"best_model_InceptionV3.keras\", monitor=\"val_loss\", save_best_only=True, mode=\"min\", verbose=1\n# )\n\n# early_stopping = EarlyStopping(\n#     monitor=\"val_loss\", patience=5, restore_best_weights=True, verbose=1\n# )\n# reduce_lr = ReduceLROnPlateau(\n#     monitor=\"val_loss\", factor=0.5, patience=3, min_lr=1e-6, verbose=1\n# )\n# csv_logger = CSVLogger(\"training_log.csv\", append=True)\n\n# # เทรนโมเดล\n# history = model.fit(\n#     train_it,\n#     # steps_per_epoch=len(train_it),\n#     epochs=50,\n#     validation_data=val_it,\n#     # validation_steps=len(val_it),\n#     verbose=1 ,\n#     callbacks=[PlotLossesKeras(), checkpoint, early_stopping, reduce_lr, csv_logger]\n# )","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**ผลลัพธ์จากการเทรนผ่าน Log ของ InceptionV3**","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Model densenet169**","metadata":{}},{"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},{"cell_type":"markdown","source":"# **Model densenet121**","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}