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

โมดูล edge_ai: ถามทะเบียนโมเดล เลือก แล้วอ่านคำตอบ

โมดูล 1 — เริ่มต้น: รันของจริงแล้วแกะดูข้างใน · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร

ใช้สี่คำสั่งหลักของโมดูล edge_ai คือ models, select, result และ stop อ่านคำตอบของโมเดลเป็น dict แปลความ conf กับ CONF_FLOOR และ latency ให้ถูก แล้วรันเมนูหกโมเดลครั้งแรกบน Emulator หรือบอร์ด

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

  1. เรียก edge_ai.models() แล้วอ่านคีย์ index, name, sensor และ labels ของแต่ละโมเดลได้ถูก และอธิบายว่าทำไมควรถามทะเบียนจากเฟิร์มแวร์แทนการ hard-code ชื่อหรือเลขโมเดล
  2. อธิบายว่า edge_ai.select(n) ยืนยันการสลับโมเดลด้วยการสังเกต (confirm by observation) และห่อการเรียกด้วย try/except OSError ได้
  3. อ่าน dict จาก edge_ai.result() แล้วบอกได้ว่า label, top, conf, scores, latency_ms และ seq หมายถึงอะไร ตัดสินได้ว่าผลใดเชื่อได้ตาม CONF_FLOOR (0.50) และแปลง latency เป็นจำนวนครั้งต่อวินาทีได้
  4. รันเมนู Edge AI บน BENTO Emulator หรือบอร์ด เลือกโมเดล กด Load แล้วเห็นคลาสที่ชนะเปลี่ยนตามท่าทางหรือเสียง

ทบทวนบทเรียน 1.1 ว่าโค้ด MicroPython อยู่บน Cortex-M33 ส่วนโมเดลอยู่บน Cortex-M55 กับ NPU เปิด BENTO IDE ไว้ ถ้ามีบอร์ดให้ต่อสาย USB ให้พร้อม ถ้ายังไม่มีก็ใช้ BENTO Emulator ได้ทั้งบทเรียน

โมดูล edge_ai คือหน้าต่างเดียวที่เราคุยกับเครื่องยนต์อนุมานบน M55 บทเรียนนี้ใช้แค่สี่คำสั่ง models → select → result → stop ซึ่งเป็นทั้งเรื่องราวของการรันโมเดล: อ่านทะเบียน เลือกโมเดล อ่านผล แล้วหยุด

edge_ai.models() คืน list ของ dict หนึ่งตัวต่อโมเดล มีคีย์ index (ใช้ตอน select) name (โชว์บนจอ) sensor (0 = IMU, 1 = RADAR, 2 = MIC) และ labels (คลาสที่โมเดลตอบได้) นิสัยที่ดีคือ ถามฮาร์ดแวร์ก่อน อย่าเดา ถ้าเฟิร์มแวร์เพิ่มหรือลดโมเดล โค้ดที่อ่านจาก models() จะปรับตามเอง ซึ่งสำคัญมากเพราะบอร์ดกับ Emulator มีจำนวนโมเดลไม่เท่ากัน

edge_ai.select(n) เป็นคำสั่งข้ามคอร์ มันส่งคำสั่งแล้วคอยเช็กว่าเครื่องยนต์สลับจริงหรือยัง (confirm by observation) ถ้าไม่ยืนยันภายในเวลาที่กำหนดจะโยน OSError เราจึงห่อด้วย try/except OSError เสมอ และ start(n) ทำงานเหมือน select(n)

