มาสร้าง Image Recognition ด้วย Convolutional Neural Networks (CNN) กันเถอะ
สำหรับหลายๆ คนที่เคยใช้งาน Social Media มา ก็อาจจะเคยได้เห็นถึงความฉลาดของมันในการระบุตัวตนของใบหน้าที่อยู่ในรูปภาพ ชนิดที่ว่าแค่รูปที่มีขนาดเล็กๆ ก็สามารถระบุได้ว่าในรูปนั้นเป็นใคร
แต่หลายคนอาจจะยังไม่รู้ว่ากระบวนการทำงานของการวิเคราะห์ใบหน้านั้นเกิดขึ้นได้อย่างไร
วันนี้ผมเลยเขียนบทความขึ้นมาเพื่ออธิบายถึงวิธีการทำงานเบื้องต้นของกระบวนการจำแนกภาพ หรือ Image Recognition
โดยบทความนี้จะแบ่งออกเป็น 2 ส่วน
ในส่วนแรกจะเป็นการอธิบายถึงทฤษฎี Convolutional Neural Networks หรือ CNN ซึ่งเป็นทฤษฎีที่เรานำมาใช้เพื่อจำแนกรูปภาพ
และในส่วนที่สองจะเป็นวิธีการ และขั้นตอนในการสร้างโมเดลขึ้นมา
Convolutional Neural Networks หรือ CNN คืออะไร?
สำหรับเด็กเล็กๆ การจะเรียนรู้ได้ว่าวัตถุที่เห็นอยู่ตรงหน้าคืออะไร ก็จะต้องเกิดจากการจดจำผ่านก็เห็นซ้ำแล้วซ้ำอีก
ซึ่งสำหรับคอมพิวเตอร์แล้วการจดจำนั้นแตกต่างออกไป เพราะในโลกของคอมพิวเตอร์มีเพียงแค่ตัวเลขเท่านั้น และคอมพิวเตอร์จะแสดงผลของรูปภาพออกมาในรูปของตัวเลขแบบ 2 มิติ (2 dimensionals) เท่านั้น ซึ่งเราจะคุ้นเคยกับคำว่า pixels นั่นแหละครับ
ดังนั้นจะเห็นได้ว่าการที่จะสอนให้คอมพิวเตอร์จดจำ และจำแนกภาพได้นั้น ต้องมีอัลกอลิทึ่มเข้ามาช่วย ซึ่ง Convolutional Neural Networks หรือ CNN ก็คือตัวช่วยนั้นนั่นเอง
แล้ว CNN ทำงานยังไงกันหล่ะ???
CNNs จะมีองค์ประกอบอยู่ 2 ส่วนใหญ่ๆ ได้แก่
1. ส่วนของ Hidden layers หรือ Feature extraction โดยในส่วนนี้จะมีส่วนย่อยที่ทำงานร่วมกันอีก 3 ส่วน คือ
- Convolution ซึ่งเป็นขั้นตอนของการสแกนรูปจาก input โดยจะมีการสร้าง filters (kernels) ขึ้นมาในรูปแบบของ matrix หลังจากนั้นก็จะทำการตรวจสอบ feature เพื่อหาลักษณะ หรือองค์ประกอบต่างๆ ของรูปภาพแต่ละรูป
- ReLU จะเป็นขั้นตอนที่ทำให้ CNN เกิดการเรียนรู้ข้อมูลที่ได้รับมาจากขั้นตอนการตรวจสอบรูปภาพก่อนหน้า โดยข้อมูลจะถูกแปลงมาอยู่ในรูปของ non-linear โดยจะมีการใช้ activation function อย่าง Rectified Linear Unit (ReLU) เพื่อเข้ามาช่วยเพิ่มประสิทธิภาพของ CNN
- Pooling จะทำการลดขนาดของรูปภาพให้เล็กลง เพื่อให้การทำงานของ CNN มีความรวดเร็วมากขึ้น และยังลดการใช้พื้นที่ความจำลงได้อีกด้วย
2. ส่วนของ Classification หลังจากผ่านขั้นตอนของ Hidden layers หรือ Feature extraction แล้ว ต่อมาในส่วนของ classification จะประกอบไปด้วย layer แบบ fully connected (จะเชื่อมกับทุก node ของ layer ก่อนหน้า) ซึ่งจะรับข้อมูลได้เพียง 1 มิติ (1 Dimensional) เท่านั้น ทำให้ต้องมีนำกระบวนการที่เรียกว่า Flatten เข้ามาช่วยในการแปลงข้อมูลจาก 3 มิติ ให้กลายเป็น 1 มิติเสียก่อน
เอาล่ะครับ!!! หลังจากที่ได้รู้เกี่ยวกับทฤษฎีไปคร่าวๆ แล้ว ต่อมาก็ถึงเวลาที่จะต้องมาลองลงมือทำกันบ้างแล้ว…
โดยบทความนี้ผมจะทำการสร้างโมเดลบน Jupyter Notebook ซึ่งหากใครยังไม่เคยลง ก็สามารถค้นหาวิธีลง และทำตามขั้นตอนได้อย่างง่ายๆ เลยครับ
เอาหล่ะ…มาเริ่มกันเลยดีกว่า!!!
.
.
ผมเริ่มต้นจากการดาวน์โหลดชุดข้อมูล Flowers Recognition เข้ามาก่อน
โดยชุดข้อมูลนี้จะเป็นรูปภาพของดอกไม้จำนวน 4,242 ดอก ซึ่งถูกแบ่งตามประเภทของดอกไม้ออกเป็น 5 กลุ่ม (จะมี 5 โฟลเดอร์)
เมื่อดาวน์โหลดชุดข้อมูลมาเรียบร้อยแล้ว เราก็จะมาเปิด Jupyter Notebook ขึ้นมา
หลังจากนั้น ผมจะเอาไฟล์ที่ดาวน์โหลดมาอัพโหลดขึ้นไปบน Jupyter (สำหรับในตัวอย่างผมใช้ไฟล์ zip)
ต่อมาเราก็จะทำการเปิดหน้า Notebook ใหม่ขึ้นมา
เราจะทำการแตกไฟล์ zip ออกมาก่อน ในกล่องแรก
import zipfile
unzip = zipfile.ZipFile(“flowers.zip”, ‘r’)
unzip.extractall(“flowers”)
โดยในบรรทัดที่ 2 “flowers.zip” คือการระบุไฟล์ที่เราต้องการจะแตก
และในบรรทัดที่ 3 “flowers” คือชื่อที่เราจะตั้งให้กับไฟล์หรือโฟลเดอร์ที่เราได้ทำการแตกออกมา
ต่อมาเราจะทำการ import สิ่งที่เราจำเป็นต้องใช้เข้ามาก่อน
from keras.models import Sequential
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
ถ้าสังเกตุชุดข้อมูลที่เรามีจะพบว่า ชุดข้อมูลจะถูกแยกออกมาตามประเภทของดอกไม้แต่ละชนิดเท่านั้น ไม่ได้มีการแบ่งชุดข้อมูลสำหรับ Train และ Validation ออกมาให้
เราจึงจะต้องทำการแบ่งส่วนของข้อมูลออกมาเพื่อใช้สำหรับการ Train และ Validation
โดยครั้งนี้จะทำการแบ่งข้อมูลสำหรับทำ validation ออกมา 30% (validation_split=0.3)
train = ImageDataGenerator(rescale=1.0/255.0,horizontal_flip=True, shear_range=0.2, zoom_range=0.2,width_shift_range=0.2,height_shift_range=0.2, fill_mode=’nearest’, validation_split=0.3)img_size = 128
batch_size = 25
train_steps = 3462/batch_size
validation_steps = 861/batch_sizetraindata = train.flow_from_directory(“flowers/flowers”, target_size = (img_size, img_size), batch_size = batch_size, class_mode=’categorical’, subset=’training’)
validationdata = train.flow_from_directory(“flowers/flowers”, target_size = (img_size, img_size), batch_size = batch_size, class_mode = ‘categorical’, subset=’validation’)
เมื่อแบ่งข้อมูลสำหรับ Train และ Validation เรียบร้อยแล้ว เราก็จะมาสร้างโมเดลกัน!!!
โดยเราจะต้องกำหนดองค์ประกอบต่างๆ ที่เป็นวิธีการของ CNN ให้ครบถ้วน (ยังจำได้อยู่มั๊ยว่ามีอะไรบ้าง???)
#ส่วนนี้คือองค์ปรกอบของ CNN ที่ได้พูดไปแล้วในตอนต้น
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(img_size, img_size, 3), padding=’same’, activation=’relu’))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation=’relu’, padding=’same’))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, (3, 3), activation=’relu’, padding=’same’))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(512, activation=’relu’))
model.add(Dense(5, activation=’softmax’))
model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])
print(model.summary())
หลังจากนั้นเราจะทำการคำนวณออกมาว่าตัวโมเดลที่เราสร้างขึ้นมามีประสิทธิภาพดีมากน้อยแค่ไหน
showmodel = model.fit_generator(traindata, steps_per_epoch=train_steps, epochs=25, validation_data=validationdata, validation_steps=validation_steps)
เรายังสามารถสร้างกราฟที่แสดงถึงค่า accuracy และค่า loss ออกมาได้อีกด้วย
#กราฟแสดงค่าaccuracy
plt.plot(model_hist.history[‘acc’])
plt.plot(model_hist.history[‘val_acc’])
plt.title(‘model Accuracy’)
plt.ylabel(‘accuracy’)
plt.xlabel(‘epoch’)
plt.legend([‘train’, ‘test’], loc=’upper left’)
plt.show()#กราฟแสดงค่าloss
plt.plot(model_hist.history[‘loss’])
plt.plot(model_hist.history[‘val_loss’])
plt.title(‘model Loss’)
plt.ylabel(‘loss’)
plt.xlabel(‘epoch’)
plt.legend([‘train’, ‘test’], loc=’upper left’)
plt.show()
เพียงเท่านี้เราก็จะสามารถสร้างโมเดล CNN เบื้องต้น สำหรับการทำ Image Recognition ได้แล้วครับ
Future work
การสร้างโมเดลสำหรับ Image Recognition ในครั้งนี้ เป็นเพียงการสร้างในเบื้องต้น และจำนวนรูปภาพก็อาจจะยังไม่มาก หรือหลากหลายเท่าที่ควร ซึ่งอาจจะทำให้ยังได้ค่าความแม่นยำที่ไม่มากนัก
ดังนั้นในอนาคตอาจจะลองนำเทคนิคของ Data Augmentation เข้ามาช่วย เพื่อทำให้โมเดลมีความแม่นยำมากยิ่งขึ้น
References
- https://www.learnopencv.com/image-classification-using-convolutional-neural-networks-in-keras/
- https://towardsdatascience.com/applied-deep-learning-part-4-convolutional-neural-networks-584bc134c1e2
- https://towardsdatascience.com/convolutional-neural-networks-from-the-ground-up-c67bb41454e1
- http://cs231n.github.io/classification/
- http://cs231n.github.io/convolutional-networks/