Is that a Supra?! (Thai version)

Jittaraboon Sapsinthaweelap
10 min readJun 20, 2022

An image classification model about Toyota cars.

Table of content

Prologue

จุดเริ่มต้นของโปรเจกต์นี้เกิดจาก ตัวผมที่เวลาจะเดินทางไปไหนผมก็มักจะเป็นคนนั่งข้างคนขับ โดยคุณพ่อของผมเป็นคนขับ ผมที่ขี้สงสัยเลยมักจะถามคุณพ่อเรื่องที่เกี่ยวกับรถต่างๆ เช่น รถคันนี้รุ่นอะไร หรือเรื่องเกี่ยวกับการทำงานของระบบต่างๆ ภายในรถ ส่วนมากผมจะถามเกี่ยวกับรถยี่ห้อ Toyota เพราะว่าคุณพ่อของผมเคยทำงานเป็นวิศวกรอยู่ที่บริษัท Toyota และคำถามที่ถามส่วนใหญ่จะเป็นครถรุ่นคันนี้รุ่นอะไร ซึ่งพ่อของผมบางทีก็ตอบได้บ้าง ตอบไม่ได้บ้าง เพราะรถบางรุ่นก็เป็นรุ่นใหม่ที่ออกมาหลังจากที่พ่อผมออกจากบริษัทมาแล้ว ผมเลยคิดว่า “ถ้าเรามีระบบที่เราสามารถโยนรูปไป แล้วระบบตอบกลับมาเป็นชื่อรุ่นเลยก็คงจะดี” แล้วเมื่อผมได้เข้าโครงการ AI builders ผมก็เลยตัดสินใจที่จะทำโปรเจกต์นี้ขึ้นมา โดยความตั้งใจจริงๆ คือต้องการที่จะทำระบบที่สามารถแยกรุ่นของรถได้ โดยไม่จำกัดรุ่น ไม่จำกัดยี่ห้อ
แต่ด้วยโปรเจกต์นี้เป็นการทำ AI ครั้งแรกของผม อีกทั้งผมก็ยังเขียน code ไม่ได้เก่งมาก จึงเลือกเฉพาะรถยี่ห้อ Toyota โดยเน้นรถรุ่นที่นิยมในไทยเป็นหลัก

The beginning

ผมได้ลองหา dataset มาอันนึง ซึ่งเป็น dataset ที่เกี่ยวกับ รถรุ่นต่างๆ ของ Toyata ประมาณ 38 รุ่น จาก Kaggle ที่ถูกสร้างขึ้นโดย Occulta Insights

โดยทั้ง 38 รุ่น มีชื่อดังนี้

4runner, alphard, avalon, avanza, avensis, aygo, camry, celica, corolla, corona, crown, estima, estios, fortuner, hiace, highlander, hilux, innova, iq, matrix, mirai, previa, prius, rav4, revo, rush, sequoia, sienna, soarer, starlet, supra, tacoma, tundra, venza, verso, vios, vitz และ yaris

และนี้คือจำนวนรูปภาพที่ได้ออกมาของรถแต่ละรุ่นครับ

จำนวนรูปภาพของรถรุ่นต่างๆ ใน dataset โดยเรียงจากจำนวนของรูปภาพน้อยไปมาก

จะเห็นได้ว่าข้อมูลมีทั้งหมด 38 รุ่น และจำนวนรูปภาพทั้งหมดประมาณ 16,000 รูปภาพ แต่เนื่องจาก dateset นี้ เป็น dataset ที่ทำขึ้นโดยชาวต่างชาติ ทำให้รถรุ่นที่นิยมในไทยอย่างรุ่น vios มีรูปอยู่เพียง 141 รูป ซึ่งเทียบกับรุ่น camry ที่มีจำนวนรูปถึง 2,246 รูป จึงคาดการณ์ว่าน่าจะมีปัญหาในอนาคตได้ ยังดีที่ dataset นี้ ถูกแยกออกเป็นรุ่นหรือตระกูลใหญ่ๆ เท่านั้น ไม่มีการแยกย้อย เช่น yaris ativ หรือ corolla altis ซึ่งยังตรงกับจุดประสงค์ของโปรเจกต์นี้อยู่

