อีก 1 star is born เพื่อนๆ คนไทย (น้องทอม) ที่ทำงานงานได้ยอดเยี่ยมมากๆ ใน Kaggle ในการแข่งขันที่ชื่อว่า Cassava Leaf Disease Classification
ครับ น้องทอมได้เขียนประสบการณ์แชร์ไว้ซึ่งหลายๆ คนคงได้อ่านแล้ว ยังไงขอแปะไว้ที่นี่อีกที่หนึ่งเผื่อใครที่พลาดไปครับ 😀
เมื่อผมอยากเป็นนัมโดซานพระเอก start-up 

การเริ่มต้นของผมก็ได้เริ่มขึ้น …..
สวัสดีทุกคน วันนี้มาแชร์ประสบการณ์การแข่งขัน kaggle (เว็บไซส์แข่งขันดาต้า ที่ใหญ่ที่สุดในโลก) เพื่อสร้างแรงบันดาลใจให้กับน้องๆที่คิดสนใจดาต้า ผมจะพยายามใช้คำศัพท์ คำอธิบายที่ง่ายต่อคนที่ไม่มีความรู้ด้านนี้ ได้เห็นภาพ
แนะนำตัวสั้นๆ ชื่อทอมเป็นวิศวะกรไฟฟ้า เรียนรู้ machine learning ด้วยตัวเองจากศูนย์ !!!
จริงๆ สนใจดาต้ามาปีสองปีแหละ แต่ไม่มีโอกาสได้จริงจัง เมื่อสิ้นปีที่แล้วได้ดูซีรีย์เกาหลีเรื่อง start-up เชื่อว่าหลายคนในกลุ่มนี้ก็น่าจะได้ดูเหมือนกัน จำได้ว่าเริ่มดูปลายเดือนพฤศจิกายนปีที่แล้ว ตอนที่ดูนี่ไฟในตัวลุกเป็นไฟ
แล้วก็บอกกับตัวเองว่า ทำไมเราไม่ลองดูสักตั้งบ้าง
พอเดือนธันวาได้วันหยุดยาว 3 อาทิตย์เลยใช้เวลานี้เรียน machine learning แบบจริงจัง (ผมมีพื้นฐานบ้างอยู่แล้ว จากการสอนน้องๆ แต่รอบนี้เรียนระดับกลาง-สูง)
พอเรียนจบก็เลยลองเข้าแข่งแบบนามโดซาน
ซึ่งผมเลือกการแข่งขันที่ชื่อ Cassava leaf disease classification
เป็นรายการที่มีคนเข้าแข่งขันมากเป็นอันดับสองของปีนี้ 4,869 คน (3,942 ทีม) ผมเริ่มแข่งตอนเดือนสุดท้าย ผู้จัดคือ Makerere University AI Lab ซึ่งเคยจัดมาแล้วรอบหนึ่ง มาปีนี้ผู้จัดได้เพิ่มความยากของการแข่งขันขึ้น จากข้อมูลเดิม 5,000 (600x500) รูปก็เพิ่มมาเป็น 20,000 รูป (800x600) โจทย์การแข่งขันคือจำแนกโรคของใบไม้ว่าป่วยเป็นโรคอะไร
ทีนี้ก่อนทีเราจะเริ่มสร้างโมเดลอะไรก็ตาม เราต้องเริ่มจากการทำ EDA ก่อน เพื่อทราบถึงชุดข้อมูล ซึ่งความยากของการแข่งขันรายการนี้คือ
1. unbalance sample (โรคที่ให้มามี 4 โรคกับปกติ (5 classes) แต่มีโรคนึงที่มีรูปภาพมากกว่าโรคอื่น 6 เท่า) ซึ่งอาจจะทำให้ ทาซาน ของเราเรียนรู้โรคนี้มากกว่าโรคอื่น เกิดเป็น bias ได้ (ผมขออนุญาติใช้คำว่าทาซาน
ตามที่พระเอกนัมโดซานใช้ )
2. noisy label เนื่องจากรูปพวกนี้ ถูก label (วินิจฉัย) โดยคน ซึ่งมีความผิดพลาดสูง เช่นบอกโรคผิด หรือว่าในรูปเดียวกัน มีใบไม้ที่มีโรคมากกว่าหนึ่งโรค แล้วทาซานเราจะตอบโรคไหนดีหล่ะ ในเมื่อคำตอบที่ถูกต้องมีแค่โรคเดียว (มีคนใช้ library cleanlab เพื่อวิเคราะห์ noisy label แล้วพบว่า 8% ของรูปภาพ >1,000 รูปที่มีการ label ที่ผิด)
มาถึงขั้นตอนการเทรนทาซานของเรา โชคดีที่ทุกวันนี้บริษัทใหญ่ๆ เช่น facebook, google, deepmind ได้เทรนทาซานไว้ให้บ้างแล้ว คิดง่ายๆก็คือทาซานนั้นถูกฝึกสอนโดยครูให้เรียนรู้เบสิคสกิลในการจำแนกรูปภาพมาบ้างแล้ว
เราก็แค่ไปรับทาซานมาเรียนรู้โรคใบไม้ต่อ เราเรียกวิธีนี้ว่า transfer learning โดยใช้ pretrained weights
ซึ่งโมเดลสำหรับ image classification ที่ใช้ๆกันเยอะในรายการนี้คือ resnext, seresnext, efficientnet (อาจจะมองเป็นสายพันธุ์ของทาซานก็ได้ครับ)
เนื่องจากต้องทำงานประจำก็เลยใช้เวลาหลังเลิกงานในการเทรนทาซาน ผมนอนวันละ 4-5 ชม (เป็นเวลาหนึ่งเดือน) เพราะต้องตื่นมาดูว่าทาซานเทรนเป็นไงบ้าง (ในการเทรนทาซาน 1 โมเดลใช้เวลาประมาณ 6 ชม. (5folds) บน V100. แล้ว fine tune อีก 2:30 ชม. รวมๆ ประมาณ 9 ชม. ต่อทานซานหนึ่งตัว (หลายๆครั้งที่ผมต้องเริ่มต้นใหม่หลังจากผ่านไปหลายชม. เพราะ set ค่าผิด หรือว่าโค้ดมีปัญหา
)
เอาหล่ะขั้นตอนการเทรนทาซานสำคัญมากๆ เพราะทุกคนได้รับทาซานที่มีความรู้มาเริ่มต้นเท่ากัน เราจะสอนทาซานยังไงให้เก่งกว่าคนอื่น
1. ปัญหาเรื่อง unbalanced sample ผมได้ใช้วิธีการเพิ่ม samples ในชุดข้อมูลที่ unbalance โดยการดึงข้อมูลจากการแข่งครั้งก่อน (แต่ก็ยังมีปัญหาเรื่อง unbalance อยู่) ทาซานบางตัวใช้ข้อมูลชุดนี้ บางตัวไม่ใช้ เพราะสัดส่วนรูปภาพไม่เหมือนกัน เช่น efficientnet ใช้ 512x512 input แต่รูปจากแข่งครั้งก่อนส่วนใหญ่ dimension ต่ำกว่า 512 ผมลอง resize แล้วให้ผลแย่กว่าเดิม
2. เรื่อง noisy label ต้องบอกเลยว่าอันนี้เป็นอะไรที่ยากมากๆๆ เพราะในความเป็นจริงเราต้องการเทรนทาซานของเราให้แยกโรคได้ถูกต้อง แต่ดันมีรูปที่บอกโรคผิด สิ่งที่เกิดขึ้นคือ ทาซานจะเรียนรู้ตามสิ่งที่เราป้อนเข้าไป ทำให้เราเรียนรู้รูปผิดไปด้วย งั้นเราจะทำยังไง ซึ่งผมใช้เวลาในการอ่านเปเปอร์เยอะมากๆ ไม่ว่าจะเป็น active and passive loss functions ลอง loss functions แต่ละแบบ, custom loss functions ผสมผสานกัน, วิธีต่อมาคือ augmentation รูปแบบแปลกๆ cutmix, fmix, cutout, mixup คือการตัดแปะรูปอื่นมาใส่บนรูป วิธีการนี้จะฝึกให้ทาซานเรียนรู้รูปหลอก และไม่จำรูปที่ผิดจนเกินไป
ในการแข่งขันนี้ผมเทรนทาซานไปมากกว่า 40+ ตัว บน 7 architectures (สายพันธุ์) (resnext50, seresnext50, efficientnet b4, b5, Vit_base_patch16, Vit_deit_base_patch16, hybrid resnext + ViT) ก่อนที่จะเอาทาซานที่ดีที่สุด 4 ตัวมาหาค่าเฉลี่ยในการตอบ (submission time ต้องไม่เกิน 9 ชม. ทาซานหนึ่งตัวใช้เวลา 2ชม. จากการทดลอง ผมเลยเลือก 4 ตัว) จำนวนยิ่งเยอะไมได้แปลว่าดีเสมอไป ไว้ผมจะอธิบายให้ฟังอีกทีตอนหลัง
(จริงๆ ปกติแล้วส่วนใหญ่คนจะจับทีมกัน ถ้าดูพวก leader จะฟอร์มทีมกัน เพราะเราเทรนทาซานที่ดีที่สุดแค่ตัวเดียว แล้วเอาไปรวมกับคนอื่น เราก็จะได้ทาซานที่เก่งมากๆ) เอาจริงผมตัดสินใจผิด ที่ไม่ยอมรวมทีมกับคนอื่น -.-“ ตอนนั้นคิดว่าคนเดียวก็ไหว 555
จริงๆ มันมีวิธีทำให้ทาซานเก่งกว่านี้ แต่เนื่องจากเวลาที่จำกัด แล้วแข่งคนเดียวเลยไม่มีเวลาได้ทำ
Boosting ensemble คือเทรนทาซาน (หัวหน้า) เพื่อเลือกว่าจะใช้ weight (น้ำหนักของคำตอบ) ของทาซาน 4 ตัวยังไงให้ได้คำตอบที่ดีที่สุด จริงๆ ผมตั้งใจจะใช้ optuna เพื่อหา weight ที่ให้คำตอบที่ดีที่สุด แต่วันสองวันสุดท้าย ผมเริ่ม burnt out จะอ๊วกออกมาเป็นทาซาน
)
Distilled learning คือการเลือกใช้คำตอบทาซานที่เก่งที่สุด (teacher) แล้วมาเทรนทาซานที่เก่งน้อยกว่า (student) ทีนี้เราก็จะได้ทาซานน้อยที่เก่งขึ้นมาอีก
Pseudo labelling คือการใช้ทาซาน predict test set แล้วเลือกรูปที่มีคำตอบ confidence interval สูงกว่า 90-95% มาใช้ในการเทรนอีกรอบ วิธีนี้ จะทำให้ทาซานของเรามั่นใจกับคำตอบมากขึ้นสร้าง boundary ที่ชัดเจนขึ้น ผมลองวิธีนี้ แต่ทาซานผมกลับไม่ค่อยมั่นใจในคำตอบเท่าไร CI อยู่ที่ 60-70% ในรูปที่ตอบถูก (เฉพาะ fold ก่อน ensemble) เลยไม่ได้ใช้วิธีนี้เพราะคิดว่าน่าจะเสี่ยงเกินไป ผมลองกับแค่ทาซานตัวเดียว อาจจะเป็นเพราะสายพันธุ์นั้นมีนิสัยไม่ค่อยมั่นใจ 555
ถึงแม้ว่าการแข่งครั้งนี้ ผมจะไม่ได้เป็นผู้ชนะเลิศแบบนัมโดซาน (ขอดราม่านิดๆ)
Public 46/3946 เหรียญเงิน คะแนน accuracy 90.7%
ผลการแข่งสุดท้าย Private 26/3946 เหรียญเงิน คะแนน accuracy 90.1% อันดับเพิ่มมา 20 อันดับ คะแนนเท่ากับอันดับ 5 แต่อดได้เหรียญทอง (ห่างไปแค่ 9 อันดับ) (Top 1% ของการแข่งขัน)
การแข่งครั้งนี้เกิด big shake up (อันนี้เป็นศัพท์ของทาง kaggle โดยปกติแล้วการแข่งเค้าจะเอาข้อมูล test set ประมาณ 30% ออกมาให้ผู้แข่งได้ประเมินประสิทธิภาพของทาซานเรา ซึ่งจะบอกคะแนน ranking ใน public leader board ก่อนที่เวลาหมดการแข่งขันจะแจ้งผล private leader board จากชุดข้อมูล 100% ซึ่งคนที่ได้อันดับสูงๆใน public กลับได้ผลที่แย่ใน private ซึ่งเกิดขึ้นได้บ่อย เพราะหลายทีมพยายามเทรนทาซานให้ overfit กับ public LB (ทำให้ทีมที่รวมทาซานเทพๆ ทำผลงานได้ไม่ดี)
หลังจากมีการแชร์ข้อมูลกัน ส่วนใหญ่ก็คิดว่า nosiy label ไม่ควรจะใช้ทาซานหลายสายพันธุ์ กลับกันทาซานสายพันธุ์เดียวที่ robust ก็สามารถทำคะแนนได้ดี ความโหดของ kaggle คือเราเลือกเอา submission ที่ดีที่สุดสองอัน เพื่อใช้ประเมินการแข่งขัน โชคดีที่สองอันที่ผมเลือกไป มีอันนึงทำคะแนนได้ดีใน private set
สุดท้ายอยากฝากให้น้องๆ ทุกคนสนใจลงมือทำโจทย์ชีวิตจริง หาความรู้ อ่านเปเปอร์ อย่าไปกลัวครับ สามารถเลือกอ่าน paper with code จะได้ทำความเข้าใจไปในตัว จริงๆใน kaggle แทบจะหาคนไทยใน leader board ไม่ได้เลย มีแต่คนจีน รัสเซีย ญี่ปุ่น เกาหลี อินเดีย เยอะมากๆ อยากเป็นแรงผลักดันให้คนไทยได้ไประดับโลก
ปล. ใครที่สนใจ kaggle สามารถ DM มาได้ครับ ผมเล็งแข่ง Catheter and line position challenge เกี่ยวกับการแพทย์ สายสวนหลอดเลือด (ตั้งใจว่าจะหานิสิตแพทย์หรืออาจารย์แพทย์ ทำ publication ต่อ ผมพอมี connection บ้างอยู่)
ใครที่สงสัยอะไรก็ถามได้ความ ยินดีให้คำแนะนำ ไม่ว่าจะเป็นเริ่มต้นเรียนยังไง อ่านหนังสืออะไร ฯลฯ
ขอบคุณทุกคนที่เสียเวลาอ่านครับ
ทอม