ข้ามไปยังเนื้อหา

ลงมือทำ: สร้างและส่งมอบแอป Edge AI

โมดูล 8 — Capstone: แอป Edge AI ของเราเอง · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร

เติมห้าบรรทัดสันหลังของ s20_capstone.py คือ select, อ่านความเร่งดิบ, result, กรองความมั่นใจด้วย EMA และ fire_alert แล้วออกแบบ จูน และเดโม Guardian ของเราเอง พิสูจน์ด้วยหลักฐานว่าเหตุการณ์จริงทำให้เตือนครั้งเดียว ส่วนเคสหลอกไม่ทำให้เตือน และเล่าเหตุผลของค่าออกแบบที่เลือก

เมื่อจบบทเรียนนี้ คุณจะ:

  1. เติมห้าจุดใน practice/s20_capstone.py จน Guardian แสดงบริบท motion กับ verdict ที่กรองแล้ว และเตือน (เสียง แบนเนอร์ ตัวนับ) ครั้งเดียวเมื่อคลาสเป้าหมายต่อเนื่องครบ HITS_NEEDED ผล
  2. ออกแบบ Guardian ของคุณ (โมเดล action และค่า CONF_FLOOR, HITS_NEEDED, EMA_ALPHA) และบันทึกเหตุผลพร้อมหลักฐานที่วัดได้ คือจำนวนการเตือนจากเหตุการณ์จริงกับจากเคสหลอกอย่างละอย่างน้อยห้าครั้ง
  3. เดโมสองนาทีที่แสดงการเตือนจริง เคสหลอกที่ไม่เตือน และการแลกเปลี่ยนที่เลือก พร้อมเสนอทิศต่อยอดหนึ่งทิศ

ผ่านบทเรียน 8.1 มาแล้ว มีแบบร่าง 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/ ด้วย:

คอมเมนต์ # เติม: อยู่ที่บรรทัด 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 สำหรับระบบที่ตรวจอัตโนมัติ

  1. Guardian ขึ้น RUNNING แต่การ์ดผลไม่ขยับเลยและ motion ขยับตามการเขย่า จุดใดยังว่าง (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)

    • ก) จุดที่ 2 อ่านความเร่ง
    • ข) จุดที่ 3 r = edge_ai.result() (หรือจุดที่ 1 select)
    • ค) จุดที่ 4 EMA
    • ง) จุดที่ 5 fire_alert
    เฉลย

    ข — motion ขยับแปลว่าเสา DAQ ทำงาน การ์ดผลต้องการทั้งโมเดลที่ถูก select และการอ่าน result ในลูป

  2. เขย่าค้างครบเกณฑ์แล้วแบนเนอร์ขึ้นรอจับตลอด ไม่มีเสียงหรือตัวนับเพิ่ม จุดใดยังว่าง (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)

    • ก) จุดที่ 5 fire_alert(r[“label”], conf_s)
    • ข) จุดที่ 2
    • ค) จุดที่ 1
    • ง) ไม่มีจุดใดผิด
    เฉลย

    ก — ด่านทั้งสามผ่านแล้วแต่ไม่มีการเรียกการกระทำ fire_alert คือปลายท่อที่ทำเสียง แบนเนอร์ และนับครั้ง

  3. หลักฐานแบบใดดีที่สุดสำหรับอธิบายว่าเลือก HITS_NEEDED = 4 เพราะอะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) “รู้สึกว่ากำลังดี”
    • ข) ตารางผลทดลอง: ที่ 4 เหตุการณ์จริงเตือนครบ 5/5 และเคสหลอกเตือน 0/5 ส่วนที่ 2 เคสหลอกเตือน 3/5
    • ค) ค่าเดียวกับเพื่อน
    • ง) ค่าที่มากที่สุดที่ใส่ได้
    เฉลย

    ข — การตัดสินใจเชิงวิศวกรรมต้องยืนบนการวัด จำนวนการเตือนจากเหตุการณ์จริงเทียบกับเคสหลอกคือหลักฐานของการแลกเปลี่ยน

  4. เดโม capstone ที่ดีควรแสดงอะไรนอกจากการเตือนที่ทำงาน (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)

    • ก) โค้ดทั้งไฟล์บนจอ
    • ข) เคสหลอกที่ Guardian ไม่เตือน และเหตุผลของการแลกเปลี่ยนที่เลือก
    • ค) จำนวนบรรทัดของโค้ด
    • ง) ไม่ต้องมีอะไรเพิ่ม
    เฉลย

    ข — ส่วนที่ยากและมีค่าคือการปฏิเสธสัญญาณปลอม และการอธิบายว่าทำไมตั้งค่าแบบนี้ นั่นคือความต่างระหว่างผลิตภัณฑ์กับเดโม

