Image Classificationด้วย Python:อย่างง่ายและตัวอย่างการสอนแบบรวดเร็ว
Tags: python, machinelearning, ai
Published: 2023-04-07 10:39:52

    

## การจำแนกภาพ (Image classification) เป็นการกำหนดป้ายกำกับหรือชั้นของภาพที่นำเข้า โดยอิงตามเนื้อหาที่ปรากฏในภาพ 
นี่เป็นสิ่งที่พบบ่อยในการประมวลผลภาพคอมพิวเตอร์ และนำไปใช้ในการรู้จำวัตถุ รู้จำใบหน้า และรถยนต์ที่ขับเคลื่อนด้วยตนเอง เป็นต้น

การจำแนกภาพเป็น Machine Learning แบบ supervised learning.

กระบวนการจำแนกภาพประกอบด้วยขั้นตอนต่างๆ ดังนี้

- _การแปรผันภาพ_ (Pre-processing): ขั้นตอนนี้เกี่ยวกับการเตรียมภาพนำเข้าสำหรับการจำแนก ซึ่งอาจรวมถึงการปรับขนาดภาพ การตัดภาพ และการปรับสีและความคมชัดของภาพ

- _การสกัดลักษณะ_(Feature extraction): ขั้นตอนนี้เกี่ยวกับการสกัดลักษณะที่เกี่ยวข้องจากภาพหลังจากทำการแปรผัน ซึ่งจะนำไปใช้เป็นข้อมูลนำเข้าในการจำแนก

- _การจำแนก_(Classification): ขั้นตอนนี้เกี่ยวกับการใช้โมเดลเรียนรู้ของเครื่อง (Machine Learning) เพื่อทำนายชนิดของภาพนำเข้า โดยอิงตามลักษณะที่สกัดมาจากขั้นตอนก่อนหน้านี้

การจำแนกภาพมีหลายประเภท เช่น การจำแนกแบบไบนารี่ (binary classification) การจำแนกแบบหลายชนิด (multi-class classification) และการจำแนกแบบหลายป้ายกำกับ (multi-label classification) โมเดลการเรียนรู้ลึก (Deep Learning) เช่น Convolutional Neural Networks (CNNs) เป็นโมเดลที่นิยมใช้สำหรับการจำแนกภาพ เนื่องจากมีความสามารถในการเรียนรู้ลักษณะของภาพอัตโนมัติจากภาพนำเข้า

การใช้ภาษา Python และไลบรารีต่างๆ สามารถทำการจำแนกภาพได้โดยใช้เทคนิคและไลบรารีต่างๆ เช่น scikit-learn, TensorFlow, และ Keras

## ทำไมต้องใช้ Python สำหรับการจัดประเภทรูปภาพ? 
Python เป็นทางเลือกที่ได้รับความนิยมสำหรับการนำเอาอัลกอริทึมการจัดประเภทรูปภาพมาประยุกต์ใช้ เนื่องจากความเรียบง่าย ความอ่านเข้าใจง่าย และการสนับสนุนของไลบรารีที่มากมาย

Python มีไลบรารีและเฟรมเวิร์กต่างๆ ที่ทำให้ง่ายต่อการนำอัลกอริทึมการจัดประเภทรูปภาพมาประยุกต์ใช้ ได้แก่

NumPy: ไลบรารีสำหรับการทำงานกับอาร์เรย์ขนาดใหญ่ และเมทริกซ์ของข้อมูลตัวเลขหลายมิติ
SciPy: ไลบรารีสำหรับการคำนวณทางวิทยาศาสตร์ซึ่งมีฟังก์ชันสำหรับการทำงานกับรูปภาพ เช่น การอ่านและเขียนไฟล์ภาพ การปรับขนาดและตัดต่อรูปภาพ และการใช้ตัวกรองรูปภาพเพื่อลบเสียงรบกวนออก
scikit-learn: ไลบรารีการเรียนรู้ของเครื่องภายในสำหรับการจัดประเภทรูปภาพ รวมถึงการใช้อัลกอริทึมต่างๆ เช่น เครื่องมือเวกเตอร์สนับสนุน (SVMs) และต้นไม้การตัดสินใจ
TensorFlow: เป็นเฟรมเวิร์กการเรียนรู้เชิงลึกที่ได้รับความนิยม มีเครื่องมือต่างๆ สำหรับสร้างและฝึกโครงข่ายประสาทเทียมสำหรับการจัดประเภท
PyTorch เป็นเฟรมเวิร์กดีพีลีนนั้นยังเป็นทางเลือกที่นิยมใช้สำหรับการสร้างและฝึกโครงข่ายประสาทเทียมสำหรับงานการจัดประเภทภาพ โดยได้รับความนิยมจากความสะดวกในการใช้งานและการใช้ไลบรารี่ต่างๆ ที่มีอยู่ใน Python เช่นเดียวกับ TensorFlow การใช้ไลบรารี่และเฟรมเวิร์กต่างๆ เหล่านี้ทำให้สามารถสร้างอัลกอริทึมจัดประเภทภาพได้อย่างสะดวก โดยนักพัฒนาสามารถโฟกัสไปที่ตัวตรวจจับวัตถุและตัวจัดกลุ่มของอัลกอริทึมของพวกเขาได้เป็นอย่างดี โดยไม่ต้องคำนึงถึงรายละเอียดการสร้างและการใช้งานต่ำของระบบ