เมื่อดูภาพรวมของ dataset แล้ว ก็ถึงเวลาที่เราจะต้องเจาะลึกเข้าไปดูรูปภาพต่างๆ ใน dataset

ตัวอย่างรูปภาพใน folder 4runner จะเห็นว่ามีรูปของรถรุ่น vios และรูปภายในรถปะปนอยู่ด้วย

พบว่า ใน folder บางทีก็อาจจะไม่ใช่รูปที่เราต้องการเสมอไป เช่น folder ของรถรุ่นนึงบางทีก็มีรถอีกรุ่นนึงปะปนอยู่ด้วย และใน folder นึงก็ไม่ได้มีรูปของภายนอกรถอย่างเดียว แต่มีรูปส่วนอื่นๆ ของตัวรถด้วย เช่น ภายในรถ, ล้อ, เครื่องยนต์ ฯลฯ ซึ่งเราไม่ต้องการ แต่ละรูปใน folder ก็มีความละเอียดของภาพที่ไม่เท่ากัน ก่อนที่เราจะไปต่อเราต้องแก้ไขปัญหาพวกนี้ก่อน

The cleanning

ในการจัดการกับข้อมูล ปัญหานี้เป็นปัญหาที่พบได้บ่อย โดยผมจะทำการ clean dataset หรือทำความสะอาดข้อมูล ให้เหลือแต่รูปภาพที่เราต้องการ

การแบ่งรูปที่ไม่ได้ใช้ออกเป็น 4 หมวดหมู่

ผมจะเอารูปที่ไม่ใช้ออกมาใส่ folder (data_not_used) ในนั้นแบ่งออกเป็น 38 folder ตาม class(หมวดหมู่ย่อยหรือในที่นี้คือ รุ่นของรถนั้นเอง) ในแต่ละ folder แบ่งรูปที่ไม่ได้ใช้เป็น 4 หมวด คือ

  • รูปของภายในรถ(interior)
  • รูปของเครื่องยนต์หรือกลไกของรถ(mechanism)
  • รูปที่เจาะจงบางส่วนมากเกินไป(too_specific)
  • รูปของรถคนละรุ่น(wrong_model)

โดยที่แยกออกเป็น 4 หมวด เผื่อว่าในอนาคตอาจจะสามารถนำมาใช้เพิ่มฟีเจอร์ได้ เช่น การแยกรุ่นรถจากภายใน หรือจากส่วนต่างๆ ของรถ

รูปภาพที่ไม่ได้ใช้มีประมาณ 2,203 รูป หรือประมาณ 13.5% ของจำนวนรูปภาพทั้งหมด

อัปโหลด dataset ขึ้น Google Drive

จากนั้นผมก็อัปโหลด dataset ขึ้น Google Drive เพื่อที่จะสามารถนำข้อมูลไปจัดการต่อผ่าน Google Colab

ในระหว่างที่ผมกำลัง clean ในส่วนที่ผ่านมาผมก็พบว่านอกจากจะมีรูปที่ไม่ต้องการแล้ว ในกลุ่มที่เราต้องการก็มี รูปที่ซ้ำปะปนอยู่ด้วยเช่นกัน ผมจึงลองค้นหาระบบที่จะช่วยหารูปภาพซ้ำดู ก็เจออยู่ระบบนึง สร้างโดยคุณ Urvi Soni

และนี้คือตัวอย่างของการนำ dataset ของเราเข้าระบบนี้

นี้คือตัวอย่างของระบบการหารูปซ้ำ

ผลออกมาค่อนข้างดี มีรูปที่ถูกนำออก 563 รูป แต่ในจำนวนนั้น ก็มีรูปที่ผมลบเองด้วย เพราะว่าตัวระบบ สามารถลบได้แค่รูปที่เหมือนกัน 100% แต่ก็มีบางรูปใน ที่เกิดจากการ crop รูปภาพเดิม ทำให้ระบบไม่สามารถตรวจจับได้

ในส่วนของรูปภาพที่มีความละเอียดไม่เท่ากัน ผมก็พบว่ายังไม่จำเป็นจะต้องทำอะไร เพราะว่าสุดท้ายแล้วเราก็ต้องทำการ resize รูปภาพอยู่ดี เพื่อนำไป train

จำนวนข้อมูลของรูปภาพแต่ละ class รูปภาพก่อน clean (สีเขียว), รูปภาพหลัง clean (สีฟ้า)

