DEV Community

Cover image for OPEN CV & DEEP LEARNING ในการตรวจจับโรคผิวหนัง และคัดกรองโดย model Xception
forcesumetee
forcesumetee

Posted on

OPEN CV & DEEP LEARNING ในการตรวจจับโรคผิวหนัง และคัดกรองโดย model Xception

มะเร็งผิวหนังเป็นหนึ่งในมะเร็งที่พบบ่อยที่สุดในโลก โดยมีผู้ป่วยใหม่มากกว่า 2 ล้านคนในสหรัฐอเมริกาในแต่ละปี https://www.webmd.com/melanoma-skin-cancer/default.htm มะเร็งผิวหนังมีสองประเภทหลักคือ Actinic keratosis (AK) และ Basal cell carcinoma (BCC)

AK เป็นโรคก่อนมะเร็งที่พบบ่อยซึ่งเกิดจากการสัมผัสกับแสงแดดเป็นเวลานาน มักปรากฏเป็นรอยแผลเรียบสีชมพูหรือสีน้ำตาลบนผิวหนัง BCC เป็นมะเร็งผิวหนังที่พบบ่อยที่สุดและเติบโตช้า มักปรากฏเป็นก้อนเล็ก ๆ บนผิวหนังที่มีสีชมพู, สีแดง, สีน้ำตาล, หรือสีดำ

การวินิจฉัย AK และ BCC มักทำโดยแพทย์ผู้เชี่ยวชาญด้านผิวหนัง (แพทย์ผิวหนัง) อย่างไรก็ตาม การวินิจฉัยโรคเหล่านี้อาจเป็นเรื่องยาก เนื่องจากอาจมีลักษณะคล้ายกับสภาพผิวอื่นๆ

ปัญหานี้สามารถแก้ไขได้โดยใช้ระบบการวินิจฉัยที่ช่วยด้วยคอมพิวเตอร์ (CAD) CAD ใช้ปัญญาประดิษฐ์ (AI) ในการวิเคราะห์รูปภาพผิวหนังเพื่อระบุโรคที่อาจก่อให้เกิดเป็นมะเร็ง

Projectนี้มุ่งเน้นไปที่การพัฒนาระบบ CAD สำหรับการวินิจฉัย AK และ BCC โดยใช้ OpenCV และการเรียนรู้เชิงลึก ระบบนี้ใช้โมเดล Xception ซึ่งเป็นโมเดล CNN (Convolutional Neural Network) ที่ได้รับการฝึกฝนบนชุดข้อมูลรูปภาพผิวหนัง

ขั้นตอนที่ 1
โหลดdatasetที่ใช้สำหรับการ train และ Test
โดยdatasetที่ใช้สำหรับ Project ในครั้งนี้เราจะใช้model ที่ได้จาก kaggle
Download Here

ขั้นตอนที่ 2
ทำการสร้างโฟเดอร์ใน google drive เพื่อใช้สำหรับการทำ model ในครั้งนี้ และทำการ upload folder ที่ใช้ในการ test และ train model ในครั้งนี้

Image description

ขั้นตอนที่ 3
ทำการ Import libraries ทั้งหมดที่ต้องการใช้ลงไป

import tensorflow as tf import numpy as np import cv2 import os from tqdm import tqdm import keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten from tensorflow.keras.layers import Conv2D, MaxPool2D from os import listdir from os.path import isfile, join from tensorflow.keras.applications import Xception import matplotlib.pyplot as plt 
Enter fullscreen mode Exit fullscreen mode

โดย libraries ที่ใช้ก็จะมี
1.TensorFlow ช่วยให้สร้างและฝึกโมเดลแมชชีนเลิร์นนิง
2.NumPy รองรับการคำนวณทางคณิตศาสตร์และการจัดการข้อมูล
3.OpenCV ช่วยให้ทำงานกับภาพและวิดีโอ
4.Keras ช่วยให้สร้างโมเดลเครือข่ายประสาทเทียมได้ง่าย
5.matplotlib.pyplot ช่วยให้สร้างกราฟและแผนภูมิ
6.โมเดล Keras อื่นๆ ช่วยให้สร้างสถาปัตยกรรมเครือข่ายประสาทเทียมที่ซับซ้อน
7.ฟังก์ชันจาก os ช่วยจัดการไฟล์และไดเรกทอรี
8.โมเดล Xception ช่วยจำแนกภาพจากชุดข้อมูลขนาดใหญ่

ขั้นตอนที่ 4
ทำการเชื่อมgoogle colab กับ google drive ที่เก็บ dataset ของเรา

from google.colab import drive drive.mount('/content/drive') 
Enter fullscreen mode Exit fullscreen mode