MVP ของชุดบทเรียน 8.1–8.2: ส่งมอบ Guardian ที่ทำงานครบอย่างน้อยสามเสา (DAQ, Processing, Apps) เฝ้าเหตุการณ์เป้าหมาย ผ่านชั้นตัดสินใจ (conf ที่กรองแล้วกับ debounce) แล้ว action ยิงจริง พร้อมอธิบายการออกแบบได้

  • เติมไฟล์ฝึกครบห้าจุด รันบน Emulator หรือบอร์ดจนเห็นการเตือนจริง
  • ออกแบบ Guardian ของคุณ ตั้งค่าออกแบบ แล้วทดสอบเหตุการณ์จริงกับเคสหลอกอย่างละอย่างน้อยห้าครั้ง จดผลลงบันทึกการเรียน
  • ลองค่าออกแบบอย่างน้อยสองชุด เลือกชุดที่ใช้พร้อมเหตุผลจากตัวเลข
  • อัดหรือเดโมสองนาที: การเตือนจริง เคสหลอกที่ไม่เตือน และการแลกเปลี่ยนที่เลือก ปิดท้ายด้วยคำถามวิจัยหรือทิศต่อยอดหนึ่งข้อ

จบคอร์สแล้ว ต่อยอดได้ตามสี่ทิศในบทเรียนนี้ หรือกลับไปที่โมดูล 5 ฝึกโมเดลของคุณเองแล้วเสียบเข้า Guardian

นี่คือบทเรียนสุดท้ายของหลักสูตร กลับไปที่ หน้าหลักสูตร เพื่อดูทางไปต่อ

  • ค่าออกแบบที่คุณเลือกเปลี่ยนไปจากค่าเริ่มต้นเท่าไร และตัวเลขใดทำให้คุณเปลี่ยนใจ
  • ถ้าต้องส่ง Guardian นี้ให้ลูกค้าใช้จริง อะไรคือสิ่งที่ยังขาดมากที่สุด

คำถามทบทวน

ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย

  1. Guardian ขึ้น RUNNING แต่การ์ดผลไม่ขยับเลยและ motion ขยับตามการเขย่า จุดใดยังว่าง (เป้าหมายข้อ 1)

    1. จุดที่ 2 อ่านความเร่ง
    2. จุดที่ 3 r = edge_ai.result() (หรือจุดที่ 1 select)
    3. จุดที่ 4 EMA
    4. จุดที่ 5 fire_alert
    ดูเฉลย

    คำตอบ: B. จุดที่ 3 r = edge_ai.result() (หรือจุดที่ 1 select)

    motion ขยับแปลว่าเสา DAQ ทำงาน การ์ดผลต้องการทั้งโมเดลที่ถูก select และการอ่าน result ในลูป

  2. เขย่าค้างครบเกณฑ์แล้วแบนเนอร์ขึ้นรอจับตลอด ไม่มีเสียงหรือตัวนับเพิ่ม จุดใดยังว่าง (เป้าหมายข้อ 1)

    1. จุดที่ 5 fire_alert(r["label"], conf_s)
    2. จุดที่ 2
    3. จุดที่ 1
    4. ไม่มีจุดใดผิด
    ดูเฉลย

    คำตอบ: A. จุดที่ 5 fire_alert(r["label"], conf_s)

    ด่านทั้งสามผ่านแล้วแต่ไม่มีการเรียกการกระทำ fire_alert คือปลายท่อที่ทำเสียง แบนเนอร์ และนับครั้ง

  3. หลักฐานแบบใดดีที่สุดสำหรับอธิบายว่าเลือก HITS_NEEDED = 4 เพราะอะไร (เป้าหมายข้อ 2)

    1. "รู้สึกว่ากำลังดี"
    2. ตารางผลทดลอง: ที่ 4 เหตุการณ์จริงเตือนครบ 5/5 และเคสหลอกเตือน 0/5 ส่วนที่ 2 เคสหลอกเตือน 3/5
    3. ค่าเดียวกับเพื่อน
    4. ค่าที่มากที่สุดที่ใส่ได้
    ดูเฉลย

    คำตอบ: B. ตารางผลทดลอง: ที่ 4 เหตุการณ์จริงเตือนครบ 5/5 และเคสหลอกเตือน 0/5 ส่วนที่ 2 เคสหลอกเตือน 3/5

    การตัดสินใจเชิงวิศวกรรมต้องยืนบนการวัด จำนวนการเตือนจากเหตุการณ์จริงเทียบกับเคสหลอกคือหลักฐานของการแลกเปลี่ยน

  4. เดโม capstone ที่ดีควรแสดงอะไรนอกจากการเตือนที่ทำงาน (เป้าหมายข้อ 3)

    1. โค้ดทั้งไฟล์บนจอ
    2. เคสหลอกที่ Guardian ไม่เตือน และเหตุผลของการแลกเปลี่ยนที่เลือก
    3. จำนวนบรรทัดของโค้ด
    4. ไม่ต้องมีอะไรเพิ่ม
    ดูเฉลย

    คำตอบ: 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 ฉบับเต็ม

TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0

เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA