การจำแนกประเภทภาพ โดยใช้ Support Vector Machine (SVM) ใน Python
Tags: python, svm, ai, machinelearning
Published: 2024-03-28 12:00:21

ในการที่เราจะจำแนกประเภทของภาพในคอมพิวเตอร์นั้น ยกตัวอย่างเช่น แยกรูปของสุนัขกับแมว หนึ่งในวิธีที่เราสามารถเลือกใช้ได้ก็คือการใช้ "Support Vector Machine (SVM)" ซึ่งนีก็ไม่ใช้วิธีเดียวในการจำแนกประเภทภาพ

Support Vector Machines(SVM) คือ อัลกอริทึมการเรียนรู้ของเครื่องแบบ supervised machine learning ประเภทหนึ่ง

Support Vector Machines(SVM) สามารถใช้งานได้หลากหลาย ทั้งการจำแนกประเภท (classification) และการถดถอย (regression)

โดยในบทความนี้เราจะมาดูวิธีการจำแนกประเภทภาพ โดยใช้ Support Vector Machines(SVM) ใน Python ซึ่งจะทำทั้งหมดนี้ใน Google Colab และในส่วนของ Dataset ที่จะนำมาจำแนกนั้นจะเป็นรูปของสุนัข และแมว

------------------------------------------------------------------

### ขั้นตอนการทำ
 
> <u>ขั้นที่ 1 : นำเข้า libraries ที่ต้องใช้ทั้งหมดลงใน Google Colab</u>

```
import pandas as pd 
import os 
from skimage.transform import resize 
from skimage.io import imread 
import numpy as np 
import matplotlib.pyplot as plt 
from sklearn import svm 
from sklearn.model_selection import GridSearchCV 
from sklearn.model_selection import train_test_split 
from sklearn.metrics import accuracy_score 
from sklearn.metrics import classification_report
```
> <u>ขั้นที่ 2 : โหลดข้อมูลชุดรูปภาพลง Google Colab</u> 

โดยในขั้นตอนนี้นั้นเราจะทำการโหลดข้อมูลรูปภาพทั้งหมดลง Google Colab และเปลี่ยนข้อมูลทั้งหมดให้อยู่ในรูปแบบของ Data frame

ดาวน์โหลด Dataset ของสุนัข และแมว ---> [HERE](https://www.kaggle.com/datasets/chetankv/dogs-cats-images/code)

Code สำหรับดาวน์โหลดข้อมูล :
```
Categories=['cats','dogs'] 
flat_data_arr=[] #input array 
target_arr=[] #output array 
datadir='drive/MyDrive/training_set_low'
#path which contains all the categories of images 
for i in Categories: 
      
    print(f'loading... category : {i}') 
    path=os.path.join(datadir,i) 
    for img in os.listdir(path): 
        img_array=imread(os.path.join(path,img)) 
        img_resized=resize(img_array,(150,150,3)) 
        flat_data_arr.append(img_resized.flatten()) 
        target_arr.append(Categories.index(i)) 
    print(f'loaded category:{i} successfully') 
flat_data=np.array(flat_data_arr) 
target=np.array(target_arr)
```
ในส่วนของ `datadir='drive/MyDrive/ForColab'` จะใช้ Goole Drive ในการเก็บข้อมูลชุดข้อมูลรูปภาพลงใน Google Colab (กดรูป Folder Drive ข้างบนให้เป็นรูปขีดทับ)

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uz94qb5rtgchf8ihcf8w.png)

ผลที่ได้จาก code :
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1we4njgf7z1debzpft0d.png)

Code แปลงข้อมูลเป็น Data frame : แปลงอาร์เรย์ทั้งสองให้เป็น DataFrame ของ pandas

```
#dataframe 
df=pd.DataFrame(flat_data)  
df['Target']=target 
df.shape
```
ผลที่ได้จาก code :
เลขด้านหน้าจะเป็นจำนวนข้อมูลทั้งหมด

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hp3j2clzgpxpqr83m0u.png)

> <u>ขั้นที่ 3 : แยกฟีเจอร์อินพุตและเอาต์พุต</u>

ในขั้นตอนนี้ เราจะทำการแยกฟีเจอร์อินพุต (input features) และฟีเจอร์เอาต์พุต (output features) ออกจาก DataFrame ใหม่ที่สร้างขึ้น

- ฟีเจอร์อินพุต หมายถึง ข้อมูลที่ใช้สำหรับป้อนโมเดลแมชชีนเลิร์นนิง
- ฟีเจอร์เอาต์พุต หมายถึง ข้อมูลที่โมเดลแมชชีนเลิร์นนิงทำนาย

code แยกฟีเจอร์อินพุตและเอาต์พุต :

```
#input data 
x=df.iloc[:,:-1] 
#output data 
y=df.iloc[:,-1]

# Splitting the data into training and testing sets 
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.20,random_state=77,stratify=y) 
```

> <u>ขั้นที่ 4 : ทำการสร้างและฝึกโมเดล</u>

- การสร้างโมเดล :
ในขั้นตอนนี้ เราจะทำการสร้างโมเดล Support Vector Machine (SVM)

```
# Defining the parameters grid for GridSearchCV 
param_grid={'C':[0.1,1,10,100], 
			'gamma':[0.0001,0.001,0.1,1], 
			'kernel':['rbf','poly']} 

# Creating a support vector classifier 
svc=svm.SVC(probability=True) 

# Creating a model using GridSearchCV with the parameters grid 
model=GridSearchCV(svc,param_grid)

```