Image description

FOLDERNAME = 'Skin/Xception_Model2' %cd /content/drive/My\ Drive/Skin 
Enter fullscreen mode Exit fullscreen mode

Image description

ขั้นตอนที่ 5
ทำการสร้างพารามิตเตอร์และโหลดภาพสำหรับงานจำแนกภาพผิวหนัง

width = 128 num_classes = 2 trainpath = 'train/' testpath = 'test/' trainImg = [trainpath + f for f in listdir(trainpath) if not f.startswith('.')] testImg = [testpath + f for f in listdir(testpath) if not f.startswith('.')] trainImg , testImg 
Enter fullscreen mode Exit fullscreen mode

Image description

ในขั้นตอนนี้เรากำหนดค่า
width: กำหนดความกว้างของรูปภาพที่จะใช้ (ในพิกเซล) ในกรณีนี้ตั้งค่าเป็น 128 เพื่อปรับให้ขนาดของรูปภาพทั้งหมดมีขนาดเท่ากันเพื่่วยลดจำนวนพารามิตเตอร์ใน model ได้
num_classes: กำหนดจำนวนคลาสสำหรับงานจำแนกภาพ ในกรณีนี้ตั้งค่าเป็น 2 (คือ Actinic keratosis และ Basal cell carcinoma)
trainpath: กำหนดเส้นทางไปยังไดเรกทอรีที่เก็บรูปภาพสำหรับฝึกโมเดล
testpath: กำหนดเส้นทางไปยังไดเรกทอรีที่เก็บรูปภาพสำหรับทดสอบโมเดล
trainImg: รายการชื่อfolderรูปภาพสำหรับฝึกโมเดล
testImg: รายการชื่อfolderรูปภาพสำหรับทดสอบโมเดล

ขั้นตอนที่ 6
สร้างฟังก์ชัน img2data ทำหน้าที่โหลดรูปภาพจากfolderที่กำหนด ปรับขนาดรูปภาพ และแปลงเป็นข้อมูลสำหรับการฝึกโมเดล

def img2data(path): rawImgs = [] labels = [] for imagePath in (path): for item in tqdm(listdir(imagePath)): file = join(imagePath, item) if file[-1] in ('g', 'jpg', 'png'): try: img = cv2.imread(file , cv2.COLOR_BGR2RGB) img = cv2.resize(img ,(width,width)) if img.shape == (width, width, 3): rawImgs.append(img) l = imagePath.split('/')[1] if l == 'Actinickeratosis': labels.append([1,0]) elif l == 'BasalCellCarcinoma': labels.append([0,1]) except: pass return rawImgs, labels 
Enter fullscreen mode Exit fullscreen mode

rawImgs: มีหน้าที่เก็บข้อมูลรูปภาพดิบ (NumPy arrays)
labels: มีหน้าที่เก็บข้อมูลlayerของแต่ละรูปภาพเอาไว้
path: มีหน้าที่ในการวบลูปรูปภาพใน folder test และ train และในแต่ละ path เราจะใช้ tqdm เพื่อวนลูปไปยังไฟล์ทั้งหมด
และนอกจากนี้
เรายังใช้ cv2.imread ในการอ่านไฟล์รูปภาพออกมาเป็น Array เพื่อที่จะสามารถอ่านค่าออกมาได้เป็นค่า 3 มิติ หรือ BGR ได้และเราได้ทำการแปลงจากค่า BGR เป็นค่า RGB เพื่อใช้ในการประมาณผลของรูปภาพได้ และ เราได้ทำการกำหนด One-Hot encoded ด้วยว่า ถ้า l = 1,0 จะมีค่าเป็น Actinic keratosis(AK) ถ้า l = 0,1 จะมีค่าเป็น Basal cell carcinoma (BCC) กรณีที่เกิดการ Error เราได้ทำการใส่ except เพื่อป้องกันไม่ให้โปรแกรมหยุดทำงานในการโหลดรูปภาพได้ และเราจะทำการส่งค่ากลับไปrawImgs และ labelsด้วยคำสั่ง return

ขั้นตอนที่ 7
ทำการโหลดข้อมูลของโมเดลในการ train และ test

x_train, y_train = img2data(trainImg) x_test, y_test = img2data(testImg) 
Enter fullscreen mode Exit fullscreen mode

Image description
ในขั้นตอนนี้เราได้ทำการโหลดรูปภาพที่ใช้สำหรับ train และ test model เอาไว้
x_train: มีหน้าที่ในการเก็บข้อมูลของรูปภาพไว้ที่ใช้ในการ train model
y_train: มีหน้าที่ในการเก็บข้อมูลlayerของรูปภาพไว้ที่ใช้ในการ train model