Training | Episode 1

การ train ครั้งแรกผมตัดสินใจที่จะทำการ แบ่ง Train/Valid/Test เอง (ที่เลือกแบบนี้เพราะว่าผมไม่รู้ว่ามันสามารถแบ่งโดยใช้ระบบได้ เพราะฉะนั้นใช้ระบบแบ่งให้เถอะ ง่ายกว่าครับ) โดยแบ่งเป็นอัตราส่วน 70:15:15 ตามลำดับ

  • Train set คือชุดข้อมูลที่เอาไว้สอน model ของเรา
  • Valid set คือชุดข้อมูลที่เปรียบเหมือนข้อสอบเก็บคะแนน เอาไว้วัดประสิทธิภาพจากการเรียน
  • Test set เปรียบเหมือนกับข้อสอบปลายภาคที่เอาไว้ให้ model เราดูตอนสุดท้าย เพื่อจะเอาความแม่นยำไปเก็บเป็นข้อมูลต่อไป
จำนวนข้อมูลในการแบ่ง train, valid, test
Test set (สีเขียว) 70% | Validation set (สีฟ้า) 15% | Test set (สีเหลือง) 15%
Validation set
Test set

พอแบ่งเสร็จแล้ว เราก็สามารถทำการ train model ได้แล้ว โดย code ที่ใช้จะเป็น code จาก curriculum ของโครงการ AI builders แล้วนำมาดัดแปลงต่อ

ในส่วนของการ train ผมจะใช้ resnet34 แล้วทำการ freeze_epochs = 1 เพื่อให้ใน epoch แรกเป็นการ freeze layer ในส่วนของ low-level features ก่อนแล้วอีก 5 epochs ที่เหลือก็จะเป็นการปล่อยให้ model เรียนต่อ รวมเป็น 6 epochs ต่อมาในส่วนของ learning rate หาจากฟังก์ชัน lr_find เพื่อให้ได้ผลลัพธ์ดีที่สุด

จำนวนรูปภาพในการ train ครั้งที่ 1 รวม 13,505 รูป
เชื่อม Google Colab กับ Google Drive
import fastbook เพื่อที่จะใช้ Fastai
ต่อมาก็สร้าง DataBlock เป็นเหมือนการบอกระบบว่า dataset ของเราหน้าตาเป็นอย่างไร จะต้องดูชื่อรุ่นรถตรงไหน? รวมถึงการทำ augmentation และการ crop ต่างๆ
หลังจานำข้อมูลเข้าแล้ว เราก็นำข้อมูลมาดูว่านำเข้าถูกหรือไม่ ครบหรือเปล่า
จากนั้นก็ทำการกำหนด learner เป็น resnet34 metric เป็น error_rate และ accuracy และหา learning rate เพื่อให้ผลที่ออกมาดีที่สุด
ผลที่ได้จากการ train model ไป 6 epochs
ผลการทำนายของ model
confusion matrix

โดย confusion matrix จะเป็นตารางในการบอกว่า ความแม่นยำในแต่ละ class มีค่าเท่าไร ซึ่งถ้า model ที่ทายถูกเยอะ เราก็จะเห็นเส้นเแนวเฉียงสีน้ำเงิน ผลออกมา accuracy 82%(บน valid set) และ balanced accuracy อยู่ที่ 57% แต่ไม่ได้แม่นตรงตามจุดประสงค์ จุดประสงค์ของผมคือการที่ให้ model สามารถทายถูกได้ในทุกๆ class แต่ผลที่ออกมาครั้งนี้คือการที่โมเดลทาย class ที่มีจำนวนข้อมูลมากถูก เช่น class camry, corolla ที่มีรูปประมาณ 2,000 รูป ทำให้ค่า accuracy สูง ทำให้ class ที่มีข้อมูลน้อย เช่น rush ที่มีประมาณ 20 รูป ก็จะมี accuracy ต่ำ หรือเรียกได้ว่า model ที่เรา train มานั้นใช้ไม่ได้นั้นเอง

ผมจึงเริ่มดูจาก class ที่มีผลออกมาแย่ที่สุด นั้นก็คือ estima, revo และ rush