## **การสอนสั้น ๆ เกี่ยวกับวิธีการสร้างโมเดลการจำแนกภาพโดยใช้ Python และ Keras:**

ส่วนนี้เป็นส่วนย่อจากตัวอย่างการจำแนกภาพที่ให้ไว้ในเอกสารของ Keras ตัวอย่างนี้แสดงถึงวิธีการสร้างโมเดลการจำแนกภาพจากศูนย์โดยใช้ภาพจากไฟล์ JPEG ที่เก็บไว้บนดิสก์และไม่ต้องใช้โมเดล Keras ที่สร้างไว้ก่อนหน้าหรือน้ำหนักที่ถูกสร้างไว้ก่อนแล้ว การทำงานนี้ใช้ชุดข้อมูล Cats vs. Dogs ของ Kaggle สำหรับการจำแนกแบบไบนารี

การสร้างชุดข้อมูลใช้ฟังก์ชัน image_dataset_from_directory พร้อมกับชั้นการจัดเตรียมข้อมูลและการปรับเปลี่ยนรูปภาพของ Keras

เพื่อการติดตั้ง Keras:

```
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
```
**ขั้นตอนที่ 1: โหลดชุดข้อมูล Cats vs. Dogs**

ดาวน์โหลดข้อมูลแบบ zip ที่มีอยู่ในรูปแบบดิสก์:

```
!curl -O https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_5340.zip

!unzip -q kagglecatsanddogs_5340.zip
!ls
```
คุณควรมีโฟลเดอร์ Animals ที่มีโฟลเดอร์ย่อยสองโฟลเดอร์ (Cats และ Dogs) อยู่:

```
!ls Animals
```
โปรดดูตัวอย่างเดิมสำหรับขั้นตอนเพิ่มเติมเพื่อลบภาพที่เสียหายด้วยนะคะ
**ขั้นตอนที่ 2: สร้างชุดข้อมูล**

เพื่อสร้างชุดข้อมูลใหม่ใช้ต่อไปนี้:

```
image_size = (180, 180)
batch_size = 128

train_ds, val_ds = tf.keras.utils.image_dataset_from_directory(
    "Animals",
    validation_split=0.2,
    subset="both",
    seed=1337,
    image_size=image_size,
    batch_size=batch_size,
)
```
**ขั้นตอนที่ 3: แสดงภาพข้อมูล
**
ภาพแรก9ภาพในชุดข้อมูลการฝึกอบรมของคุณควรปรากฏดังนี้ สัญลักษณ์ 0 คือแมว ส่วนสัญลักษณ์ 1 คือหมา:

```
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):
    for i in range(9):
        ax = plt.subplot(3, 3, i + 1)
        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(int(labels[i]))
        plt.axis("off")
```
ผลลัพธ์ควรมีลักษณะดังนี้:

```
Corrupt JPEG data: 2226 extraneous bytes before marker 0xd4
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wain8mlvw72b8dc4mqsc.png)
**ขั้นตอนที่ 4: เพิ่มข้อมูลภาพแบบการแปลงค่า**

หากชุดข้อมูลของคุณไม่เพียงพอคุณสามารถเพิ่มข้อมูลได้อย่างเทียบเท่าโดยใช้การแปลงค่าแบบสุ่มเพื่อเพิ่มข้อมูลภาพการฝึกอบรมที่สมจริง เช่น คุณอาจใช้การหมุนเล็กน้อยแบบสุ่มหรือการพลิกแนวนอนแบบสุ่มเพื่อให้โมเดลของคุณสามารถเรียนรู้เกี่ยวกับภาพต่าง ๆ ได้มากขึ้น

```
data_augmentation = keras.Sequential(
    [
        layers.RandomFlip("horizontal"),
        layers.RandomRotation(0.1),
    ]
)
```
คุณสามารถแสดงผลตัวอย่างข้อมูลที่ถูกเพิ่มขึ้นโดยการใช้ฟังก์ชัน data_augmentation บนภาพแรกในชุดข้อมูลของคุณได้:

```
plt.figure(figsize=(10, 10))
for images, _ in train_ds.take(1):
    for i in range(9):
        augmented_images = data_augmentation(images)
        ax = plt.subplot(3, 3, i + 1)
        plt.imshow(augmented_images[0].numpy().astype("uint8"))
        plt.axis("off")
