เริ่มกันเลย!
ในบทสอนนี้ พี่จะพาน้องไปทำระบบจดจำท่าทาง (Gesture Recognition) แบบง่ายๆ ด้วย AI บนบอร์ด Wio Terminal โดยใช้ AIfES® ครับ สิ่งที่เจ๋งมากๆ คือเราทำทุกอย่างบนบอร์ดเลย ไม่ต้องพึ่งพีซี! เราสามารถสอน AI ให้รู้จักท่าทางได้ 3 แบบเลยนะ ตัว AI ที่เราใช้คือ Artificial Neural Network (ANN) ซึ่งเราสามารถเทรนมันได้บนบอร์ดเลยด้วย Optimizer ชื่อ Adam จาก AIfES®
สำหรับเซ็นเซอร์ที่ใช้ เราก็ใช้ตัวที่ติดมากับบอร์ดอยู่แล้วนั่นคือ 3-axis digital accelerometer (LIS3DHTR) ไม่ต้องต่ออะไรเพิ่มให้วุ่นวายเลย ง่ายมั้ยล่ะ!
โปรเจกต์จดจำท่าทางแบบนี้ก็มีให้เล่นกับบอร์ด Arduino อื่นๆ ด้วยนะ น้องสามารถไปดูตัวอย่างได้ในไลบรารี AIfES® for Arduino เลย
ตัวอย่างนี้มีให้สำหรับบอร์ดพวกนี้:
- Arduino Nano 33 IoT
- Arduino Nano BLE Sense
- Arduino Nano RP2040 Connect
แน่นอน บอร์ดอื่นๆ ที่มี accelerometer ติดมาหรือต่อเพิ่มเองก็ใช้ได้เหมือนกัน แค่ปรับโค้ดตัวอย่างนิดหน่อยก็ลุยได้แล้ว
อยากรู้จัก AIfES® ให้มากขึ้น ก็ไปหาข้อมูลเพิ่มเติมได้นะ
อุปกรณ์และซอฟต์แวร์ที่ต้องเตรียม
- Arduino IDE (ตัวนี้ต้องมีแน่นอน)
- ติดตั้งไลบรารี AIfES® ผ่าน Arduino Library Manager (ค้นหาคำว่า aifes)
- ติดตั้งบอร์ด Wio Terminal ตามคู่มือ
- ติดตั้งไลบรารีสำหรับ accelerometer "Grove - 3-Axis Digital Accelerometer ±2g to 16g (LIS3DHTR)" ผ่าน Library Manager (ค้นหาคำว่า LIS3DHTR)
ไอเดียของบทสอนนี้
บทสอนนี้ได้แรงบันดาลใจมาจากผลงานของ Eloquent Arduino ครับ หลังจากที่ได้คุยกัน พี่ก็เอาแนวทางการบันทึกข้อมูล/ฟีเจอร์มาจากโปรเจกต์ของเขาเลย เขาใช้ Support Vector Machines (SVM) ในการจำแนกท่าทางและเทรนบนพีซี ส่วนเราใช้ ANN ซึ่งเราสามารถเทรนบนบอร์ดได้เลยด้วย AIfES®
น้องสามารถไปดูโปรเจกต์เต็มๆ ของเขาได้ ซึ่งอธิบายพื้นฐานไว้ได้ดีมากเลย ส่วนโค้ดก็มีให้ดูเช่นกัน
ท่าทางอะไรบ้างที่เราสามารถฝึกได้?
จัดไปวัยรุ่น! ท่าทางที่เราสามารถเอามาฝึกให้โมเดลเราจำได้ก็มีหลายแบบเลย เช่น:
- ท่า Flex (อวดกล้าม)
- ท่า Twist (บิดตัว)
- ท่า Punch (ชก)
- ท่าเคลื่อนไปด้านใดด้านหนึ่ง
- ... และอื่นๆ ตามแต่จะสรรหามา
แต่เดี๋ยวก่อน! ต้องขยับให้แรงหน่อยนะตัวนี้ ไม่งั้นมันจะไม่เริ่มบันทึกข้อมูลให้หรอก เพราะเราตั้งค่าให้ต้องมีค่าความเร่งขั้นต่ำถึงจะเริ่มเก็บข้อมูลได้
ข้อมูล / ฟีเจอร์ (Data / Features)
ถ้าน้องขยับน้อยไปหรือไม่ขยับเลย ระบบก็จะไม่บันทึกข้อมูลใดๆ ทั้งสิ้น ต้องมีค่าความเร่งเกินเกณฑ์ที่ตั้งไว้ ระบบถึงจะเริ่มจับค่ามาเก็บ
ชุดข้อมูล / ฟีเจอร์หนึ่งชุด จะประกอบด้วยค่าความเร่งจากทั้ง 3 แกน (X, Y, Z) ในตัวอย่างนี้ เราจะเก็บค่าความเร่งจากแกน X, Y, Z จำนวน 20 ค่า (ต่อเนื่องกัน) แล้วเก็บรวมกันเป็นหนึ่งชุดข้อมูล พร้อมกับป้ายกำกับ (Label) ดังนั้นทั้งหมดเราก็จะป้อนข้อมูลเข้าไปในโครงข่ายประสาทเทียม (Neural Network) ทั้งหมด 60 ค่า ส่วนป้ายกำกับนั้นจะถูกสร้างขึ้นอัตโนมัติระหว่างกระบวนการฝึก
ป้ายกำกับถูกสร้างแบบนี้:
- ท่าทางที่ 1: 1, 0, 0
- ท่าทางที่ 2: 0, 1, 0
- ท่าทางที่ 3: 0, 0, 1
ตัวอย่างชุดข้อมูลสำหรับท่าทางที่ 1 จะหน้าตาประมาณนี้:
X1, Y1, Z1, X2, Y2, Z2, ..., X20, Y20, Z20, 1, 0, 0
ต้องบอกไว้ก่อนว่าวิธีการเก็บข้อมูลแบบนี้ไม่ใช่การสกัดคุณลักษณะ (Feature Extraction) จริงๆ นะจ๊ะ เราแค่หลีกเลี่ยงการประมวลผลขั้นสูงเช่น FFT ฯลฯ เพื่อให้เห็นภาพรวมของหลักการทำงานได้ชัดเจนขึ้นเท่านั้น
โครงข่ายประสาทเทียม (The Artificial Neural Network)
โครงข่ายประสาทเทียม (ANN) ของเรามีทั้งหมด 3 ชั้น (Layer) โครงสร้างมีดังนี้:
- ชั้นอินพุต (Input layer): 60 อินพุต
- ชั้นซ่อน (Hidden layer): 4 นิวรอน (ใช้ฟังก์ชันกระตุ้น sigmoid)
- ชั้นเอาต์พุต (Output layer): 3 เอาต์พุต (ใช้ฟังก์ชันกระตุ้น softmax)
แล้วเราหาโครงสร้างนี้มาได้ยังไง? ในตัวอย่างนี้ เราพัฒนาโมเดลด้วย AIfES® บนบอร์ดโดยตรงเลย แต่จริงๆ แล้วน้องสามารถใช้ AIfES® บน PC หรือใช้เฟรมเวิร์ก Python อย่าง Keras, TensorFlow หรือ PyTorch ในการหาความเหมาะสมของโครงสร้างเครือข่ายก็ได้นะ ถ้าทำแบบนั้น น้องก็แค่ส่งข้อมูลฝึกผ่าน UART ไปที่ PC แล้วฝึกโมเดลบนนั้นได้เลย พอฝึกเสร็จด้วย Python แล้ว ก็ดึงค่า weight ออกมา แล้วนำไปใช้กับ AIfES® อีกที
สำหรับการนำไปใช้จริง เราใช้ AIfES-Express มาช่วย ซึ่งทำให้การเขียนโค้ดง่ายขึ้นมาก และสามารถปรับโครงสร้าง ANN ได้ด้วยการเปลี่ยนค่าไม่กี่จุด ถ้าน้องอยากเปลี่ยนจำนวนนิวรอน, ฟังก์ชันกระตุ้น หรือจำนวนชั้น ก็ทำได้ง่ายๆ แน่นอนว่าถ้าอยากเพิ่มจำนวนท่าทาง ก็ต้องเพิ่มจำนวนนิวรอนในชั้นซ่อนตามไปด้วย AIfES-Express ใช้ง่ายกว่า แต่เพราะมันสร้างโมเดลตอนรันไทม์ มันจึงทำงานช้ากว่าการใช้ AIfES® แบบปกติ ข้อดีของ AIfES-Express คือเราสามารถเปลี่ยนโครงสร้าง ANN ได้ระหว่างรันไทม์นั่นเอง
การฝึกโมเดล (Training)
การกำหนดค่าเริ่มต้นให้ weight (Initialization of the weights):
ก่อนอื่นเราต้องมีเมล็ดสุ่ม (random seed) สำหรับการกำหนดค่าเริ่มต้น ในที่นี้เราใช้สัญญาณรบกวนจากขาแอนะล็อก (analog pin) โดยตั้งค่าในฟังก์ชัน setup() ด้วยคำสั่ง srand(analogRead(A1)); ส่วนการกำหนดค่าเริ่มต้นจริงๆ เราใช้วิธี glorot_uniform ที่มีอยู่แล้วใน AIfES®
พารามิเตอร์สำหรับการฝึก:
- ตัวหาค่าเหมาะสุด (Optimizer): Adam
- ฟังก์ชันคำนวณความผิดพลาด (Loss): Crossentropy
- อัตราการเรียนรู้ (Learn rate): 0.1
- จำนวนรอบฝึกสูงสุด (Epochs): 1000 (จะหยุดก่อนได้ถ้าถึงค่าเป้าหมาย)
- หยุดฝึกเมื่อดีพอ (Early stopping): เปิดใช้งาน
- ค่าความผิดพลาดเป้าหมาย (Target loss): 0.09
- ขนาดชุดข้อมูลย่อย (Batch size): ใช้ข้อมูลทั้งหมด (Full batch)
- ช่วงแสดงผล (Print interval): 10
ใน AIfES-Express เราสามารถเปิดใช้งาน early stopping ได้ โดยเราจะกำหนดค่าความผิดพลาดเป้าหมายที่ต้องการไว้ AIfES® จะหยุดการฝึกทันทีที่ค่าความผิดพลาดต่ำกว่าหรือเท่ากับค่าเป้าหมายที่ตั้งไว้ ฟังก์ชันนี้ทำงานคู่กับช่วงแสดงผล (print interval) ในตัวอย่างเราตั้งช่วงแสดงผลไว้ที่ 10 หมายความว่าทุกๆ 10 รอบฝึก (epoch) ระบบจะคำนวณและตรวจสอบค่าความผิดพลาด แล้วแสดงผลผ่านฟังก์ชันพิมพ์ที่เรากำหนดไว้
สู้งานนะน้อง! ห้ามช็อตนะตัวนี้
กระบวนการทำงานเป็นยังไงบ้าง
กระบวนการทั้งหมดทำงานอัตโนมัติเต็มรูปแบบ ตามขั้นตอนคร่าวๆ ดังนี้:
การบันทึกข้อมูล/ฟีเจอร์สำหรับเทรน:
- หลังจากเริ่มต้นแล้ว น้องจะเข้าสู่โหมดบันทึกข้อมูลฝึกสอนโดยอัตโนมัติ
- คิดถึงท่าทางแรกที่อยากสอน แล้วทำซ้ำ 5 ครั้ง
- การบันทึกข้อมูลของแต่ละท่าทางจะเริ่มต้นอัตโนมัติเมื่อความเร่งถึงค่าที่ตั้งไว้
- พักสักครู่ระหว่างเปลี่ยนท่าทางนะตัวนี้ ให้เซ็นเซอร์ความเร่งกลับสู่สภาวะนิ่งก่อน
- ทำขั้นตอนเดิมซ้ำสำหรับอีก 2 ท่าทางที่เหลือที่น้องเลือก
- ในที่สุดก็จะได้ข้อมูลทั้งหมด 15 ชุดสำหรับใช้ฝึกสอน
- การติดป้ายชื่อ (label) ให้ข้อมูลจะเกิดขึ้นระหว่างการบันทึกเลย
การเทรนโมเดล:
- เมื่อบันทึกท่าทางสุดท้ายเสร็จ ระบบจะเริ่มเทรนอัตโนมัติหลังจากนับถอยหลัง 3 วินาที
- ทุกๆ 10 epochs ค่าความสูญเสีย (loss) จะถูกแสดงบนหน้าจอ
- เมื่อค่าความสูญเสียถึงเป้าหมายที่กำหนด การเทรนจะหยุดอัตโนมัติ
การจำแนกประเภท (Classification):
- หลังการเทรนเสร็จ โหมดจำแนกประเภทจะเริ่มทำงาน
- โปรแกรมจะอยู่ในสถานะนี้จนกว่าจะมีการรีสตาร์ทใหม่
Edge-AI Motion Classification
โปรเจคขั้นสูงนี้ implements pipeline ของ AI ทั้งหมดลงบน WIO Terminal โดยตรง ทำให้มันเรียนรู้และจดจำท่าทางมือได้โดยไม่ต้องพึ่งพีซีหรือคลาวด์เลย
- AIfES Neural Network Core: ใช้ไลบรารี AIfES (Artificial Intelligence for Embedded Systems) ตัว Arduino จะดึงข้อมูลความเร่ง 3 แกนจาก IMU ในตัวของ WIO แล้วป้อนเข้าไปใน neural network ขนาดจิ๋วที่โฮสต์อยู่บนตัวอุปกรณ์
- On-Device Training Logic: ผู้ใช้สามารถ "ฝึกสอน" อุปกรณ์ได้โดยทำท่าทางซ้ำหลายๆ ครั้ง; WIO Terminal จะอัปเดตน้ำหนัก (weights) ภายในแบบเรียลไทม์ และแสดงระดับ "ความมั่นใจ (Confidence Level)" ปัจจุบันบน LCD ในตัว
การปรับแต่งให้เร็วสุดๆ
- CMSIS-DSP Acceleration: ใช้คำสั่งคณิตศาสตร์ความเร็วสูงของโปรเซสเซอร์ SAMD51 เพื่อให้มั่นใจว่า AI inference ใช้เวลาไม่เกิน 10ms ต่อท่าทาง
AIfES® Logo
AIfES® ถูกจดทะเบียนเป็นเครื่องหมายคำ/เครื่องหมายภาพ ขนาดโลโก้คือ 166 x 166 พิกเซล และเป็นสี R5G6B5 16 บิตต่อพิกเซล
บั๊กที่รู้จักกันดี
อาจเกิดกรณีที่เซ็นเซอร์ความเร่งเริ่มต้นไม่ถูกต้อง
- ถอดสาย USB ของ Wio Terminal ออก แล้วเสียบใหม่
- แฟลชเฟิร์มแวร์ใหม่อีกรอบ