มีพี่ที่อยู่ในโครงการ AI builders แนะนำ loss function ตัวนึงมาที่มีชื่อว่า Triplet loss function ซึงเป็นการสอน model ให้เอารูป 2 รูปจาก class เดียวกัน มาเปรียบเทียบกับรูปที่อยู่คนละ class แต่ที่นี้ปัญหาที่ผมพบก็คือตัวผมเองหาวิธีที่จะนำ loss function นี้มาใช้กับ ตัว FastAI ที่ผมใช้อยู่ได้ (อาจจะเป็นเพราะผมยังเป็นมือใหม่อยู่เลยหาวิธีไม่เจอ) บวกกับมีเพื่อนที่เข้าร่วมโครงการด้วยกันเสนอว่า ให้หารูปใหม่เลย ผมเลยไม่ได้ใช้ loss function ตัวนี้ และตัดสินใจที่จะตัด data บางส่วนออก และหาใหม่เลย

แก้ปัญหา 1.1

Toyota Revo — ผมเลยตัดสินใจที่จะยุบ class revo รวมกับ class hilux ไปเลย เพราะว่าจากที่ผมหาข้อมูลมา รุ่น revo แล้วจริงๆ มีชื่อว่า hilux revo แปลว่ามันเป็นรุ่นที่ย่อยออกมาจาก รุ่น hilux

แก้ปัญหา 1.2

จำนวนข้อมูลใน dataset

หลังจากที่ผมกลับมาดูจำนวนรูปใน dataset ก็พบว่า datset นี้ ไม่สมดุล ผมจึงตัดสินใจที่ตัดรูปสำหรับ class ที่มีรูปน้อยกว่า ~200 รูปออก และหาใหม่ class ละ 400 รูป

วิธีหาข้อมูลที่ใช้คือการ scrape มาจากการ search Google เพียงแต่ผมไม่ได้ใช้ Google แต่ใช้ search engine ทีเรียกว่า duckduckgo เพราะว่า duckduckgo สามารถ scrape ข้อมูลได้มากกว่าการ scrape จาก Google ส่วน code ที่ใช้ก็นำมาจากพี่ๆ AI builders (อีกแล้ว)

วิธีการ scrape จาก duckduckgo
กำหนด keyword ที่เราต้องการ และจำนวนรูป (ในที่นี้ต้องการ 500 รูปเพื่อที่จะนำมาตัดรุปที่ไม่ได้ใช้ออก)
ผลที่ได้ 25 folders (nu = not_use)

แก้ปัญหา 1.3

Toyota Previa — ในระหว่างที่หา data ใหม่ผมก็พบว่ารถรุ่น estima กับ previa เป็นรุ่นเดียวกัน แค่คนละชื่อเพราะเกิดจากการเรียกชื่อของฝั่งยุโรป และเอเชีย ผมจึงเลือกที่จะตัดรุ่น previa ออก เพราะว่า รุ่น estima เป็นชื่อที่นิยมกว่าในไทย

จำนวนรูปภาพ

และนี้คือจำนวนรูปภาพเก่าและใหม่(clean แล้ว) เปรียบเทียบกัน (อันที่เท่าเดิมคือใช้ data เก่า)

จำนวนรูปภาพเก่า(สีน้ำเงิน), จำนวนรูปภาพใหม่(สีส้ม)

Training | Episode 2 In-depth

การ train ครั้งเป็นการเอา data ที่หามาใหม่มา train โดยครั้งนี้ผมให้ระบบ แบ่ง train set และ valid set ออกเป็น 80:20 โดยอัตโนมัติ

จำนวนรูปภาพในการ train ครั้งที่ 2 รวม 21,195 รูป
resnet34 6 epochs lr = 0.00057
confusion matrix พร้อมกับการ highlight ส่วนที่มีปัญหา

ความแม่นยำในการ train ครั้งนี้อยู่ที่ 76%(บน valid set) และ balanced accuracy อยู่ที่ 76.7% จาก confusion matrix ด้านบน ความแม่นยำของรถแต่ละรุ่นเพิ่มขึ้นอย่างมาก แต่ก็ยังมีรุ่นที่มีปัญหาอยู่ ผมเลยทำการ highlight รุ่นที่มีปัญหา และนี้คือวิธีที่ผมจะใช้ในการแก้

แก้ปัญหา 2.1

Toyota Avalon — ตัวรถมีหน้าตาคล้ายกับตัวรถ Camry ทำให้เกิดปัญหา