x_test: มีหน้าที่ในการเก็บข้อมูลของรูปภาพไว้ที่ใช้ในการ test model
y_test: มีหน้าที่ในการเก็บข้อมูลlayerของรูปภาพไว้ที่ใช้ในการ test model

ขั้นตอนที่ 8
แปลงข้อมูลรูปภาพและข้อมูลlayerของรูปภาพ

x_train = np.array(x_train) y_train = np.array(y_train) x_test = np.array(x_test) y_test = np.array(y_test) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /=255 x_test /=255 
Enter fullscreen mode Exit fullscreen mode

โดยขั้นตอนนี้เราจะทำการ แปลงข้อมูลรูปภาพและข้อมูลlayerเป็น NumPy arrays และ Normalize ข้อมูลรูปภาพก่อนป้อนข้อมูลเข้าสู่model Convolutional Neural Network
โดยเราจะแปลง x_train , y_train , x_test , y_test เป็น NumPy arrays และ x_train , x_test ให้เป็นชนิดข้อมูล float32 และทพการแบ่งกลุ่มให้เป็น 255

ขั้นตอนที่ 9
สร้างmodel Xception สำหรับงานจำแนกภาพ Actinic keratosis (AK) และ Basal cell carcinoma (BCC)

def create_xception_model(input_shape=(width, width, 3), num_classes=2): base_model = Xception(weights='imagenet', include_top=False, input_shape=input_shape) base_model.trainable = False x = base_model.output x = Flatten()(x) x = Dense(128, activation='relu')(x) x = Dropout(0.5)(x) # Regularization predictions = Dense(num_classes, activation='softmax')(x) model = Sequential([ base_model, Flatten(), Dense(128, activation='relu'), Dropout(0.5), Dense(num_classes, activation='softmax') ]) return model model = create_xception_model(input_shape=(width, width, 3), num_classes=num_classes) 
Enter fullscreen mode Exit fullscreen mode

ฟังก์ชัน create_xception_model: ฟังก์ชันนี้รับสองค่า
input_shape: รูปร่างของข้อมูลรูปภาพ (width, width, 3)
num_classes: จำนวนคลาสสำหรับงานจำแนกภาพ
ฟังก์ชันในการสร้าง model xception:
ใช้ Xception(weights='imagenet', include_top=False, input_shape=input_shape)โหลดmodel Xception ที่ผ่านการtrainชุดข้อมูล ImageNet และทำการ ตั้งค่า include_top=False เพื่อไม่รวมชั้นสุดท้าย (Fully-connected) และทำการระบุ input_shape ของmodel และ base_model.trainable = False เพื่อป้องกันไม่ให้model Xception ที่โหลดมาถูกปรับพารามิเตอร์ระหว่างการฝึกmodelใหม่
base_model.output: รับoutputจากmodel Xception
Flatten()(x): แปลงข้อมูลจากโครงสร้าง 3 มิติ (width, height, channels) เป็น 1 มิติ
Dense(128, activation='relu')(x): เพิ่มชั้น Fully-connected ใหม่ที่มี 128 neurons network
Dropout(0.5)(x):เพิ่มชั้น Dropout ช่วยลดปัญหา overfitting โดยตัดการเชื่อมต่อ neurons network บางส่วน
Dense(num_classes, activation='softmax')(x): เพิ่มชั้น Fully-connected ใหม่ที่มีจำนวน neurons network เท่ากับจำนวนคลาส และ แปลงค่าเอาต์พุตเป็นค่าความน่าจะเป็นสำหรับแต่ละคลาส
และทำการส่งค่ากลับไปด้วย return
และทำการสร้างโมเดลด้วยคำสั่ง create_xception_model(input_shape=(width, width, 3), num_classes=num_classes)

ขั้นตอนที่ 10
ตั้งค่าการ train model สำหรับ xception

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics= ['accuracy']) batch_size = 32 epochs = 10 
Enter fullscreen mode Exit fullscreen mode

โค้ดนี้ตั้งค่าhyperparameterที่สำคัญสำหรับtrain model Xception
โดยเราได้ตั้งค่า epochs ในการ train model จำนวน 10 ครั้ง และตั้ง จำนวนตัวอย่างข้อมูลที่model xception จะใช้ในการคำนวณการไล่ระดับสี แต่ละครั้งระหว่างการtrain อยู่ที่ 32

ขั้นตอนที่ 11
เริ่มการtrain model

history = model.fit(x_train, y_train ,batch_size=batch_size, epochs=epochs ,validation_data=(x_test, y_test)) 
Enter fullscreen mode Exit fullscreen mode

