Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python - Image Classification ด้วย Keras

Image Classification คือการจัดประเภทภาพเข้าสู่หมวดหมู่ต่างๆ ด้วยวิธีอย่าง:

  • Train โมเดลเล็กจากศูนย์ (from scratch)
  • Fine-tune โมเดลสำเร็จรูป เช่น VGG16

ตัวอย่างโค้ด: CNN แบบง่ายจากศูนย์


from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Activation, Dropout, Flatten, Dense
from keras import backend as K

# Config
img_width, img_height = 224, 224
train_data_dir = 'v_data/train'
validation_data_dir = 'v_data/test'
nb_train_samples = 400
nb_validation_samples = 100
epochs = 10
batch_size = 16

# Input shape ตาม backend
if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height)
else:
    input_shape = (img_width, img_height, 3)

# สร้างโมเดล
model = Sequential()

# Block 1
model.add(Conv2D(32, (2, 2), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# Block 2
model.add(Conv2D(32, (2, 2)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# Block 3
model.add(Conv2D(64, (2, 2)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

# Fully connected layers
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))  # ป้องกัน overfitting
model.add(Dense(1))
model.add(Activation('sigmoid'))  # Binary classification

# Compile
model.compile(
    loss='binary_crossentropy',
    optimizer='rmsprop',
    metrics=['accuracy']
)

# Data Generators (Data Augmentation)
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True
)

test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary'
)

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary'
)

# Train
model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size
)

# บันทึกโมเดล
model.save_weights('ImgmodelKeras_saved.h5')

โครงสร้างโฟลเดอร์ข้อมูล (Directory Structure)


v_data/
├── train/
│   ├── class_a/
│   │   ├── img1.jpg
│   │   └── img2.jpg
│   └── class_b/
│       ├── img3.jpg
│       └── img4.jpg
└── test/
    ├── class_a/
    │   └── img5.jpg
    └── class_b/
        └── img6.jpg

สำคัญ: ใช้ TensorFlow/Keras เวอร์ชันใหม่ (TF 2.x)


# TF 2.x / Keras 3.x ใช้วิธีนี้แทน
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Activation, Dropout, Flatten, Dense

# fit_generator → model.fit() (TF 2.1+)
model.fit(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size
)

# Save model แบบสมบูรณ์
model.save('my_model.keras')  # หรือ .h5

Transfer Learning กับ VGG16 (แนะนำสำหรับผลลัพธ์ดีกว่า)


from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout
from tensorflow.keras.models import Model

# โหลด VGG16 ไม่รวม top layers
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# Freeze base layers
for layer in base_model.layers:
    layer.trainable = False

# เพิ่ม custom head
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
predictions = Dense(num_classes, activation='softmax')(x)  # หรือ sigmoid สำหรับ binary

model = Model(inputs=base_model.input, outputs=predictions)

# Fine-tune: unfreeze บาง layers ท้าย
for layer in base_model.layers[-4:]:
    layer.trainable = True

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

สรุป

  • CNN แบบ Scratch: ใช้ได้กับข้อมูลเยอะ โครงสร้างเรียบง่าย
  • Transfer Learning (VGG16, ResNet, EfficientNet): ใช้ได้กับข้อมูลน้อย ให้ accuracy สูงกว่า
  • Data Augmentation สำคัญมาก (shear, zoom, flip)
  • Dropout และ Batch Normalization ป้องกัน overfitting
  • ใช้ model.fit() แทน fit_generator() ใน TF 2.x