ด้านซ้ายเป็นรุ่น Camry ด้านขวาเป็นรุ่น Avalon

แต่หลังจากการหาข้อมูลเพิ่มเติม ผมก็เจอข้อมูลที่บอกว่า Toyota Avalon เป็นรุ่นที่ขายเฉพาะสหรัฐอเมริกา และโซนยุโรปบางประเทศเท่านั้น ผมเลยตัดสินใจว่าจะตัดรถรุ่น Avalon ออกเพราะ ไม่ตรงกับจุดประสงค์ของผม

แก้ปัญหา 2.2

Toyota Avanza — ตัวรถด้านหน้ามีความแตกต่างที่ชัดเจน แต่ด้านหลังมีความเหมือนกันในระดับนึง

ด้านซ้ายเป็นรูปด้านหลังของรถรุ่น Avanza และด้านขวาเป็นด้านหลังของรถรุ่น Innova

วิธีแก้ของผมก็คือ การเพิ่มรูปด้านหลังของรถรุ่น Avanza เข้าไป 79 รูป แล้วรอดูผลในการ train คร้งต่อไป

แก้ปัญหา 2.3

Toyota Celica, Corona, Crown — ตัวรถรุ่น Celica, Corona และ Crown มีหลาย generation แต่ที่เป็นปัญหาคือ generation เก่าๆ ของทั้ง 3 รุ่น

Toyota Celica 2nd generation (1977–1981)
Toyota Corona 7th generation (1982)
Toyota Crown 8th generation (1987)

ด้วยความที่ว่า รุ่น Celica และ Crown ใน generation ใหม่ๆ มีหน้าตาที่ต่างกันอย่างเห็นได้ชัด ผมเลยตัดสินใจที่จะ เลือกรูปเฉพาะรุ่น Celica เฉพาะ 6th — 7th generation และรุ่น Crown เฉพาะ 12th — 15th generation เท่านั้น เพราะเป็นรุ่นที่ใหม่ มีความแตกต่างกันอย่างเห็นได้ชัด และเป็นรุ่นที่มีโอกาสที่จะเจอตามท้องถนน

Toyota Celica 6th generation (1993–1999)
Toyota Celica 7th generation (1999–2006)
Toyota Crown 12th generation (2003)
Toyota Crown 13th generation (2008)
Toyota Crown 14th generation (2012)
Toyota Crown 15th generation (2018)

แก้ปัญหา 2.4

Toyota Fortuner — ผมคาดการณ์ว่าปัญหาที่พบคือ รูปภาพน้อย และรูปภาพเห็นตัวรถไม่ชัดเจน

ตัวอย่างรูปภาพรถรุ่น fortuner ภาพส่วนใหญ่จะเน้นฉากด้านหลัง จึงทำให้ตรวจจับตัวรถยาก

ผมเลยหารูปภาพรถรุ่น fortuner ใหม่มาประมาณ 500 รูป แล้วรอดูผลจากการ train ครั้งต่อไป

แก้ปัญหา 2.5

Toyota Hilux — คาดว่าที่ผลออกมาไม่ดีเกิดจากการที่รูปภาพน้อย เทียบกับอีกสองรุ่น คือ tacoma กับ highlander

กราฟเปรียบเทียบจำนวนรูปภาพของรถ 3 รุ่น

ผมเลยไปหารูปของรถรุ่น hilux เพิ่มอีกประมาณ 800 รูป เพื่อที่จะได้มีจำนวนรูปพอๆ กับ อีกสองรุ่น รอดูผลในการ train ครั้งต่อไป

แก้ปัญหา 2.5

Toyota Vitz — จากการหาข้อมูลเพิ่มเติมพบว่า มันคือรถรุ่น Yaris ที่ถูกดัดแปลงเล็กๆ น้อยๆ แล้วเปลี่ยนชื่อ เพื่อนำไปขายที่ประเทศญี่ปุ่นเท่านั้น ซึ่งไม่ตรงตามจุดประสงค์ของผม จึงทำการตัดรุ่นนี้ออก

Toyota Vitz
Toyota Yaris

