{"cells":[{"cell_type":"markdown","metadata":{"id":"pVk1SP3EaUvn"},"source":["# Classification with Convolutional Neural Network Using PyTorch\n","\n","ในบทเรียนนี้เราจะทดลองสร้าง Convolutional Neural Network ซึ่งเป็น Neural Network ที่ใช้ฟีเจอร์เชิงพื้นที่ (spatial features) ของภาพเพื่อนำมาช่วยใช้ในการเทรนและทำนายประเภทของภาพ โดยในตัวอย่างนี้เราจะใช้ภาพที่เราได้ทดลองใช้ตอนเรียนเรื่อง Principal Component Analysis (PCA) ซึ่งเป็นภาพที่ผู้ป่วยทดลองวาดนาฬิกา มาทดลองสร้างโมเดลเพื่อแบ่งประเภทกัน\n","\n","ชุดข้อมูล: https://github.com/cccnlab/CDT-API-Network"]},{"cell_type":"markdown","metadata":{},"source":["โดยในขั้น ตอนของการสร้าง Convolutional Neural Network (CNN) นั้น ประกอบไปด้วย\n","1. เตรียม Dataset\n","2. กําหนด input layer โดยมีจํานวนมิติเท่ากับข้อมูลที่เตรียมมา\n","3. กําหนด convolutional layer และ pooling layer โดยอาจทําซํ้าได้หลายรอบสําหรับ\n","feature extraction และการลดขนาดมิติของข้อมูลในแต่ละ layer\n","4. กําหนด fully-connected (dense) layer\n","5. กําหนด logics layer หรือ out put layer ซึ่งในกรณีนี้คือการทํา classification ของ\n","ภาพนาฬิกาที่ถูกวาดโดยผู้ป่วยว่าปกติ (normal) หรือ ผิดปกติ (abnormal)"]},{"cell_type":"markdown","metadata":{},"source":["\n"," \n","[ที่มา](https://www.researchgate.net/figure/Basic-architecture-of-CNN_fig3_335086346)"]},{"cell_type":"markdown","metadata":{},"source":["Convolution คือการดําเนินการทางคณิตศาสตร์ $f * g$ เพื่อแสดงให้เห็นผลของฟังก์ชัน $f$ ที่ เปลี่ยนแปลงไปเมื่อมีฟังก์ชัน $g$ โดยในรูปด้านล่าง สีม่วงคือ $f = [6,2,5,2,1,0,4,3,6,4]$ สีเขียว คือ $g = [6,5,4]$ และสีแดงคือ $f * g = [66,45,44,17,22,32,63,64]$"]},{"cell_type":"markdown","metadata":{},"source":[""]},{"cell_type":"markdown","metadata":{},"source":["เพื่อเปรียบเทียบให้เห็นภาพชัด Convolution ถูกนํามาใช้ใน classic machine learning อย่างมาก สําหรับ การทํา feature extraction ในรูปแบบ 2D โดยมี $f$ คือ image และ $g$ คือ\n","filter (หรืออาจเรียกว่า kernel) โดยใน convolutional layer สามารถเลือกปรับ ขนาดของ input (padding) หรือ ขนาดการเลื่อนของการแสกน (stride) ได้ มีผลลัพธ์ท่ีได้จากการ คํานวณเรียกว่า Feature Map\n"]},{"cell_type":"markdown","metadata":{},"source":[""]},{"cell_type":"markdown","metadata":{},"source":["ในกรณี Back propagation จะมีกระบวนการเรียนรู้เพื่อปรับ filter (kernel) ของ convolutionallayerเพื่อให้มีผลลัพธ์ที่สูงที่สุด\n","โดย convolutional layer จะถูกส่งต่อไปยัง pooling layer เพื่อปรับขนาดภาพ และลดมิติของfeaturemapลง เพื่อให้โมเดลไม่จําเป็นต้องเรียนรู้ค่า weight ที่มีจํานวนมากเกินไป โดยมีเทคนิคที่นิยมคือ max pooling และ average pooling\n","โดย pooling layer สุดท้ายจะถูกรวม และเปลี่ยนรูปไปเป็น fully-connected layer เพื่อคํานวนเป็นoutputlayerใช้สําหรับ classification ภาพนาฬิกาที่ได้ยกนํามาเป็นตัว อย่างในบท นี้"]},{"cell_type":"markdown","metadata":{},"source":["## Download the Data"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":1155,"status":"ok","timestamp":1688465945839,"user":{"displayName":"Korrawiz Chotayapa","userId":"12619977060284176060"},"user_tz":-420},"id":"PMI86_jqaUvq","outputId":"646ab883-3dcd-4e8e-e857-1c90d3c07305"},"outputs":[{"name":"stdout","output_type":"stream","text":["--2023-07-04 10:19:02-- https://github.com/ichatnun/brainCodeCamp/raw/main/Fundamentals/DimensionalityReduction/data/CDT/clock_images.pickle\n","Resolving github.com (github.com)... 140.82.112.3\n","Connecting to github.com (github.com)|140.82.112.3|:443... connected.\n","HTTP request sent, awaiting response... 302 Found\n","Location: https://raw.githubusercontent.com/ichatnun/brainCodeCamp/main/Fundamentals/DimensionalityReduction/data/CDT/clock_images.pickle [following]\n","--2023-07-04 10:19:03-- https://raw.githubusercontent.com/ichatnun/brainCodeCamp/main/Fundamentals/DimensionalityReduction/data/CDT/clock_images.pickle\n","Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.109.133, 185.199.110.133, ...\n","Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n","HTTP request sent, awaiting response... 200 OK\n","Length: 1106083 (1.1M) [application/octet-stream]\n","Saving to: ‘images.pickle’\n","\n","images.pickle 100%[===================>] 1.05M --.-KB/s in 0.05s \n","\n","2023-07-04 10:19:03 (20.2 MB/s) - ‘images.pickle’ saved [1106083/1106083]\n","\n","--2023-07-04 10:19:03-- https://github.com/ichatnun/brainCodeCamp/raw/main/Fundamentals/DimensionalityReduction/data/CDT/labels.pickle\n","Resolving github.com (github.com)... 140.82.113.4\n","Connecting to github.com (github.com)|140.82.113.4|:443... connected.\n","HTTP request sent, awaiting response... 302 Found\n","Location: https://raw.githubusercontent.com/ichatnun/brainCodeCamp/main/Fundamentals/DimensionalityReduction/data/CDT/labels.pickle [following]\n","--2023-07-04 10:19:03-- https://raw.githubusercontent.com/ichatnun/brainCodeCamp/main/Fundamentals/DimensionalityReduction/data/CDT/labels.pickle\n","Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n","Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n","HTTP request sent, awaiting response... 200 OK\n","Length: 630 [application/octet-stream]\n","Saving to: ‘labels.pickle’\n","\n","labels.pickle 100%[===================>] 630 --.-KB/s in 0s \n","\n","2023-07-04 10:19:04 (55.1 MB/s) - ‘labels.pickle’ saved [630/630]\n","\n"]}],"source":["# Download the dataset which contrains images and labels of the Clock Drawing Test (CDT)\n","\n","!wget -O images.pickle https://github.com/ichatnun/brainCodeCamp2023/raw/main/Fundamentals/DimensionalityReduction/data/CDT/clock_images.pickle\n","!wget -O labels.pickle https://github.com/ichatnun/brainCodeCamp2023/raw/main/Fundamentals/DimensionalityReduction/data/CDT/labels.pickle"]},{"cell_type":"code","execution_count":1,"metadata":{"id":"k-ILPP8ZaUvt"},"outputs":[],"source":["# import libraries\n","import torch\n","import torch.nn as nn\n","import torch.nn.functional as F\n","import torch.optim as optim # module ที่เก็บ optimizer ต่างๆ ที่เราจะเอามาใช้ในการ train model\n","from torch.utils.data import Dataset, DataLoader # โหลด dataset มาใช้งาน\n","import torchvision # module สำหรับ computer vision ของ PyTorch\n","import torchvision.transforms as transforms # module สำหรับ transform รูปภาพ เช่น การปรับขนาดรูปภาพ การทำ data augmentation\n","from sklearn.model_selection import train_test_split # ใช้สำหรับแบ่งข้อมูลเป็น train/validation/test set\n","from glob import glob # ใช้สำหรับหา path ของไฟล์ในโฟลเดอร์\n","from PIL import Image # ใช้สำหรับโหลดรูปภาพ และแปลงรูปภาพให้เป็น array\n","from matplotlib import pyplot as plt # ใช้สำหรับ plot รูปภาพ\n","import pickle # ใช้สำหรับ save และ load ข้อมูล\n","import pandas as pd # ใช้สำหรับจัดการข้อมูลในรูปแบบของตาราง\n","import numpy as np # ใช้สำหรับจัดการข้อมูลในรูปแบบของ array\n","import os # ใช้สำหรับจัดการไฟล์และโฟลเดอร์"]},{"cell_type":"markdown","metadata":{"id":"mVUmiMvDaUvt"},"source":["## Prepare Data\n","\n","การเตรียมข้อมูลทำได้โดยการอ่านข้อมูลภาพจาก `images.pickle` และประเภทของภาพจาก `labels.pickle` เพื่อใช้ในการเตรียมข้อมูล จากนั้นเปลี่ยนเป็น dataframe"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"vDNsj1yjaUvu"},"outputs":[],"source":["# โหลดข้อมูลไฟล์ .pickle ที่เราได้ทำการ save ไว้ก่อนหน้านี้ และโหลดมาผ่าน wget จาก github\n","with open(\"images.pickle\", \"rb\") as handle:\n"," images = pickle.load(handle)\n","with open(\"labels.pickle\", \"rb\") as handle:\n"," labels = pickle.load(handle)"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"C0CyAxm6aUvu"},"outputs":[],"source":["# แปลงรูปภาพให้เป็น RGB array และเก็บไว้ใน list\n","list_images = []\n","for image in images:\n"," image = Image.fromarray(image) # Convert array to PIL image\n"," image = image.convert(\"RGB\") # Convert to RGB mode\n"," list_images.append(image)"]},{"cell_type":"markdown","metadata":{"id":"65F202JBaUvv"},"source":["สร้าง dataframe ที่เก็บข้อมูลที่จำเป็นต้องใช้ โดยมี column ดังนี้\n","- `Images` : ภาพที่ใช้ train\n","- `encoded_labels` : ค่า label โดย 0 คือ ปกติ และ 1 คือ ผิดปกติ"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":656,"status":"ok","timestamp":1688465954893,"user":{"displayName":"Korrawiz Chotayapa","userId":"12619977060284176060"},"user_tz":-420},"id":"FTOeHGI-aUvv","outputId":"8fc4a0b1-f088-44fa-8ba3-69862da901a5"},"outputs":[{"name":"stderr","output_type":"stream","text":[":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n",":4: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)\n"]}],"source":["df_data = pd.DataFrame(columns=[\"Images\", \"encoded_labels\"]) # สร้าง dataframe เพื่อเก็บข้อมูลรูปภาพและ label ที่เป็นตัวเลข\n","\n","# นำข้อมูลรูปภาพและ label มาเก็บไว้ใน dataframe\n","for img, label in zip(list_images, labels):\n"," df_data = df_data.append({\"Images\": img, \"encoded_labels\": label}, ignore_index=True)"]},{"cell_type":"markdown","metadata":{"id":"gPyZ2YYJaUvv"},"source":["## Split Data and Prepare DataLoaders\n","\n","แบ่งข้อมูลเป็น train set (90%) และ test set (10%) โดยใช้ `train_test_split` จาก `sklearn.model_selection`"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":20,"status":"ok","timestamp":1688465954894,"user":{"displayName":"Korrawiz Chotayapa","userId":"12619977060284176060"},"user_tz":-420},"id":"NGTw-NzUaUvw","outputId":"fde46b8f-87c0-42d1-a11d-4f991115a838"},"outputs":[{"data":{"text/plain":["(54, 6)"]},"execution_count":6,"metadata":{},"output_type":"execute_result"}],"source":["# แบ่งข้อมูลเป็น train/validation/test set โดยใช้ train/validation set อยู่ในสัดส่วน 90:10\n","train_data, test_data = train_test_split(df_data, test_size=0.1, random_state=42)\n","len(train_data), len(test_data)"]},{"cell_type":"markdown","metadata":{"id":"roaNKSnnaUvw"},"source":["สร้างชุดข้อมูล dataset จาก training และ testing โดยใช้ `torch.utils.data.Dataset` and `torch.utils.data.DataLoader` โดย\n","\n","- `Dataset` เป็น class ที่ใช้ในการกำหนดชุดข้อมูลของเรา โดยปกติจะประกอบด้วย 3 ฟังก์ชันหลักคือ `__init__` ใช้เพื่อประกาศค่าต่างๆ, `__len__` เป็นฟังก์ชันที่ให้ขนาดของชุดข้อมูล, และ `__getitem__` ที่มี index เป็น input และให้ `img` และ `label` ของ index นั้นๆออกมา\n","- `DataLoader` ส่วนมากจะใช้ร่วมกับ `Dataset` ที่เราสร้างขึ้น โดยเมื่อเราประกาศ `Dataset` แล้วจะสามารถนำ `DataLoader` มาครอบ `Dataset` เพื่อใช้ในการดึงข้อมูลออกมาเป็น batch ได้"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"hvHga8XtaUvw"},"outputs":[],"source":["# สร้างขั้นตอนสำหรับการแปลงข้อมูลรูปภาพรวมเป็นตัวแปร transform โดย\n","# 1. ทำการแปลงรูปภาพให้เป็น tensor\n","# 2. ทำการ normalize รูปภาพด้วย mean และ standard deviation ของชุดข้อมูล\n","transform = transforms.Compose(\n"," [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]\n",")\n","\n","base_path = \"CDT_dataset\" # กำหนด path ของ dataset ที่เราจะเก็บไว้\n","\n","# สร้าง class สำหรับการโหลด dataset ที่เราสร้างขึ้นมา\n","class CDT_dataset(Dataset): \n"," def __init__(self, img_data, base_path, transform):\n"," self.img_data = img_data\n"," self.base_path = base_path\n"," self.transform = transform\n","\n"," def __len__(self): # สร้าง function สำหรับ return จำนวนข้อมูลใน dataset ด้วยการใช้ len(...)\n"," return len(self.img_data)\n","\n"," def __getitem__(self, index): # สร้าง function สำหรับ return ข้อมูลและ label ของข้อมูลใน dataset ด้วยการใช้ index\n"," # โหลดรูปภาพจาก path ที่เก็บไว้\n"," img = self.img_data.iloc[index][\"Images\"]\n"," # ลดขนาดภาพให้มีขนาด 32x32 เพื่อใช้ในการทำนาย\n"," img = img.resize((32, 32)) \n"," # ถ้ามีการสร้างขั้นตอนการแปลงข้อมูลรูปภาพ ให้ทำการแปลงข้อมูลรูปภาพด้วย\n"," if self.transform is not None:\n"," img = self.transform(img)\n"," # สร้าง label ของข้อมูล\n"," label = self.img_data.iloc[index][\"encoded_labels\"]\n"," # ส่งข้อมูลรูปภาพและ label กลับไป\n"," return img, label\n","\n","\n","train_dataset = CDT_dataset(train_data, base_path, transform) # สร้าง train dataset\n","test_dataset = CDT_dataset(test_data, base_path, transform) # สร้าง test dataset"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"Zg0tWa2jaUvx"},"outputs":[],"source":["# สร้าง train loader และ test loader โดยกำหนดให้มี batch size เท่ากับ 4 และ shuffle ข้อมูล\n","# โดยที่ DataLoader คือ class สำหรับการโหลดข้อมูลในรูปแบบของ batch\n","train_loader = DataLoader(train_dataset, batch_size=4, shuffle=True) # สร้าง train loader\n","test_loader = DataLoader(test_dataset, batch_size=4, shuffle=True) # สร้าง test loader"]},{"cell_type":"markdown","metadata":{"id":"jiBIfq7haUvx"},"source":["เขียนฟังก์ชันเพื่อยกตัวอย่างภาพที่ใช้ train โดยใช้ `next(iter(train_loader))` เพื่อดึงตัวอย่างออกมา 1 batch ในด้านบนเรากำหนดให้ `batch_size` มีค่าเท่ากับ 4"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":210},"executionInfo":{"elapsed":12,"status":"ok","timestamp":1688465954897,"user":{"displayName":"Korrawiz Chotayapa","userId":"12619977060284176060"},"user_tz":-420},"id":"BkCBEg1daUvx","outputId":"bf4792c8-161d-430b-a27d-4c6f0f140f12"},"outputs":[{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAh8AAACwCAYAAACviAzDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAs60lEQVR4nO2de1TVVfr/33gBr2DiCCKiaBbeMxVFLS0xMvOSdndGu8y0nKC8rFVqTfadGgdnZq3RaszWNGVNZZZNalnqGN5LRPGSSqIlqalgZohXNNm/P+bnZz37OXLgIHwOnPN+rXXW2pvn8Dmb/bmczX6e5/2EGGMMCCGEEEJcopa/B0AIIYSQ4IKLD0IIIYS4ChcfhBBCCHEVLj4IIYQQ4ipcfBBCCCHEVbj4IIQQQoircPFBCCGEEFfh4oMQQgghrsLFByGEEEJchYsPQgghhLhKlS0+5syZgzZt2qBevXro3bs3srKyquqjCCGEEFKDCKmK2i4ffPABxo4di9deew29e/fG7NmzsXDhQuTm5qJ58+Zef7ekpARHjhxB48aNERISUtlDI4QQQkgVYIzBqVOnEBMTg1q1ytjbMFVAYmKiSU1NdfqXLl0yMTExJj09vczfPXTokAHAF1988cUXX3zVwNehQ4fK/K6vg0rmwoULyM7OxrRp05yf1apVC8nJydi4caPH+4uLi1FcXOz0zf/fiJk0aRLCwsIqe3iEEEIIqQKKi4sxa9YsNG7cuMz3Vvri4/jx47h06RKioqKsn0dFRWHPnj0e709PT8cf//hHj5+HhYVx8UEIIYTUMMoTMuH3bJdp06bh5MmTzuvQoUP+HhIhhBBCqpBK3/lo1qwZateujYKCAuvnBQUFiI6O9ng/dzgIIYSQ4KLSdz5CQ0PRo0cPZGRkOD8rKSlBRkYGkpKSKvvjCCGEEFLDqPSdDwCYPHkyxo0bh549eyIxMRGzZ8/GmTNn8PDDD1/1sf/v//7v6gdIqgXeziXPc+BQ1rnkuQ4ceE8HB5VxLqtk8XHffffhxx9/xPTp05Gfn48bbrgBy5cv9whCJYQQQkjwUSWLDwBIS0tDWlpaVR2eEEIIITUUv2e7EEIIISS4qLKdD+KJEUr2RqnalylFS6o1Fy9edNoXLlywbFJET9saNGjgtOvVq2fZ9DUh+7xeCCE1GT7BCCGEEOIqXHwQQgghxFXodnGR8+fPO+21a9datvr161v96667zmm3aNGiagdGyuSXX36x+jt37rT6V6pPdCWbPpdS0VdLEtetW9fqSzE+7aKJiIhw2tdcc43nH0BK5dKlS1b/6NGjTjsmJsayVYW7q6SkxOpL11xoaGiVfz4h/oBXMiGEEEJchYsPQgghhLgKFx+EEEIIcRXGfLiIjOvQKZdffvml1e/SpYsrYyKlc+7cOae9bds2yyZTZAGga9euTlvHEGRmZpZq+/777512t27dLFubNm2svowdOXXqlGU7cOCA0/75558tW1xcnNWvU4e3vTf27NnjtHVs1rBhw5x2eHi4ZZOxG7qwZl5entWX9tq1a1u206dPO20d26OvHxkX1KhRI8smC3k2a9bMsmm16fKUQA9mTp486bR15XUZY6XPpZznvXv3WrZly5ZZ/b59+zrtVq1aWTZ5/nQsWE2FOx+EEEIIcRUuPgghhBDiKlx8EEIIIcRVAsr5q/UVzpw5Y/UbNmzotP3h4/zhhx+cth7b9ddfb/V3797ttKWGA2DHF/iC1hOQcxBIPl/9d0q86SToc7J9+3an3bJlS8um4yjkZ+q5lP7ayMhIy9a2bVunLXVgAE+NB9lv3LixZZPxB8eOHbNs2tcs/cn6OMGI9tPfeuutTlvehwCwaNEip925c2fLJuM4ZLwQALRv397qy/tdxw/p55hExv0AduyPvn5l7I/+O6RmDAAMHz7caQejlkhRUZHV37Rpk9U/e/as05bxHwBw/Phxp61jawYMGOC0c3JyLNvBgwetfuvWrZ22jjGTx5UaUADQoUMHq19TYrqC7yojhBBCiF/h4oMQQgghrlIz9mfKid5u/+6776x+p06dnHZVbU3J7blXXnnFssmtzwcffNCy6S245cuXO21ZMRUAxo8f77R1OqbeMpUpvfo4cvtQuwP0tmygIs+XToeUrhW9Lau3v2X6mze3i06Tk2mV2gWir2dv2+H79u1z2lpeXbp2AOCnn35y2lo2ntLs9jzrlPddu3Y57blz51q2p556ymlrN6pGp8xKtBtIol00FT1f7777rtXfsWOH0+7evXuFjlnTkCnV33zzjWXTz1WZtvzJJ59YtsTERKcdGxtr2eT1ou/95ORkq3/HHXc4bf2sli49ef8CwNKlS61+TXGhVd+REUIIISQg4eKDEEIIIa7CxQchhBBCXCWg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","text/plain":[""]},"metadata":{},"output_type":"display_data"},{"name":"stdout","output_type":"stream","text":["abnormal normal abnormal abnormal\n"]}],"source":["# สร้างฟังก์ชันสำหรับการแสดงรูปภาพและ label ของข้อมูลใน dataset\n","def imshow(img):\n"," img = img / 2 + 0.5\n"," npimg = img.numpy()\n"," plt.imshow(np.transpose(npimg, (1, 2, 0)))\n"," plt.show()\n","\n","images, labels = next(iter(train_loader)) # ดึงข้อมูลจาก train loader มาเก็บไว้ในตัวแปร images และ labels\n","# iter(...) คือ function สำหรับการสร้าง iterator ของ train loader\n","# next(...) คือ function สำหรับการดึงข้อมูลจาก iterator ของ train loader มาเก็บไว้ในตัวแปร images และ labels\n","\n","SD_type = {0: \"normal\", 1: \"abnormal\"} # สร้าง dictionary สำหรับแปลง label ที่เป็นตัวเลขเป็นชื่อของ class\n","\n","imshow(torchvision.utils.make_grid(images)) # แสดงรูปภาพที่อยู่ในตัวแปร images\n","classes = (\"normal\", \"abnormal\") # กำหนดชื่อของ class ที่เรามี\n","print(\" \".join(f\"{classes[labels[j]]:5s}\" for j in range(4))) # แสดง label ของข้อมูลที่อยู่ในตัวแปร labels"]},{"cell_type":"markdown","metadata":{"id":"TSx2h4KHaUvx"},"source":["## Introduction to Convolution\n","convolution เป็นวิธีการนึ่งที่ที่ดูการเปลี่ยนแปลงของฟังก์ชั่นหนึ่ง เมื่อมีอีกฟังก์ชั่นเข้ามา ใน deep-learning convolution ถูกนำมาใช้อย่างแพร่หลายในงานที่เกี่ยวกับรูปภาพเพื่อดึงข้อมูลเชิงพื้นที่ (spatial feature) ออกมาจากรูปภาพ โดย pytorch จะใช้คำสั่ง `nn.Conv2d` ในการทำ convolution\n","โดย parameters ที่สำคัญจะประกอบไปด้วย\n","* `in_channels`: input image channel\n","* `out_channels`: output channel หลังจาก convolve แล้ว\n","* `kernel_size`: ขนาดของ filter ที่นำมา convolve กับรูปของเรา\n","* `stride`: filter จะเคลื่อนที่ทีละกี่ pixel ค่า default = 1\n","* `padding`: padding รูปภาพ ค่า default = 0\n","\n","ภาพที่ได้หลังจากการ convolution อาจจะมีขนาด/depthเปลี่ยนไปขึ้นอยู่กับ parametersซึ่งเราสามารถคำนวนขนาดของภาพที่ออกมาได้ดังนี้\n","\n","`output_size = ((input_size - kernel_size + 2 * padding) / stride) + 1`"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":394,"status":"ok","timestamp":1688465955282,"user":{"displayName":"Korrawiz Chotayapa","userId":"12619977060284176060"},"user_tz":-420},"id":"_czkGldbaUvy","outputId":"30328401-fbb4-4a1a-dcb3-363500d24efd"},"outputs":[{"data":{"text/plain":["torch.Size([1, 3, 5, 5])"]},"execution_count":10,"metadata":{},"output_type":"execute_result"}],"source":["# สมมุติว่ามีรูปภาพ 1 ภาพ ขนาด 5x5 และมี 3 ช่องสี\n","input = torch.randn(1, 3, 5, 5)\n","input.shape"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":27,"status":"ok","timestamp":1688465955297,"user":{"displayName":"Korrawiz Chotayapa","userId":"12619977060284176060"},"user_tz":-420},"id":"n-UVz5IuaUvy","outputId":"20bd6819-c464-4c54-d3ed-83aa981651cd"},"outputs":[{"data":{"text/plain":["torch.Size([1, 16, 3, 3])"]},"execution_count":11,"metadata":{},"output_type":"execute_result"}],"source":["conv = nn.Conv2d(in_channels=3, # จำนวนช่องสีของภาพ\n"," out_channels=16, # จำนวนช่องสีของภาพที่เราต้องการให้เป็น output\n"," kernel_size=3, # ขนาดของ filter\n"," stride=1, # ขนาดของการเคลื่อนที่ของ filter\n"," padding=0) # จำนวนช่องสีที่เราต้องการให้เพิ่มเติมเพื่อให้ขนาดของภาพเท่าเดิม\n","# output size = (5 - 3 + 2*0)/1 + 1 = 3\n","output = conv(input) # ทำการคำนวนด้วยการป้อน input ลงไปใน conv ซึ่งเป็น object ที่เราสร้างไว้ให้ทำหน้าที่เป็น convolution ในสองมิติ \n","output.shape # depth ของภาพจะเพิ่มเป็น 16และ dimension ของภาพจะเท่ากับการคำนวนคือ 3"]},{"cell_type":"markdown","metadata":{"id":"XkwGhz4xaUvy"},"source":["## Train the Model\n","\n","สร้าง model โดยใช้ `torch.nn.Module` ซึ่งเป็นตัวแบบของ Neural Network model ใน pytorch โดยมี layer ดังนี้\n","- Convolutional layer (`nn.Conv2d`) ซึ่งจะรับค่าทั้งหมด 3 ค่าคือ input depth, output depth และ kernel size ยกตัวอย่างเช่นในเลเยอร์แรก `nn.Conv2d(3, 6, 5)` จะรับ input depth ของภาพเท่ากับ 3 นั่นก็คือ RGB channel นั่นเอง และ output ออกมาเป็นภาพที่มี depth เท่ากับ 6\n","- จากนั้นก็จะส่งต่อไปให้ `nn.MaxPool2d(2, 2)` ซึ่งมี kernel size เท่ากับ 2 และ stride เท่ากับ 2 โดยจะลดขนาดของภาพเป็นครึ่งหนึ่งนั่นเอง (แต่ depth เท่าเดิม)"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"EDT0xGwNaUvy"},"outputs":[],"source":["class Net(nn.Module): # สร้าง class สำหรับการสร้างโมเดลจาก nn.Module\n"," def __init__(self): # สร้าง constructor ของ class\n"," super().__init__() # เรียกใช้ constructor ของ nn.Module\n"," self.conv1 = nn.Conv2d(3, 6, 5) # สร้าง convolution layer แรก โดยมี in_channels เท่ากับ 3 และ out_channels เท่ากับ 6 และมี kernel_size เท่ากับ 5\n"," self.pool = nn.MaxPool2d(2, 2) # สร้าง pooling layer โดยมี kernel_size เท่ากับ 2 และ stride เท่ากับ 2\n"," self.conv2 = nn.Conv2d(6, 16, 5) # สร้าง convolution layer ที่สอง โดยมี in_channels เท่ากับ 6 และ out_channels เท่ากับ 16 และมี kernel_size เท่ากับ 5\n"," self.fc1 = nn.Linear(16 * 5 * 5, 120) # สร้าง fully connected layer แรก โดยมี in_features เท่ากับ 16 * 5 * 5 และ out_features เท่ากับ 120\n"," self.fc2 = nn.Linear(120, 84) # สร้าง fully connected layer ที่สอง โดยมี in_features เท่ากับ 120 และ out_features เท่ากับ 84\n"," self.fc3 = nn.Linear(84, 10) # สร้าง fully connected layer ที่สาม โดยมี in_features เท่ากับ 84 และ out_features เท่ากับ 10\n","\n"," def forward(self, x): # สร้าง method สำหรับการทำ forward propagation\n"," x = self.pool(F.relu(self.conv1(x))) # ทำการ convolution และ pooling และ activation function (ReLu) ใน convolution layer แรก\n"," x = self.pool(F.relu(self.conv2(x))) # ทำการ convolution และ pooling และ activation function (ReLu) ใน convolution layer ที่สอง\n"," x = torch.flatten(x, 1) # ทำการ flatten ข้อมูลใน x ให้เหลือแค่ batch dimension\n"," x = F.relu(self.fc1(x)) # ทำการแปลงผ่าน fully connected และ activation function (ReLu) ใน fully connected layer แรก\n"," x = F.relu(self.fc2(x)) # ทำการแปลงผ่าน fully connected และ activation function (ReLu) ใน fully connected layer ที่สอง\n"," x = self.fc3(x) # ทำการแปลงผ่าน fully connected ใน fully connected layer สุดท้าย\n"," return x # ส่งค่า x กลับ\n","\n","\n","model = Net() # สร้าง object ของ class Net"]},{"cell_type":"markdown","metadata":{},"source":["**เราทราบได้อย่างไรว่า class ที่เราสร้างขึ้น มี network layer เชื่อมต่อกันอย่างไร**\n","\n"," \n"," เฉลย\n"," \n"," เราสามารถดูได้จากขั้นตอนการแปลง input ผ่าน method `forward` ที่อยู่ใน class ได้ โดยจากตัวอย่างด้านบน จะพบว่า network ของเรามีการเชื่อมต่อกันแบบเรียงลำดับดังนี้\n"," \n","