Image description
คำสั่ง model.fit คือเริ่มทำการ train model โดยเราจะ train model ด้วย x_train และ y_train validation_data ใช้สำหรับประเมินประสิทธิภาพของModelย้อนหลังระหว่าง Train model ตามด้วยจำนวน batch_size ที่32 และกำหนดค่า epochs อยู่ที่10

ขั้นตอนที่ 12
plot graph model ดูค่า accuracy(ความแม่นยำ)และค่า loss(ค่าความผิดพลาด) ของ model ที่เปรียบเทียบActinic keratosis (AK) และ Basal cell carcinoma (BCC)

 plt.figure(figsize=(10,4)) plt.subplot(121), plt.title('model accuracy');plt.ylabel('accuracy');plt.xlabel('epoch') plt.legend(['train', 'validation'], loc='upper left') plt.plot(history.history['accuracy']);plt.plot(history.history['val_accuracy']) plt.subplot(122) plt.title('model loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['train', 'validation'], loc='upper left') plt.plot(history.history['loss']);plt.plot(history.history['val_loss']) acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] avg_acc = np.mean(acc) * 100 avg_val_acc = np.mean(val_acc) * 100 print("Average training accuracy:", avg_acc, "%") print("Average validation accuracy:", avg_val_acc, "%") 
Enter fullscreen mode Exit fullscreen mode

Image description

Image description
ผลลัพธ์
จากกราฟเมื่อได้ทดลองในการ train 10รอบพบว่า
มีความแม่นยำในการtrain อยู่ที่ 89.84%
มีความแม่นยำในการทดสอบ อยู่ที่ 76.12%

ขั้นตอนที่ 13
ทดสอบmodel

testpath = 'test/' testImg = [testpath+f for f in listdir(testpath) if listdir(join(testpath, f))] rimg = [] for imagePath in (testImg): for item in (os.listdir(imagePath)): file = os.path.join(imagePath, item) if item.split('.')[0] != "": img = cv2.imread(file , cv2.COLOR_BGR2RGB) ori = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.resize(img ,(width,width)) rimg = np.array(img) rimg = rimg.astype('float32') rimg /= 255 rimg = np.reshape(rimg ,(1,128,128,3)) predict = model.predict(rimg) label = ['Actinickeratosis','BasalCellCarcinoma'] result = label[np.argmax(predict)] print(predict) print('real:'+str(item)) print('predict:'+str(result)) plt.imshow(ori) plt.show() 
Enter fullscreen mode Exit fullscreen mode

จากการทดสอบนี้พบว่า สามารถทำนายแยกโรคผิวหนังระหว่าง Actinic keratosis (AK) และ Basal cell carcinoma (BCC) ได้โดยใช้ model ที่ถูก Train มาจากข้างต้น

Result

Image description
จากการทดสอบรูปนี้พบว่าค่า One-Hot encoded [ 0.11 , 0.88 ] สังเกตได้ว่า 0.88 มีค่าเข้าใกล้เลข 1 มากกว่า 0.11 ดังนั้นผลลัพธ์จึงเป็น Basal cell carcinoma (BCC) โดยถ้านำ 0.88 เปลี่ยนเป็นเปอร์เซ็นต์แล้วผลลัพธ์ที่ได้คือ 88%

Image description
จากการทดสอบรูปนี้พบว่าค่า One-Hot encoded [ 0.99 , 0.00 ] สังเกตได้ว่า 0.99 มีค่าเข้าใกล้เลข 1 มากกว่า 0.00 ดังนั้นผลลัพธ์จึงเป็น Actinic keratosis (AK)โดยถ้านำ 0.99 เปลี่ยนเป็นเปอร์เซ็นต์แล้วผลลัพธ์ที่ได้คือ 99%

สรุปผล

ผลการทดลองแสดงให้เห็นว่าการใช้ OPEN CV กับ model Xception สามารถจำแนก Actinic keratosis (AK) และ Basal cell carcinoma (BCC) ได้ความแม่นยำอยู่ที่ 76.12% อย่างไรก็ตามถ้าเพิ่มประสิทธิภาพในการประมาณผล เช่น เพิ่มความละเอียดของรูปภาพ หรือ ลองเปลี่ยน model มาใช้ VGG16 หรือ MobileNetV2 อาจจะเพิ่มประสิทธิภาพได้การประมวลผลได้

อ้างอิง
https://opencv.org/
https://www.tensorflow.org/
https://keras.io/api/applications/xception/
https://www.kaggle.com/datasets/riyaelizashaju/skin-disease-image-dataset-balanced/data
https://www.webmd.com/melanoma-skin-cancer/default.htm

Top comments (0)