Toyota Yaris — คาดว่าเกิดจากรถรุ่น Vitz ก่อนหน้านี้ ที่หน้าตาเหมือนกัน จึงทำให้ผลออกมาไม่ดี จากการตัดรถรุ่น Vitz ออกก่อนหน้านี้ น่าจะทำให้ผลของรุ่น Yaris ดีขึ้น รอดูในการ train ครั้งต่อไป

Training | Episode 3 Performance

การ train ครั้งนี้เป็นการ เอาการแก้ปัญหาก่อนหน้านี้มาปรับใช้ และ train ต่อ เพื่อดูผลลัพธ์ต่อไป

เพิ่มรุ่น

Toyota Wish — เป็นรถรุ่นที่เพิ่มเข้าไปในครั้งนี้ เหตุผลที่เพิ่มเข้าไปคือ เป็นรถที่ยังไม่มี และเป็นรถที่มีความนิยมในไทยค่อนข้างสูง

Toyota Wish
จำนวนรูปภาพที่ใช้ในการ train ครั้งที่ 3 รวม 21,615
resnet34 6 epochs lr = 0.0012
confusion matrix แสดงความแม่นยำของแต่ละ class หลังจากการปรับแต่งข้อมูล

การ train ครั้วนี้ accuracy จะอยู่ที่ 87%(บน valid set) balanced accuracy อยู่ที่ 75.4% และจาก confusion matrix พบว่ารถรุ่นที่มีความแม่นยำค่อนข้างต่ำ มีความแม่นยำที่ดีขึ้นอย่างเห็นได้ชัด ยกเว้นแต่รถรุ่น Yaris ที่ความแม่นยำยังถือว่าต่ำอยู่

Training | Episode 4 Final

เป็นการนำปัญหาของการ train ครั้งที่ 3 มาแก้ไข แล้วก็มีการเพิ่มรุ่นใหม่

แก้ปํญหา 4.1

Toyota Vios — ตัด 3rd generation เพราะมีการใช้โครงเดียวกับ Yaris ativ มีการเปลี่ยนเฉพาะภายใน และเครื่องยนต์เท่านั้น

Toyota Vios 3rd generation
Toyota Yaris Ativ

เหลือเพียง vios 1st & 2nd generation เพราะมีหน้าตาต่างจาก Yaris พอสมควร

Toyota Vios 1st generation
Toyota Vios 2nd generation

แก้ปัญหา 4.2

Toyota Verso — ตัดออก เพราะเป็นรถที่ไม่มีขายในไทย และมีความนิยมน้อยในไทย

เพิ่มรุ่น

Toyota C-HR — เพิ่มรถรุ่น c-hr เข้าไป เพราะเป็นรถที่มีขายในไทยและมีความนิยมสูง

Toyota C-HR

เพิ่มรุ่น

Toyota Sienta — เพิ่มรถรุ่น sienta เข้าไป เพราะเป็นรถที่มีขายในไทย และมีความนิยมค่อนข้างสูง

Toyota Sienta

จากนั้นก้นำมา train ต่อเลย ผลออกมาตามนี้ครับ

จำนวนข้อมูลที่ใช้ในการ train ครั้งที่ 4 รวม 21,878 รูป
resnet34 6 epochs lr = 0.0012
confusion matrix

การ train ในครั้งนี้ผลลัพธ์ที่ได้ถือว่าเป็นที่น่าพึงพอใจ โดยความแม่นยำอยู่ที่ 87%(บน valid set) และ balanced accuracy อยู่ที่ 89% ส่วนความแม่นยำเฉลี่ยของแต่ละ class จะอยู่ที่ 70–80% ซึ่งผมมองว่า เป็นผลลัพธ์ที่มีความแม่นยำที่เพียงพอที่จะนำ model ไป deploy ได้แล้ว

Evaluation

เนื่องจากในระหว่างที่พัฒนามีการเพิ่มและลด class ผมเลยเลือก class ที่มีมาตั้งแต่ใน kaggle ตอนแรก และไม่ได้ถูกนำออกมาเพื่อทำการวัดผล 33 class ได้แก่

4runner, alphard, avanza, avensis, aygo, camry, celica, corolla, corona, crown, estima, estios, fortuner, hiace, highlander, hilux, innova, iq, matrix, mirai, prius, rav4, rush, sequoia, sienna, soarer, starlet, supra, tacoma, tundra, venza, vios และ yaris

