ลงมือทำ: สร้างและส่งมอบแอป Edge AI
โมดูล 8 — Capstone: แอป Edge AI ของเราเอง · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร
เติมห้าบรรทัดสันหลังของ s20_capstone.py คือ select, อ่านความเร่งดิบ, result, กรองความมั่นใจด้วย EMA และ fire_alert แล้วออกแบบ จูน และเดโม Guardian ของเราเอง พิสูจน์ด้วยหลักฐานว่าเหตุการณ์จริงทำให้เตือนครั้งเดียว ส่วนเคสหลอกไม่ทำให้เตือน และเล่าเหตุผลของค่าออกแบบที่เลือก
เป้าหมาย
หัวข้อที่มีชื่อว่า “เป้าหมาย”เมื่อจบบทเรียนนี้ คุณจะ:
- เติมห้าจุดใน practice/s20_capstone.py จน Guardian แสดงบริบท motion กับ verdict ที่กรองแล้ว และเตือน (เสียง แบนเนอร์ ตัวนับ) ครั้งเดียวเมื่อคลาสเป้าหมายต่อเนื่องครบ HITS_NEEDED ผล
- ออกแบบ Guardian ของคุณ (โมเดล action และค่า CONF_FLOOR, HITS_NEEDED, EMA_ALPHA) และบันทึกเหตุผลพร้อมหลักฐานที่วัดได้ คือจำนวนการเตือนจากเหตุการณ์จริงกับจากเคสหลอกอย่างละอย่างน้อยห้าครั้ง
- เดโมสองนาทีที่แสดงการเตือนจริง เคสหลอกที่ไม่เตือน และการแลกเปลี่ยนที่เลือก พร้อมเสนอทิศต่อยอดหนึ่งทิศ
ก่อนเริ่ม
หัวข้อที่มีชื่อว่า “ก่อนเริ่ม”ผ่านบทเรียน 8.1 มาแล้ว มีแบบร่าง Guardian ของคุณและค่าเริ่มต้นพร้อมเหตุผล เตรียมเคสหลอกไว้ล่วงหน้า เช่นเขย่าแวบเดียวหรือเสียงก้ำกึ่ง เพื่อพิสูจน์ว่าชั้นตัดสินใจทำงาน
- อุปกรณ์: บอร์ด TESAIoT Dev Kit ที่ลงเฟิร์มแวร์ MicroPython ของ BENTO แล้ว หรือ BENTO Emulator ใน BENTO IDE — ทำ capstone ครบบน Emulator ได้ด้วยโมเดล Motion กับปุ่ม Shake ถ้าจะเฝ้าเสียงหรือเรดาร์ต้องใช้บอร์ด
- เรียนมาก่อน: บทเรียน 8.1 — ออกแบบ capstone: Guardian สามเสาในไฟล์เดียว
ทั้งไฟล์อ่านเป็นประโยคเดียว: เลือกโมเดล → อ่านบริบทและ verdict → กรองให้นิ่ง → เจอครบเกณฑ์ค่อยสั่งการ → ออกก็เก็บกวาด ปุ่มออกแบบอยู่บนหัวไฟล์
(MODEL_KEYWORD, HITS_NEEDED = 3, EMA_ALPHA = 0.4, ACTION_NOTE = 72) ห้าจุดที่เติมคือ (1) edge_ai.select(model['index']) เมื่อกด Load ใน try
แล้วขึ้น RUNNING หลัง select สำเร็จเท่านั้น (2) ax, ay, az = sensors.bmi270.acceleration() ลืมแล้ว motion ค้าง 0.0 (3) r = edge_ai.result() ลืมแล้วการ์ดไม่ขยับ
(4) conf_s = conf_ema.update(r['conf']) ลืมแล้วสีสถานะกระพริบตามพีค และ (5) fire_alert(r['label'], conf_s) เมื่อ streak >= HITS_NEEDED and not fired
ลืมแล้วครบเกณฑ์แต่ Guardian เงียบ
เติมครบยังไม่ใช่ capstone ขั้นที่ห้าที่เฉลยไม่ได้ให้คือการออกแบบของคุณ: เลือกโมเดลและ action ตั้งค่าออกแบบ แล้ววัดผลจริง ทำเหตุการณ์จริงกับเคสหลอกอย่างละหลายครั้ง นับว่าเตือนกี่ครั้ง จากนั้นจูนและบันทึกว่าค่าเปลี่ยนผลอย่างไร เพื่อให้คำอธิบายการออกแบบยืนบนตัวเลข ไม่ใช่ความรู้สึก ส่งมอบด้วยเดโมสั้น ๆ ที่เห็นทั้งการเตือนจริงและการไม่เตือน ทิศต่อยอดมีสี่ทาง: เสียบโมเดลที่ฝึกเองจากโมดูล 5, เพิ่ม feature จาก FFT ของโมดูล 4, fusion กับเซนเซอร์ดิบหรือเรดาร์ของบทเรียน 6.5 และส่งเหตุการณ์ขึ้น MQTT แบบบทเรียน 6.6
ตัวอย่างสมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่างสมบูรณ์”s20_capstone_full.py คือ Guardian ฉบับขัดเรียบร้อย เลือกโมเดลสดจาก dropdown แสดง latency ล้างตัวกรองเมื่อเริ่มเฝ้ารอบใหม่ และนับจำนวนการเตือน
| ไฟล์ | ไฟล์นี้สอน |
|---|---|
| examples/s20_capstone_full.py | Capstone: Edge AI Guardian (ฉบับเต็ม) |
สไลด์ของบทเรียนนี้อ้างถึงไฟล์ที่อยู่ในบทเรียนอื่นหรือใน shared/ ด้วย:
- shared/training/eval_pc.py — Run the exported int8 .tflite on the PC and report accuracy + confusion.
ฝึกเติม
หัวข้อที่มีชื่อว่า “ฝึกเติม”คอมเมนต์ # เติม: อยู่ที่บรรทัด 127 (select), 152 (ความเร่งดิบ), 159 (result), 166 (conf_ema.update) และ 194 (fire_alert)
ถ้าขึ้น RUNNING แต่การ์ดไม่ขยับ ตรวจจุดที่ 127 และ 159 ถ้าสีสถานะกระพริบทุกเฟรม ตรวจจุดที่ 166
| ไฟล์ฝึก | เรื่อง |
|---|---|
| practice/s20_capstone.py | Capstone: Edge AI Guardian (ฉบับฝึกเติมโค้ด) |
เปิดเฉลยหลังจากลองเองแล้วอย่างน้อยหนึ่งรอบ และอ่าน วิธีใช้เฉลย ก่อน
| เฉลย | คู่กับ |
|---|---|
| solution/s20_capstone.py | practice/s20_capstone.py |
เช็กความเข้าใจ
หัวข้อที่มีชื่อว่า “เช็กความเข้าใจ”คำถามชุดเดียวกันอยู่ใน quiz.yaml สำหรับระบบที่ตรวจอัตโนมัติ
-
Guardian ขึ้น RUNNING แต่การ์ดผลไม่ขยับเลยและ motion ขยับตามการเขย่า จุดใดยังว่าง (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)
- ก) จุดที่ 2 อ่านความเร่ง
- ข) จุดที่ 3 r = edge_ai.result() (หรือจุดที่ 1 select)
- ค) จุดที่ 4 EMA
- ง) จุดที่ 5 fire_alert
เฉลย
ข — motion ขยับแปลว่าเสา DAQ ทำงาน การ์ดผลต้องการทั้งโมเดลที่ถูก select และการอ่าน result ในลูป
-
เขย่าค้างครบเกณฑ์แล้วแบนเนอร์ขึ้นรอจับตลอด ไม่มีเสียงหรือตัวนับเพิ่ม จุดใดยังว่าง (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)
- ก) จุดที่ 5 fire_alert(r[“label”], conf_s)
- ข) จุดที่ 2
- ค) จุดที่ 1
- ง) ไม่มีจุดใดผิด
เฉลย
ก — ด่านทั้งสามผ่านแล้วแต่ไม่มีการเรียกการกระทำ fire_alert คือปลายท่อที่ทำเสียง แบนเนอร์ และนับครั้ง
-
หลักฐานแบบใดดีที่สุดสำหรับอธิบายว่าเลือก HITS_NEEDED = 4 เพราะอะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)
- ก) “รู้สึกว่ากำลังดี”
- ข) ตารางผลทดลอง: ที่ 4 เหตุการณ์จริงเตือนครบ 5/5 และเคสหลอกเตือน 0/5 ส่วนที่ 2 เคสหลอกเตือน 3/5
- ค) ค่าเดียวกับเพื่อน
- ง) ค่าที่มากที่สุดที่ใส่ได้
เฉลย
ข — การตัดสินใจเชิงวิศวกรรมต้องยืนบนการวัด จำนวนการเตือนจากเหตุการณ์จริงเทียบกับเคสหลอกคือหลักฐานของการแลกเปลี่ยน
-
เดโม capstone ที่ดีควรแสดงอะไรนอกจากการเตือนที่ทำงาน (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)
- ก) โค้ดทั้งไฟล์บนจอ
- ข) เคสหลอกที่ Guardian ไม่เตือน และเหตุผลของการแลกเปลี่ยนที่เลือก
- ค) จำนวนบรรทัดของโค้ด
- ง) ไม่ต้องมีอะไรเพิ่ม
เฉลย
ข — ส่วนที่ยากและมีค่าคือการปฏิเสธสัญญาณปลอม และการอธิบายว่าทำไมตั้งค่าแบบนี้ นั่นคือความต่างระหว่างผลิตภัณฑ์กับเดโม
MVP ของชุดบทเรียน 8.1–8.2: ส่งมอบ Guardian ที่ทำงานครบอย่างน้อยสามเสา (DAQ, Processing, Apps) เฝ้าเหตุการณ์เป้าหมาย ผ่านชั้นตัดสินใจ (conf ที่กรองแล้วกับ debounce) แล้ว action ยิงจริง พร้อมอธิบายการออกแบบได้
- เติมไฟล์ฝึกครบห้าจุด รันบน Emulator หรือบอร์ดจนเห็นการเตือนจริง
- ออกแบบ Guardian ของคุณ ตั้งค่าออกแบบ แล้วทดสอบเหตุการณ์จริงกับเคสหลอกอย่างละอย่างน้อยห้าครั้ง จดผลลงบันทึกการเรียน
- ลองค่าออกแบบอย่างน้อยสองชุด เลือกชุดที่ใช้พร้อมเหตุผลจากตัวเลข
- อัดหรือเดโมสองนาที: การเตือนจริง เคสหลอกที่ไม่เตือน และการแลกเปลี่ยนที่เลือก ปิดท้ายด้วยคำถามวิจัยหรือทิศต่อยอดหนึ่งข้อ
จบคอร์สแล้ว ต่อยอดได้ตามสี่ทิศในบทเรียนนี้ หรือกลับไปที่โมดูล 5 ฝึกโมเดลของคุณเองแล้วเสียบเข้า Guardian
นี่คือบทเรียนสุดท้ายของหลักสูตร กลับไปที่ หน้าหลักสูตร เพื่อดูทางไปต่อ
สะท้อนคิด
หัวข้อที่มีชื่อว่า “สะท้อนคิด”- ค่าออกแบบที่คุณเลือกเปลี่ยนไปจากค่าเริ่มต้นเท่าไร และตัวเลขใดทำให้คุณเปลี่ยนใจ
- ถ้าต้องส่ง Guardian นี้ให้ลูกค้าใช้จริง อะไรคือสิ่งที่ยังขาดมากที่สุด
คำถามทบทวน
ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย
-
Guardian ขึ้น RUNNING แต่การ์ดผลไม่ขยับเลยและ motion ขยับตามการเขย่า จุดใดยังว่าง (เป้าหมายข้อ 1)
- จุดที่ 2 อ่านความเร่ง
- จุดที่ 3 r = edge_ai.result() (หรือจุดที่ 1 select)
- จุดที่ 4 EMA
- จุดที่ 5 fire_alert
ดูเฉลย
คำตอบ: B. จุดที่ 3 r = edge_ai.result() (หรือจุดที่ 1 select)
motion ขยับแปลว่าเสา DAQ ทำงาน การ์ดผลต้องการทั้งโมเดลที่ถูก select และการอ่าน result ในลูป
-
เขย่าค้างครบเกณฑ์แล้วแบนเนอร์ขึ้นรอจับตลอด ไม่มีเสียงหรือตัวนับเพิ่ม จุดใดยังว่าง (เป้าหมายข้อ 1)
- จุดที่ 5 fire_alert(r["label"], conf_s)
- จุดที่ 2
- จุดที่ 1
- ไม่มีจุดใดผิด
ดูเฉลย
คำตอบ: A. จุดที่ 5 fire_alert(r["label"], conf_s)
ด่านทั้งสามผ่านแล้วแต่ไม่มีการเรียกการกระทำ fire_alert คือปลายท่อที่ทำเสียง แบนเนอร์ และนับครั้ง
-
หลักฐานแบบใดดีที่สุดสำหรับอธิบายว่าเลือก HITS_NEEDED = 4 เพราะอะไร (เป้าหมายข้อ 2)
- "รู้สึกว่ากำลังดี"
- ตารางผลทดลอง: ที่ 4 เหตุการณ์จริงเตือนครบ 5/5 และเคสหลอกเตือน 0/5 ส่วนที่ 2 เคสหลอกเตือน 3/5
- ค่าเดียวกับเพื่อน
- ค่าที่มากที่สุดที่ใส่ได้
ดูเฉลย
คำตอบ: B. ตารางผลทดลอง: ที่ 4 เหตุการณ์จริงเตือนครบ 5/5 และเคสหลอกเตือน 0/5 ส่วนที่ 2 เคสหลอกเตือน 3/5
การตัดสินใจเชิงวิศวกรรมต้องยืนบนการวัด จำนวนการเตือนจากเหตุการณ์จริงเทียบกับเคสหลอกคือหลักฐานของการแลกเปลี่ยน
-
เดโม capstone ที่ดีควรแสดงอะไรนอกจากการเตือนที่ทำงาน (เป้าหมายข้อ 3)
- โค้ดทั้งไฟล์บนจอ
- เคสหลอกที่ Guardian ไม่เตือน และเหตุผลของการแลกเปลี่ยนที่เลือก
- จำนวนบรรทัดของโค้ด
- ไม่ต้องมีอะไรเพิ่ม
ดูเฉลย
คำตอบ: B. เคสหลอกที่ Guardian ไม่เตือน และเหตุผลของการแลกเปลี่ยนที่เลือก
ส่วนที่ยากและมีค่าคือการปฏิเสธสัญญาณปลอม และการอธิบายว่าทำไมตั้งค่าแบบนี้ นั่นคือความต่างระหว่างผลิตภัณฑ์กับเดโม
อ้างอิงบทเรียนนี้
ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน
"ลงมือทำ: สร้างและส่งมอบแอป Edge AI" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
ข้อความอ้างอิงภาษาอังกฤษ: "Hands-on: build and ship an edge AI app" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
ลิงก์บทเรียน: https://tesaiot.github.io/tesa-qualification-program/courses/edge-ai-developer/m08-capstone/l02-capstone-build-lab/
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA