@cc8 ผมมี version ที่วันก่อนรันได้ แต่ตอนนี้รันไม่ได้เพราะเข้าใจว่าคุณ cc8 ได้ลบ dataset ทิ้งไป ผมได้แชร์ไว้ให้ที่นี่ครับ https://www.kaggle.com/ratthachat/train-model-unet-code/ สามารถ fork (copy and edit) ไปลองแก้ไข dataset เป็น dataset ชุดใหม่น่าจะรันได้ครับผม
version ที่ใช้script จาก cloud-images-segmentation-utillity-script สามารถรันได้ครับ แต่ version ใหม่ผมใช้
# import keras
import
tensorflow as tf
import
os
os.environ[
"SM_FRAMEWORK"
]
=
'tf.keras'
import
segmentation_models as sm
# no error
สวัสดีครับคุณ @cc8 ช่วงนี้ติดภารกิจหลายอย่าง เลยตอบช้าต้องขออภัยด้วยนะครับ
สำหรับ version tf.keras ลองดูคร่าวๆ ไม่มีอะไรผิดปกติ -- ทว่า error messages ที่บอกว่า "no gradient provided" ก็ค่อนข้างประหลาด ผมเดาว่าอาจจะเกิดจาก tensorflow update เป็นรุ่นใหม่ (ใน Kaggle คือ 2.2.0 และรุ่นใหม่ล่าสุด 2.3.0 ) ในขณะที่ code ของ segmentation model นี้ยังไม่ได้อัพเดต ผมลองใช้ tensorflow รุ่น 2.0 ดู พบว่าพบ error ใหม่ ที่ดูเข้าใจมากขึ้นว่าอาจจะเกี่ยวกับ dataset ที่มีปัญหา (index out of range) ผมได้แชร์ kernel ที่มี error นี้ไว้นี่นี่ครับ
https://www.kaggle.com/ratthachat/model-with-tf-kras?scriptVersionId=40180192
เนื่องจากการ debug ต้องใช้เวลานานในแต่ละปัญหา ต้องรบกวนคุณ @cc8 ลองตรวจสอบตัว dataset อีกทีว่า มีอะไรหรือไม่ครับ ส่วนเรื่องการให้ segmentation model ใช้งานกับ TF 2.3 ได้นั้น สามารถคุยกับเจ้าของผลงานได้โดยตรงเลยครับ และสามารถโพสต์ Kaggle kernel ให้เค้าดูเพื่อให้เห็นภาพได้อีกด้วย 😀 https://github.com/qubvel/segmentation_models/issues
สวัสดีครับคุณ @neural-engineer เรื่องตอบช้าไม่เป็นไรครับ ขอบคุณที่มาตอบข้อสงสัยผมทุกครั้งครับ
ขอคำแนะนำครับ
- ผมเทรนโมเดล ตามลิ้งค์นี้ครับ https://www.kaggle.com/cooncanei/test-1-10-epoch-no-class-weight-vgg19 ผลที่ได้คือค่า loss ที่ epoch 8 ค่าลดลงจาก epoch 7 อย่างมากครับ และหลังจาก epoch 8 ไปค่า loss และ metric คงที่ครับ และเมื่อเอาโมเดลที่ได้จากการเทรนมาทำนาย ให้ผลการทำนายเป็นภาพสีดำทั้งหมดไม่ตรงกับ mask ครับ ผลค่า loss และ metric ที่ออกมาลัษณะนี้เกิดจากอะไรครับ จะสามารถแก้ไขได้อย่างไรบ้างครับ
- ผมนำโมเดลเดิมมาเทรนโดยกำหนดค่า class weights for dice_loss ได้ผลค่า loss ลดลงในลัษณะเดียวกัน นอกจากนี้แล้วค่า loss ติดลบ ตามลิ้งนี้ครับ https://www.kaggle.com/cooncanei/test-1-15-epoch-class-weight-vgg19 ค่า loss ติดลบได้ไหมครับ ค่าติดลบมีความหมายอย่างไรครับ
- ผมเทรนโมเดลเดิม โดยเพิ่มการทำ augmentation ตามลิ้งค์นี้ครับ https://www.kaggle.com/cooncanei/test-4-15-epoch-vgg19-aug ผลค่่า loss และ metric ออกมาในแนวทางเดียวกับโมเดลที่ไม่ได้ทำ augmetation ครับ
ก่อนอื่นต้องเล่าคุณ @cc8 ก่อนว่า เรื่องการตรวจสอบขั้นตอนการผิดพลาดนี้เป็นเรื่องที่ผมเองก็ต้องเจออยู่สม่ำเสมอ แต่ก็ไม่มีเทคนิกที่ตายตัวว่า จะแก้ปัญหาแต่ละจุดอย่างไร เนื่องจากการตรวจสอบการผิดพลาดในขั้น training นี่เป็นขั้นที่ละเอียดมากครับ เพราะความผิดพลาดหรือ bugs นั้นอาจจะเกิดใน ขั้น basic programming (python / numpy) หรือขั้น deep learning programming (keras) หรือขั้นสร้างโมเดล (unet) หรือขั้นตอนการออกแบบการฝึกสอน (training pipeline) หรือแม้แต่ขั้นการวัดผลเอง (validation pipeline)
สำหรับโมเดลของคุณ cc8 นั้น สิ่งที่สำคัญที่สุดที่น่าจะต้องวิเคราะห์ในปัญหาของคุณ cc8 ให้ได้ก็คือ "ผลลัพธ์ในการทดสอบ" (validation performance ) ไม่ดี ได้ mask เป็นสีดำเสมอ ซึ่งแปลว่าโมเดลไม่มีความสามารถในการ detect ภาพที่ไม่เคยเห็นได้จริง เรื่องอื่นอาจเป็นความสำคัญรองลงมา
ในการวิเคราะห์ validation performance นี้นั้น ถ้าเราสมมติว่าไม่มีอะไรผิดพลาดในขั้นตอนการเขียนโปรแกรม เราก็อาจจะมาลองวิเคราะห์ที่ training pipeline และ validation pipeline กันได้
ในเรื่องของ training pipeline นั้น อาจลองดูประเด็นต่างๆ ต่อไปนี้
1. Feasibility analysis : ปัญหานี้โอกาสแก้ไขได้จริง มากน้อยแค่ไหน
ในภาพฝึกสอนนั้น "มนุษย์ผู้เชี่ยวชาญ" หรือ คุณหมอที่เป็นผู้ label ภาพการสอนนั้น (ซึ่งอาจจะเป็นคุณ cc8 เอง) สามารถ label จาก input ได้หรือไม่ (หมายถึงว่า การ label ไม่ได้เกิดจากการนำ input ชนิดอื่นที่คุณภาพสูงกว่ามาช่วยเหลือ) ถ้าผู้เชี่ยวชาญต้องใช้ input ที่มีคุณภาพสูงกว่า ก็อาจหมายความได้ว่า "signal" ที่เราต้องการ detect เพื่อสร้าง mask นั้นอาจไม่ได้อยู่ใน input
ยกตัวอย่าง Feasibility เช่น ในปัญหาเลือดคั่งในสมองจากภาพ DICOM ของ CT Scan นั้น ผู้เชี่ยวชาญสามารถแยกแยะได้จริง จึงผ่านขั้น Feasibility test
ในทางตรงกันข้าม ปัญหาสมองขาดเลือด (หา lesion mask) ซึ่งมีคุณหมออีกท่านนึงเคยปรึกษาผมเป็นการส่วนตัวนั้น จำเป็นต้องใช้ input ที่คุณภาพสูงกว่า คือ CT Perfusion และแม้แต่ผู้เชี่ยวชาญก็ไม่สามารถสร้าง lesion mask จากภาพ DICOM ได้ ดังนั้น signal อาจไม่ได้อยู่ใน DICOM จริง และอาจไม่ผ่านขั้น feasibility test
2. Overfitting analysis : ปัญหานี้แก้ไขได้จริง แต่โมเดลของเรา overfit training data
นั้นคือโมเดล "จำ" training data ตรงๆ พอเจอรูปใหม่ๆ ที่ไม่เคยเห็นก็ไม่สามารถทำนายได้
ปัญหานี้มักเกิดจาก data มีปริมาณที่น้อยจนเกินไป และโมเดลไม่สามารถ generalize ได้
ซึ่งเราพอจะลด degree ของ overfitting ได้ด้วยการทำ augmentation ที่ช่วยเพิ่มความหลากหลายของข้อมูล ซึ่งคุณ cc8 เองก็ได้ส่งตัวอย่างที่ทำ augmentation มาให้ดูใน notebook #3
อย่างไรก็ดี ใน notebook นี้ augmentation ที่ใช้เป็น aug13 ซึ่งเป็นเพียง PadIfNeed … augmentation ที่น่าจะใช้ควรจะเป็น aug12 มากกว่า ซึ่งตรงนี้ไม่แน่ใจว่ามีอะไรผิดพลาดหรือไม่ครับ
นอกจากนี้ ควรลอง visualize aug12 กับ training data ดูสัก 30-100 รูปว่าได้ภาพที่สมเหตุสมผลทางการแพทย์หรือไม่
3. Metric analysis : การวัดผลถูกต้องหรือไม่
ค่า loss ที่พล็อตนั้นถ้าไม่นับเรื่อง ติดลบ (ซึ่งยังไม่ทราบสาเหตุ) ก็ดูสมเหตุผลระดับนึง ที่ training data นั้นมีค่า loss ต่ำกว่า validation data อย่างไรก็ดีใน IOU metric ซึ่งน่าจะเป็นตัวเลขที่สะท้อนความจริงมากกว่าค่า loss กลับแจ้งว่าค่า IOU ของ training และ validation data นั้นดีใกล้เคียงกัน โดย IOU นั้นมีค่าถูกต้องราวๆ 80% ซึ่งขัดแย้งกับผลการทำนายที่ทำนายภาพดำทั้งหมด ตรงนี้ก็อาจมีบางอย่างผิดพลาดได้เหมือนกันครับ
โดยเฉพาะใน notebook #3 นั้นใน epoch สุดท้ายเห็นมี validation IOU ที่ 86% ซึ่งดูดีมากๆ ต้องลอง visualize ตรวจสอบซ้ำดูอีกที
4. Visualization analysis :
ทดลอง visualize ผลทำนาย mask ของทั้ง training data และ validation data ในแต่ละ epoch เพื่อดูว่ามีอะไรที่ผิดปกติไปจากที่ควรจะเป็นหรือไม่
เช่นใน training data นั้น มีบางรูปที่ทำนายถูก 100% แต่มีบางรูปที่ผิด 100% เช่นกัน หรือไม่ เพราะอะไรโมเดลถึงไม่สามารถ เรียนรู้รูปที่ผิดได้
เป็นแนวทางกว้างๆ ก่อนนะครับผม
ยินดีครับคุณ cc8 ยังไงสำหรับเรื่อง bug เนื่องจากเราไม่ทราบชัดเจนกว่าเกิดจากสาเหตุใด ใน 4 ประเด็นข้างต้น คงต้อง discuss และเจาะลึกเพิ่มเติมเป็นรายประเด็น ซึ่งคุณ cc8 ให้รายละเอียดเพิ่มเติมในแต่ละประเด็นได้เลยครับ
อย่างไรก็ดีผมคิดว่าปัญหาเรื่องภาพบนสมองนี้ค่อนข้างยาก และด้วย limit ของ training data ที่อาจมีไม่เยอะ อาจเป็นข้อจำกัดสำคัญของงานชิ้นนี้ครับ