ผมได้ทำการ train model ใหม่ 2 ตัว ตัวนึงเป็น model ที่ใช้ old dataset จาก kaggle ทั้งหมด และอีกตัวคือ model ที่ใช้ข้อมูลจาก kaggle ส่วนนึงรวมกับ ที่ผมไปหาเพิ่มด้วยการ scrape จาก duckduckgo (ผมขอเรียกว่า new dataset) จากนั้นผมก็จะนำทั้ง 2 model มาทำนาย test set ที่มี 33 class เหมือนกัน จำนวน class ละ 100 รูป รวมแล้ว 3,300 รูป ผลที่ได้ออกมาดีงนี้

กราฟเปรียบเทียบ old dataset(สีฟ้า) รวม 12,829 รูป และ new dataset(สีส้ม) รวม 20,636 รูป
ผลการทำนายของ model ที่ใช้ old dataset บน test set
confusion matrix ของ model ที่ใช้ old dataset บน test set
ผลการทำนายของ model ที่ใช้ new dataset บน test set
confusion matrix ของ model ที่ใช้ new dataset บน test set

จากผลการทำนายของทั้ง 2 model ออกมา มีความแม่นยำเพิ่มขึ้นจาก 32.7% มาเป็น 74.3% (บน test set) ซึ่งตัวผมเองมองว่าเป็นการพัฒนาที่ดี แต่ที่น่าเป็นห่วงก็คือ ในส่วนของ class vios ที่มีผลออกมาไม่ดีทั้งคู่เลย แต่เนื่องจากข้อจำกัดด้านเวลา ผมจึงจำเป็นที่จะต้อง นำ model ไป deploy ก่อน

Deployment

ในการ deploy model ตัวนี้ ผมจะใช้ model ที่รับรอง 36 class ดังนี้

4runner, alphard, avanza, avensis, aygo, camry, celica, c-hr, corolla, corona, crown, estima, estios, fortuner, hiace, highlander, hilux, innova, iq, matrix, mirai, prius, rav4, rush, sequoia, sienna, sienta, soarer, starlet, supra, tacoma, tundra, venza, vios, wish และ yaris

โดยผมจะทำการ deploy โดยใช้ streamlit และ streamlit cloud เพราะว่าเป็น platform ที่ฟรี และมี widgets ต่างๆ ให้เลือกใช้ โดยระบบของผมจะเป็นการให้ผู้ใช้ใส่รูป หรือเลือกรูปจาก sample images ใน side bar ก้านข้าง จากนั้นก็ไห้ model ของผมทำนายรูปออกมา แล้วบอกผู้ใช้ ว่าทายออกมาเป็นรุ่นอะไร และมีโอกาสกี่เปอร์เซ็นต์ที่จะถูก (ในส่วนของ source code สามารถดูได้ใน Github Is-that-a-Supra)

App ที่ deploy ผ่าน streamlit

ในส่วนของ sample images ตอนนี้จะมีเพียง 36 รูป class ละ 1 รูป รวมกันแล้ว 36 รูปเพื่อให้ผู้ใช้สามารถทดลองระบบได้ โดยที่ไม่ต้องไปหารูปเพิ่มเติม

train โดยใช้ resnet34 และ FastAI

โดยมีรุ่นที่ยังมีปัญหาอยู่คือ vios

ตัว model ถูก deploy ผ่าน streamlit cloud

รูปส่วนใหญ่ที่เลือกควรจะเป็นรูปที่เห็นตัวรถชัดเจน (45 องศาน่าจะเป็นมุมที่เหมาะที่สุดจากการทดลองของผม) และควรจะเป็นรูปแนวนอน

Streamlit App

รายชื่อรุ่นที่ถูกตัดออก หรือมีเงื่อนไขพิเศษ

Toyota Revo ยุบรวมกับรุ่น hilux

Toyota Previa ซ้ำกับรุ่น estima

Toyota Avalon ไม่ตรงตามจุดประสงค์

Toyota Celica รองรับเฉพาะ 6th — 7th generation

Toyota Crown รองรับเฉพาะ 12th — 15th generationq

Toyota Vitz ไม่ตรงตามจุดประสงค์

Toyota Verso ไม่ตรงตามจุดประสงค์

Conclusion