edge_ai.result() คืนผลล่าสุดเป็น dict หรือ None ถ้ายังไม่มีผล: label คลาสที่ชนะ top ลำดับของคลาสนั้น conf ความมั่นใจ 0..1 scores คะแนนทุกคลาสที่รวมกันได้ 1 latency_ms เวลาที่ NPU ใช้ และ seq ที่เพิ่มขึ้นทุกครั้งที่มีผลใหม่ ในภาษาคณิต คลาสที่ชนะคือ $\arg\max_k s_k$ และความมั่นใจคือ $\max_k s_k$ ค่า CONF_FLOOR = 0.50 คือเส้นที่เฟิร์มแวร์แนะนำ ต่ำกว่านี้ถือว่าโมเดลยังไม่ชัวร์ เพราะโมเดลตอบเป็นความน่าจะเป็น ไม่ใช่ความจริงเด็ดขาด ส่วน latency แปลงเป็นจำนวนครั้งต่อวินาทีได้ด้วย $\text{fps} = 1000 / t_{\text{ms}}$ เช่น 4.1 ms ≈ 244 ครั้งต่อวินาที

เปิด 12_edge_ai_menu.py ดูก่อนว่าหน้า Edge AI จริงใช้สี่คำสั่งนี้อย่างไร ทาย (Predict) ก่อนรันว่าเลือก Motion แล้วเขย่าบอร์ดจะเกิดอะไร แล้วค่อยรันเทียบ ไฟล์ที่เราจะเติมเองอยู่ในบทเรียน 1.3

ไฟล์ ไฟล์นี้สอน
examples/12_edge_ai_menu.py Edge AI Menu: เลือกและรันโมเดล AI ได้ทุกตัวในเฟิร์มแวร์เดียว (ไม่ต้องต่อเน็ต)

สไลด์ของบทเรียนนี้อ้างถึงไฟล์ที่อยู่ในบทเรียนอื่นหรือใน shared/ ด้วย:

คำถามชุดเดียวกันอยู่ใน quiz.yaml สำหรับระบบที่ตรวจอัตโนมัติ

  1. ทำไมโค้ดในหลักสูตรนี้ถึงอ่านชื่อโมเดลจาก edge_ai.models() แทนการเขียนชื่อหรือเลขโมเดลตายตัว (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)

    • ก) เพราะ models() เร็วกว่าการเขียน list เอง
    • ข) เพราะเฟิร์มแวร์แต่ละบอร์ดมีโมเดลไม่เท่ากัน ถ้าอ่านจากทะเบียน โค้ดจะปรับตามเองโดยไม่ต้องแก้
    • ค) เพราะ select() รับได้เฉพาะชื่อโมเดล
    • ง) เพราะ Emulator ไม่มีโมเดลเลย
    เฉลย

    ข — นิสัย “ถามฮาร์ดแวร์ก่อน อย่าเดา” ทำให้โค้ดชุดเดียวใช้ได้ทั้งบอร์ดหกโมเดลและ Emulator ห้าโมเดล ลำดับที่ต่างกันก็ไม่ทำให้พัง

  2. ถ้า edge_ai.select(n) ส่งคำสั่งไปแล้วแต่เครื่องยนต์ไม่สลับภายในเวลาที่กำหนด จะเกิดอะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) select() คืน None เงียบ ๆ แล้วโปรแกรมทำต่อ
    • ข) select() โยน OSError เราจึงต้องห่อด้วย try/except OSError
    • ค) บอร์ดรีบูตเอง
    • ง) โมเดลตัวเดิมถูกลบออกจากทะเบียน
    เฉลย

    ข — select() ยืนยันด้วยการสังเกตว่าโมเดลที่ active เปลี่ยนจริง ถ้าไม่เห็นก็โยน OSError เพื่อไม่ให้โปรแกรมโกหกว่ากำลังรัน

  3. ผลคือ {‘label’: ‘circle’, ‘conf’: 0.41, …} และ CONF_FLOOR = 0.50 ควรทำอย่างไรกับคำตอบนี้ (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)

    • ก) เชื่อเลยเพราะ circle ชนะ
    • ข) ถือว่ายังไม่ชัวร์ เพราะ conf ต่ำกว่า CONF_FLOOR ยังไม่ควรสั่งการตามคำตอบนี้
    • ค) เรียก select() ใหม่ทุกครั้งที่ conf ต่ำ
    • ง) คูณ conf ด้วย 2 ให้ผ่านเกณฑ์
    เฉลย

    ข — argmax เลือกผู้ชนะเสมอแม้คะแนนสูสี CONF_FLOOR คือเกณฑ์ตัดบนค่า conf เชื่อคำตอบก็ต่อเมื่อ conf ≥ 0.50

  4. latency_ms = 5 หมายความว่าโมเดลรันได้สูงสุดราวกี่ครั้งต่อวินาที (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)

    • ก) 5 ครั้ง
    • ข) 50 ครั้ง
    • ค) 200 ครั้ง
    • ง) 5000 ครั้ง
    เฉลย

    ค — fps = 1000 / t_ms = 1000 / 5 = 200 ครั้งต่อวินาที เหลือเฟือเมื่อเทียบกับลูปที่อ่านผลทุกราว 180 ms

  5. บน BENTO Emulator คุณเลือก Motion Detection กด Load แล้วลากแผ่นเอียงหรือกด Shake ควรเห็นอะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 4)

    • ก) คลาสที่ชนะเปลี่ยนระหว่าง idle / circle / shaking พร้อมแถบความมั่นใจของทุกคลาส
    • ข) รายชื่อโมเดลหายไปจาก dropdown
    • ค) หน้าจอขึ้น Push ทุกครั้ง
    • ง) ไม่มีอะไรเปลี่ยนจนกว่าจะต่อ WiFi
    เฉลย

    ก — Motion มีสามคลาส idle circle shaking บน Emulator คะแนนเลียนแบบจากเซนเซอร์จำลอง จึงเปลี่ยนตามการเอียงหรือเขย่าที่เราจำลอง ไม่ต้องใช้เน็ตเลย

  • ใน REPL หรือในไฟล์ พิมพ์ edge_ai.models() แล้วจดว่าบอร์ดหรือ Emulator ของคุณมีกี่โมเดล ชื่ออะไร ใช้เซนเซอร์อะไร
  • รันเมนูบน Emulator (หรือบอร์ด) เลือก Motion Detection กด Load แล้วเห็นคลาสที่ชนะเปลี่ยนเป็น idle / circle / shaking
  • ถ้ามีบอร์ด ลองสลับไปโมเดลไมโครโฟนอย่างน้อยหนึ่งตัว แล้วส่งเสียงให้คลาสเปลี่ยน

บทเรียน 1.3 เราจะไล่โค้ดไฟล์ s01_first_inference.py แล้วเติมสี่ช่องเองจนเมนูทำงานครบวงจร

บทเรียนถัดไป: บทเรียน 1.3 — ลงมือทำ: เมนูโมเดลตัวแรกของเรา

  • ถ้าตั้ง CONF_FLOOR ต่ำเกินไปหรือสูงเกินไป แอปของคุณจะผิดพลาดแบบไหน
  • ทำไม select() ถึงต้อง “รอดู” ว่าสลับจริง แทนที่จะเชื่อว่าสั่งแล้วสำเร็จ

คำถามทบทวน

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

  1. ทำไมโค้ดในหลักสูตรนี้ถึงอ่านชื่อโมเดลจาก edge_ai.models() แทนการเขียนชื่อหรือเลขโมเดลตายตัว (เป้าหมายข้อ 1)

    1. เพราะ models() เร็วกว่าการเขียน list เอง
    2. เพราะเฟิร์มแวร์แต่ละบอร์ดมีโมเดลไม่เท่ากัน ถ้าอ่านจากทะเบียน โค้ดจะปรับตามเองโดยไม่ต้องแก้
    3. เพราะ select() รับได้เฉพาะชื่อโมเดล
    4. เพราะ Emulator ไม่มีโมเดลเลย
    ดูเฉลย

    คำตอบ: B. เพราะเฟิร์มแวร์แต่ละบอร์ดมีโมเดลไม่เท่ากัน ถ้าอ่านจากทะเบียน โค้ดจะปรับตามเองโดยไม่ต้องแก้

    นิสัย "ถามฮาร์ดแวร์ก่อน อย่าเดา" ทำให้โค้ดชุดเดียวใช้ได้ทั้งบอร์ดหกโมเดลและ Emulator ห้าโมเดล ลำดับที่ต่างกันก็ไม่ทำให้พัง

  2. ถ้า edge_ai.select(n) ส่งคำสั่งไปแล้วแต่เครื่องยนต์ไม่สลับภายในเวลาที่กำหนด จะเกิดอะไร (เป้าหมายข้อ 2)

    1. select() คืน None เงียบ ๆ แล้วโปรแกรมทำต่อ
    2. select() โยน OSError เราจึงต้องห่อด้วย try/except OSError
    3. บอร์ดรีบูตเอง
    4. โมเดลตัวเดิมถูกลบออกจากทะเบียน
    ดูเฉลย

    คำตอบ: B. select() โยน OSError เราจึงต้องห่อด้วย try/except OSError

    select() ยืนยันด้วยการสังเกตว่าโมเดลที่ active เปลี่ยนจริง ถ้าไม่เห็นก็โยน OSError เพื่อไม่ให้โปรแกรมโกหกว่ากำลังรัน

  3. ผลคือ {'label': 'circle', 'conf': 0.41, ...} และ CONF_FLOOR = 0.50 ควรทำอย่างไรกับคำตอบนี้ (เป้าหมายข้อ 3)

    1. เชื่อเลยเพราะ circle ชนะ
    2. ถือว่ายังไม่ชัวร์ เพราะ conf ต่ำกว่า CONF_FLOOR ยังไม่ควรสั่งการตามคำตอบนี้
    3. เรียก select() ใหม่ทุกครั้งที่ conf ต่ำ
    4. คูณ conf ด้วย 2 ให้ผ่านเกณฑ์
    ดูเฉลย

    คำตอบ: B. ถือว่ายังไม่ชัวร์ เพราะ conf ต่ำกว่า CONF_FLOOR ยังไม่ควรสั่งการตามคำตอบนี้

    argmax เลือกผู้ชนะเสมอแม้คะแนนสูสี CONF_FLOOR คือเกณฑ์ตัดบนค่า conf เชื่อคำตอบก็ต่อเมื่อ conf ≥ 0.50

  4. latency_ms = 5 หมายความว่าโมเดลรันได้สูงสุดราวกี่ครั้งต่อวินาที (เป้าหมายข้อ 3)

    1. 5 ครั้ง
    2. 50 ครั้ง
    3. 200 ครั้ง
    4. 5000 ครั้ง
    ดูเฉลย

    คำตอบ: C. 200 ครั้ง

    fps = 1000 / t_ms = 1000 / 5 = 200 ครั้งต่อวินาที เหลือเฟือเมื่อเทียบกับลูปที่อ่านผลทุกราว 180 ms

  5. บน BENTO Emulator คุณเลือก Motion Detection กด Load แล้วลากแผ่นเอียงหรือกด Shake ควรเห็นอะไร (เป้าหมายข้อ 4)

    1. คลาสที่ชนะเปลี่ยนระหว่าง idle / circle / shaking พร้อมแถบความมั่นใจของทุกคลาส
    2. รายชื่อโมเดลหายไปจาก dropdown
    3. หน้าจอขึ้น Push ทุกครั้ง
    4. ไม่มีอะไรเปลี่ยนจนกว่าจะต่อ WiFi
    ดูเฉลย

    คำตอบ: A. คลาสที่ชนะเปลี่ยนระหว่าง idle / circle / shaking พร้อมแถบความมั่นใจของทุกคลาส

    Motion มีสามคลาส idle circle shaking บน Emulator คะแนนเลียนแบบจากเซนเซอร์จำลอง จึงเปลี่ยนตามการเอียงหรือเขย่าที่เราจำลอง ไม่ต้องใช้เน็ตเลย

อ้างอิงบทเรียนนี้

ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน

"โมดูล edge_ai: ถามทะเบียนโมเดล เลือก แล้วอ่านคำตอบ" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0

ข้อความอ้างอิงภาษาอังกฤษ: "The edge_ai module: list the models, select one, read its answer" 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/m01-onboarding/l02-edge-ai-module/

วิธีอ้างอิง TESA ฉบับเต็ม

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

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