- การฝึกโมเดล :
ก่อนทำการฝึกโมเดล เราจะต้องแบ่งข้อมูลออกเป็นสองชุดก่อน ได้แก่

1. ชุดข้อมูลสำหรับฝึก (Training set) : ใช้สำหรับฝึกโมเดล
2. ชุดข้อมูลสำหรับทดสอบ (Testing set) : ใช้สำหรับประเมินประสิทธิภาพของโมเดล

Code สำหรับฝึกโมเดล
```
# Training the model using the training data 
model.fit(x_train,y_train)
```
เราสามารถฝึกโมเดลด้วยข้อมูล โดยใช้เมธอด `fit`

> <u>ขั้นที่ 5 : ประเมินความแม่นยำของโมเดล</u>

หลังจากฝึกโมเดล SVM แล้ว เราจะทำการทดสอบความแม่นยำของโมเดลด้วยข้อมูลทดสอบ (testing data)

Code สำหรับการทดสอบความแม่นยำของข้อมูล
```
# Testing the model using the testing data 
y_pred = model.predict(x_test) 
  
# Calculating the accuracy of the model 
accuracy = accuracy_score(y_pred, y_test) 
  
# Print the accuracy of the model 
print(f"The model is {accuracy*100}% accurate")
```
ผลที่ได้จาก code : จะเป็นเปอร์เซ็นต์ความแม่นยำของโมเดลออกมา

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0lxzvm1pk0i00tglmq0j.png)

หลังจากประเมินความแม่นยำของโมเดลด้วยค่าความแม่นยำ (accuracy) แล้ว เราสามารถใช้ฟังก์ชัน `classification_report` จาก scikit-learn เพื่อสร้างรายงานประเภท (classification report) สำหรับโมเดล SVM ของเรา

Code สำหรับแสดง classification report :

```
print(classification_report(y_test, y_pred, target_names=['cat', 'dog']))
```
ผลที่ได้จาก code : จะแสดงออกมาในรูปแบบของตาราง

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/suvqqd2dgfnvcrp7aj20.png)

และนี้ก็คือขั้นตอนทั้งหมดสำหรับการเทรนโมเดล Support Vector Machine (SVM) สำหรับจำแนกประเภทภาพ

------------------------------------------------------------------

### การใช้งานโมเดล

Code สำหรับการใช้งาน :

```
path='dataset/test_set/dogs/dog.4001.jpg'
img=imread(path) 
plt.imshow(img) 
plt.show() 
img_resize=resize(img,(150,150,3)) 
l=[img_resize.flatten()] 
probability=model.predict_proba(l) 
for ind,val in enumerate(Categories): 
    print(f'{val} = {probability[0][ind]*100}%') 
print("The predicted image is : "+Categories[model.predict(l)[0]])
```

ตัวอย่างผลลัพธ์ที่ได้ : 
1.
เปอร์เซ็นต์ความแม่นยำ 50% / จำนวนข้อมูลที่ใช้ฝึก 16 รูป (แมว 8 , สุนัข 8)
`path='drive/MyDrive/test_image/cats/cat.4089.jpg'`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9172y6vm9hcbb2p4eqm.png)

2.
เปอร์เซ็นต์ความแม่นยำ 50% / จำนวนข้อมูลที่ใช้ฝึก 16 รูป (แมว 8 , สุนัข 8)
`path='drive/MyDrive/test_image/dogs/dog.4060.jpg'`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aunom2lqb7rirou1caf1.png)

3.
เปอร์เซ็นต์ความแม่นยำ 66.67% / จำนวนข้อมูลที่ใช้ฝึก 32 รูป (แมว 16 , สุนัข 16)
`path='drive/MyDrive/test_image/cats/cat.4089.jpg'`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/siq7s5dvo403068vdye6.png)

4.
เปอร์เซ็นต์ความแม่นยำ 66.67% / จำนวนข้อมูลที่ใช้ฝึก 32 รูป (แมว 16 , สุนัข 16)
`path='drive/MyDrive/test_image/dogs/dog.4060.jpg'`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tucxtubwtdrho47v8u4n.png)

#### สรุปผล

เราจะเห็นว่าถ้าเราต้องการความแม่นยำของการจำแนกประเภทภาพ โดยใช้ Support Vector Machine (SVM) ใน Python ที่มีความแม่นยำที่มากนั้นจะขึ้นอยู่กับจำนวนรูปภาพที่เรานำมาฝึกเลย หากเราใช้ภาพที่เยอะความแม่นยำก็ยิ่งมาก อย่างในตัวอย่างผลลัพธ์การรันตัว Model ที่มีจำนวนรูปภาพสำหรับฝึก 32 ภาพความแม่นยำที่ได้จะอยู่ที่ 66.67% ซึ่งมากกว่า Model ที่มีจำนวนรูปภาพสำหรับฝึก 16 ภาพที่มีความแม่นยำอยู่ที่ 50% 

เพราะฉะนั้นแล้วหากต้องการจำแนกประเภทภาพให้ดีก็แค่เพิ่มข้อมูลในการฝึกก็จะช่วยให้ได้ผลที่แม่นยำมากขึ้นแน่นอน ^-^

------------------------------------------------------------------

ข้อมูลจาก/ชุดภาพข้อมูล 

- https://www.geeksforgeeks.org/classifying-data-using-support-vector-machinessvms-in-python/?ref=lbp
- https://www.geeksforgeeks.org/image-classification-using-support-vector-machine-svm-in-python/
- https://www.kaggle.com/datasets/chetankv/dogs-cats-images?resource=download