ผมได้ทำการนำ dataset จาก kaggle จากนั้นก็ทำการ clean แต่ผลยังออกมาไม่ดีพอ จึงทำการ หาข้อมูลมาทำ new dataset จากนั้น ก็ train แล้ว evaluate และ deploy ลง streamlit cloud

จากการทำโปรเจกต์นี้ ผมได้เรียนรู้ว่า จำนวนข้อมูลเป็นสิ่งสำคัญในการทำ model AI ​แต่ส่วนอื่นก็สำคัญเช่นกัน ทั้ง module ที่เราจะใช้เขียน และ loss function ต่างๆ และผมที่เรียนด้าน data อยู่ก็ได้เรียนรู้มุมมองของคนที่ทำงานด้าน AI ว่าคนที่ทำ AI ต้องการข้อมูลแบบไหน เพื่อที่ในอนาคตผมจะได้สามารถเข้าใจความต้องการของข้อมูลต่างๆ ได้

Future work

  • การใช้ loss function อื่นๆ

ยังมี loss function อื่นอีกมากมาย triplet loss ก็เป็นหนึ่งในนั้นที่ผมไม่ได้ใช้ และถ้ามีโอกาสในการพัฒนาต่อผมก็อยากจะลองเอามาใช้จริงๆ ซักที

  • การเพิ่มรุ่น หรือยี่ห้อใหม่เข้าไปเพิ่ม

ที่ผมเลือก Toyota และรุ่นที่นิยมในไทยก็เพราะว่าผมอยากเริ่มจากการเริ่มทำอะไรเล็กๆ ก่อน เพื่อไม่ให้มันเกินตัวเกินไป แต่จริงๆ แล้วยังมีรถอีกหลายรุ่น และหลายยี่ห้อที่ผมอยากจะเพิ่มเข้าไปอีก

  • การเพิ่มความแม่นยำ

อันนี้แน่นอนอยู่แล้ว ยิ่งความแม่นยำดี ถูกเยอะ ก็เป็นสิ่งที่ดี คาดว่าถ้าเกิดได้ลองใช้ module อื่นๆ ได้เพิ่ม loss function ใหม่ๆ ก็จะช่วยได้

  • การใช้ module อื่น

ครั้งนี้ผมได้ใช้แค่ FastAI ในการเขียน แต่จริงๆ แล้วมี module อื่นให้ใช้อีกมากมายที่มาพร้อมกับ ความอิสระในการกำหนดการตั้งค่าต่างๆ เช่น PyTorch, Tenserflow ฯลฯ ซึ่งก็มีโอกาสที่จะทำให้ผลที่ออกมาดีขึ้นเช่นกัน

  • การเปลี่ยนจาก classification เป็น object detection

การเปลี่ยนจาก classification เป็น object detection จะช่วยทำให้ เราสามารถ แยกรถได้หลายๆ คัน พร้อมๆ กัน และยังสามารถที่จะตีกรอบให้ผู้ใช้ดูได้ด้วยว่ามีรถอยู่ตรงไหนในภาพบ้าง ตัวผมเองก็ได้พยายามลองที่จะทำแล้ว แต่ด้วยความที่ไม่มี dataset ตามที่ผมต้องการ และตอนที่ผมทำ dataset ใหม่ ก็ไม่ได้คิดถึงข้อนี้ เลยทำให้ทำไม่ทัน

Link

Github : https://github.com/BikiniGordon/Is-that-a-Supra

App : https://share.streamlit.io/bikinigordon/is-that-a-supra/main/deploy/app_V1.py

Special thanks

ขอบคุณพี่ๆ และ เพื่อนๆ ทุกคนในโครงการนี้ด้วยครับ ไม่งั้นโปรเจกต์นี้คงไม่เกิดขึ้น

มาจนถึงจุดนี้แล้ว ผมเป็นใคร?

ผมนายจิตรบุณย์ ทรัพย์สินทวีลาภ (กั๊ต) อายุ 16 คณะนี้ศึกษาอยู่ที่ โรงเรียน มศว ประสานมิตร (ฝ่ายมัธยม) เอก DE (Digital Engineering) เป็นคนที่ชอบเทคโนโลยี ชอบคอมพิวเตอร์ ชอบรถยนต์ แต่ยังเป็นมือใหม่ด้านการเขียนโปรแกรม และจะพยายามที่จะพัฒนาตัวเองต่อไป

--

--