```
**ขั้นตอนที่ 5: ทำให้ข้อมูลเป็นมาตรฐาน**

ภาพจะอยู่ในขนาดมาตรฐานของ 240x240 พร้อมกับชุดข้อมูลที่ผลิตเป็นชุดแบบ float32 อย่างไรก็ตาม การมีค่าความสว่างของช่องสี RGB ในช่วง [0, 255] ไม่เหมาะสำหรับระบบประมวลผลของโครงข่ายประสาทเทียม ดังนั้น ดีกว่าจะต้องมาตรฐานเพื่อให้ค่าอยู่ในช่วง [0, 1] คุณสามารถทำได้โดยใช้ชั้น rescaling layer

**ขั้นตอนที่ 6: ประมวลผลข้อมูลของคุณ**

วิธีหนึ่งในการใช้ตัวประมวลผลก่อนการเพิ่มข้อมูลคือการประยุกต์ใช้ตัวประมวลผลก่อนการเพิ่มข้อมูลกับชุดข้อมูลของคุณ ชุดข้อมูลที่ได้จะผลิตชุดรูปภาพที่ถูกเพิ่มขึ้น:

```
augmented_train_ds = train_ds.map(
    lambda x, y: (data_augmentation(x, training=True), y))
```
ในวิธีนี้ การเพิ่มขนาดข้อมูลเกิดขึ้นแบบไม่เชื่อมต่อกันโดยใช้ CPU และต้องมีการเก็บข้อมูลชั่วคราวก่อนที่จะเข้าถึงโมเดล วิธีนี้เหมาะสำหรับการฝึกอบรมบน CPU เพราะการเพิ่มขนาดข้อมูลจะไม่ส่งผลต่อการ block โมเดล คุณควรเลือกวิธีนี้เมื่อไม่แน่ใจ

**ขั้นตอนที่ 7: กำหนดค่า Dataset**

การกำหนดค่า Dataset ควรมุ่งเน้นการทำงานอย่างมีประสิทธิภาพสูงสุด โดยเริ่มต้นด้วยการนำ data augmentation มาใช้กับ training dataset และตรวจสอบว่ามีการใช้ buffered prefetching เพื่อให้สามารถดึงข้อมูลจากดิสก์ได้อย่างต่อเนื่อง โดยไม่ทำให้การทำงานถูก block ตัวอย่างเช่น:

```
train_ds = train_ds.map(
    lambda img, label: (data_augmentation(img), label),
    num_parallel_calls=tf.data.AUTOTUNE,
)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.prefetch(tf.data.AUTOTUNE)
```
**ขั้นตอนที่ 8: สร้างโมเดล**

ในตัวอย่างนี้ เราจะสร้างรุ่นขนาดเล็กของ Xception โครงสร้างนี้ไม่ได้ถูกปรับแต่งเพื่อให้เหมาะสมแต่คุณสามารถใช้ KerasTuner เพื่อหาการกำหนดรูปแบบของโมเดลที่เหมาะสมได้ กระบวนการนี้ประกอบด้วยการเริ่มต้นโมเดลโดยใช้ data_augmentation และจากนั้นเป็นชั้นการปรับขนาดภาพ ต้องรวมชั้น dropout ก่อนชั้น fully connected สุดท้าย:

```
def make_model(input_shape, num_classes):
    inputs = keras.Input(shape=input_shape)

    x = layers.Rescaling(1.0 / 255)(inputs)
    x = layers.Conv2D(128, 3, strides=2, padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation("relu")(x)

    previous_block_activation = x 

    for size in [256, 512, 728]:
        x = layers.Activation("relu")(x)
        x = layers.SeparableConv2D(size, 3, padding="same")(x)
        x = layers.BatchNormalization()(x)

        x = layers.Activation("relu")(x)
        x = layers.SeparableConv2D(size, 3, padding="same")(x)
        x = layers.BatchNormalization()(x)

        x = layers.MaxPooling2D(3, strides=2, padding="same")(x)

        residual = layers.Conv2D(size, 1, strides=2, padding="same")(
            previous_block_activation
        )
        x = layers.add([x, residual])  
        previous_block_activation = x  # Set aside next residual

    x = layers.SeparableConv2D(1024, 3, padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation("relu")(x)

    x = layers.GlobalAveragePooling2D()(x)
    if num_classes == 2:
        activation = "sigmoid"
        units = 1
    else:
        activation = "softmax"
        units = num_classes

    x = layers.Dropout(0.5)(x)
    outputs = layers.Dense(units, activation=activation)(x)
    return keras.Model(inputs, outputs)

model = make_model(input_shape=image_size + (3,), num_classes=2)
keras.utils.plot_model(model, show_shapes=True)
```
**ขั้นตอนที่ 9: ฝึกโมเดลการจัดประเภทภาพ**

ใช้สคริปต์ต่อไปนี้:

```
epochs = 25

callbacks = [
    keras.callbacks.ModelCheckpoint("save_at_{epoch}.keras"),
]
model.compile(
    optimizer=keras.optimizers.Adam(1e-3),
    loss="binary_crossentropy",
    metrics=["accuracy"],
)
model.fit(
    train_ds,
    epochs=epochs,
    callbacks=callbacks,
    validation_data=val_ds,
)
```
ควรจะได้ validation accuracy สูงหลังจาก train ไป 25 epochs (มากกว่า 90%) หาก train มากกว่า 50 epochs อาจทำให้ validation performance เสื่อมลง ซึ่งเป็นสัญญาณของ overfitting

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

สรุปนะคะ

## แนวทางปฏิบัติที่ดีที่สุดสำหรับการจำแนกภาพโดยใช้ Python
1.ใช้ชนิดข้อมูลและโครงสร้างที่เหมาะสม: ใช้ NumPy arrays และ SciPy sparse matrices เพื่อแทนภาพและโครงสร้างข้อมูลอื่น ๆ ให้อยู่ในรูปแบบที่มีประสิทธิภาพและง่ายต่อการจัดการ

2.ทำการประมวลผลและมาตรฐานข้อมูลของคุณก่อน: ก่อนที่จะฝึกโมเดลการจำแนกภาพของคุณ มีความสำคัญที่จะทำการประมวลผลและมาตรฐานข้อมูลของคุณ เช่นการเปลี่ยนขนาดภาพให้เหมือนกัน การแปลงภาพเป็นระดับเทา และการปรับใช้ตัวกรองภาพเพื่อลบเสียง การมาตรฐานข้อมูลของคุณยังช่วยเพิ่มประสิทธิภาพของโมเดลของคุณได้อีกด้วย

3.ใช้ชุดการตรวจสอบเพื่อประเมินผลโมเดลของคุณ: เมื่อฝึกโมเดลการเรียนรู้ของคุณ การประเมินประสิทธิภาพของมันบนข้อมูลที่ไม่เคยเห็นมีความสำคัญ การแบ่งข้อมูลของคุณเป็นชุดการฝึกและการทดสอบและการฝึกโมเดลของคุณบนชุดการฝึกและการประเมินการใช้ชุดการทดสอบ ช่วยให้คุณได้รับความเข้าใจที่ดีขึ้นเกี่ยวกับประสิทธิภาพของโมเดลของคุณบนข้อมูลจริง

4.ใช้ regularization เพื่อป้องกัน overfitting: Overfitting เกิดขึ้นเมื่อโมเดลซับซ้อนเกินไปและเรียนรู้รูปแบบในข้อมูลการฝึกอบรมที่ไม่สามารถนำไปใช้กับข้อมูลที่มองไม่เห็นได้อย่างมีประสิทธิภาพ วิธีหนึ่งในการป้องกัน overfitting คือการใช้ regularization ซึ่งเป็นการเพิ่มเงื่อนไขในโมเดลเพื่อป้องกันไม่ให้โมเดลซับซ้อนเกินไป

5.ใช้ metrics การประเมินที่เหมาะสม: เมื่อประเมินประสิทธิภาพของโมเดลการจำแนกภาพของคุณ มีความสำคัญที่จะใช้ metrics การประเมินที่เหมาะสม ตัวอย่างเช่น หากคุณทำงานกับชุดข้อมูลที่สมดุล (นั่นคือจำนวนตัวอย่างสำหรับแต่ละคลาสเท่ากัน) คุณสามารถใช้ metrics เช่น accuracy, precision, และ recall ได้ แต่หากคุณทำงานกับชุดข้อมูลที่ไม่สมดุล คุณอาจต้องใช้ metrics เช่น F1 score หรือ AUC (Area Under the Curve)


ref:{% embed https://datagen.tech/guides/image-classification/python/?fbclid=IwAR0djIs2JbRwCpiynrWLKn31MPugMSxdT3Znh1OvtPme9A45CLj9xrI1yN0 %}
ref2:{% embed https://analyticsindiamag.com/top-5-image-classification-research-papers-every-data-scientist-should-know/ %}