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

ลงมือทำ: เมนูโมเดลตัวแรกของเรา

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

ไล่โค้ดไฟล์ s01_first_inference.py ตามโครงสี่จังหวะของโปรแกรม MicroPython แล้วเติมสี่ช่องด้วยคำสั่ง select, result, verdict.text และ stop จนเมนู Edge AI ทำงานครบวงจรและปิดตัวเองอย่างเรียบร้อย

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

  1. ชี้ได้ว่าส่วนใดของ s01_first_inference.py อยู่ในจังหวะ import, สร้างครั้งเดียว, ลูป และ ui.poll และอธิบายว่าทำไมต้องสร้าง widget นอกลูป
  2. เติมสี่ช่องใน practice/s01_first_inference.py จนกด Load แล้วเห็นคลาสที่ชนะและแถบความมั่นใจทุกคลาสเปลี่ยนตามท่าทางหรือเสียง และกด Stop แล้วโมเดลหยุดจริง
  3. อธิบายว่าการเช็ก r[‘seq’] ก่อนวาดจอ และบล็อก finally ที่เรียก edge_ai.stop() ป้องกันปัญหาอะไร
  4. หาท่าหรือเสียงที่ทำให้ conf ต่ำกว่า 50% แล้วอธิบายได้ว่าทำไมคะแนนถึงกระจาย

ผ่านบทเรียน 1.2 มาแล้ว และรู้ว่าสี่คำสั่ง models, select, result, stop ทำอะไร เปิดไฟล์ฝึกใน BENTO IDE เตรียมบันทึกการเรียนไว้จดว่าแต่ละโมเดลต้องทำท่าหรือเสียงแบบไหนถึงจะชนะ

โปรแกรม MicroPython บน BENTO เกือบทุกตัวเดิน สี่จังหวะ: import → สร้าง widget ครั้งเดียว → ลูปที่อ่านค่าแล้วอัปเดตจอ → ui.poll รับปุ่มและการแตะจอ แล้ววนกลับ การสร้าง widget นอกลูปแล้วในลูปแค่เปลี่ยนค่าทำให้จอไม่กระพริบและไม่กินหน่วยความจำ ไฟล์ s01_first_inference.py อ่านได้เป็นประโยคเดียว: ถามว่ามีโมเดลอะไร → เลือกหนึ่งตัว → วนอ่านผล → เอาคลาสที่ชนะขึ้นจอ → หยุดตอนออก

ช่องเติมทั้งสี่คือสี่คำสั่งหลักพอดี: ปุ่ม Load เรียก edge_ai.select(sel) ภายใน try และขึ้น RUNNING หลัง select สำเร็จเท่านั้น ในลูปอ่าน r = edge_ai.result() แล้ววาดเฉพาะเมื่อ r['seq'] เปลี่ยน ด้วย verdict.text(r['label'] or '-') และแถบของทุกคลาสจาก r['scores'] (คลาสที่ i == top ระบายเขียว) ปุ่ม Stop เรียก edge_ai.stop() ส่วนบล็อก finally ที่ให้ไว้แล้วหยุดเครื่องยนต์ทุกครั้งที่ออก ไม่ว่าจะออกด้วยปุ่ม back หรือ error นี่คือนิสัยงานฝังตัว: ทิ้งเครื่องไว้ในสถานะที่รู้แน่เสมอ

ความสำเร็จของบทเรียนนี้ไม่ใช่แค่ “เห็นตัวหนังสือขยับ” แต่ต้องบอกได้ว่า conf 92% หมายความว่าอะไร และทำไมบางท่าโมเดลถึงยังไม่ชัวร์ ท่าที่ก้ำกึ่งระหว่างสองคลาส หรือเสียงที่คล้ายหลายคลาส ทำให้คะแนนกระจาย ไม่มีคลาสไหนชนะขาด

ใช้บันไดช่วยเหลือตามลำดับ: คำใบ้ # เติม: ในไฟล์ฝึก → ตารางช่องเติมในสไลด์ → เฉลย → ฉบับเต็ม s01_first_inference_full.py เป็นฉบับขัดเรียบร้อยที่เพิ่ม latency และใช้ CONF_FLOOR แยกสี “มั่นใจ” กับ “ยังไม่ชัวร์” เปิดดูหลังเติมไฟล์ฝึกผ่านแล้ว แล้วลองหาว่ามันต่างจากไฟล์ของคุณตรงไหน

ไฟล์ ไฟล์นี้สอน
examples/s01_first_inference_full.py เมนู Edge AI 6 โมเดล (ฉบับเต็ม)

ในไฟล์มี pass สี่จุดตรงคอมเมนต์ # เติม: เติมตามลำดับนี้ แล้วรันทดสอบทุกครั้งที่เติมเสร็จหนึ่งจุด

  1. ปุ่ม Load → edge_ai.select(sel) 2) ในลูป → r = edge_ai.result() 3) มีผลใหม่ → verdict.text(r['label'] or '-')
  2. ปุ่ม Stop → edge_ai.stop() ถ้าลืมจุดที่ 1 จะขึ้น RUNNING แต่ไม่มีผล ถ้าลืมจุดที่ 3 แถบขยับแต่ตัวอักษรใหญ่ไม่เปลี่ยน ถ้ายังไม่ขึ้น ให้กลับไปเช็กการเยื้องบรรทัดกับชื่อคำสั่งก่อน
ไฟล์ฝึก เรื่อง
practice/s01_first_inference.py รันโมเดล Edge AI ตัวแรกของเรา (ฉบับฝึกเติมโค้ด)

เปิดเฉลยหลังจากลองเองแล้วอย่างน้อยหนึ่งรอบ และอ่าน วิธีใช้เฉลย ก่อน

เฉลย คู่กับ
solution/s01_first_inference.py practice/s01_first_inference.py

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

  1. เรียงสี่จังหวะของโปรแกรม MicroPython บน BENTO (เรียงลำดับ · เป้าหมายข้อ 1)

    • ก) ลูป: อ่านผลแล้วอัปเดตจอ
    • ข) import: edge_ai, ui, lcd, time
    • ค) ui.poll: รับปุ่มและการแตะจอ
    • ง) สร้างครั้งเดียว: อ่าน models() และสร้าง widget
    เฉลย

    ข → ง → ก → ค — import → สร้างครั้งเดียว → ลูป → ui.poll แล้ววนกลับ widget สร้างนอกลูป ในลูปแค่เปลี่ยนค่า จอจึงไม่กระพริบ

  2. เติมไฟล์ฝึกแล้ว กด Load สถานะขึ้น RUNNING แต่ไม่มีผลอนุมานเลย ลืมเติมจุดใดมากที่สุด (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) จุดที่ 1: edge_ai.select(sel) ในปุ่ม Load
    • ข) จุดที่ 3: verdict.text(…)
    • ค) จุดที่ 4: edge_ai.stop()
    • ง) บรรทัด import lcd
    เฉลย

    ก — ถ้าไม่เรียก select() โมเดลไม่ถูกสั่งให้รันเลย แต่โค้ดยังขึ้นข้อความ RUNNING ตามบรรทัดถัดไป ตารางช่องเติมในสไลด์บอกอาการนี้ไว้ตรง ๆ

  3. แถบความมั่นใจขยับทุกคลาส แต่ตัวอักษรใหญ่ของคลาสที่ชนะไม่เปลี่ยนเลย ช่องใดยังไม่ได้เติม (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) r = edge_ai.result()
    • ข) verdict.text(r[‘label’] or ‘-’)
    • ค) edge_ai.stop()
    • ง) edge_ai.select(sel)
    เฉลย

    ข — แถบมาจาก r[‘scores’] ที่ให้ไว้แล้ว แสดงว่า result() ทำงาน ส่วนตัวอักษรใหญ่ต้องเติม verdict.text เอง

  4. ข้อใดบอกเหตุผลของการเช็ก r[‘seq’] และบล็อก finally ได้ถูกต้อง (เลือกทุกข้อที่ถูก) (เลือกได้หลายข้อ · เป้าหมายข้อ 3)

    • ก) เช็ก seq เพื่อวาดจอเฉพาะเมื่อมีผลใหม่ ไม่วาดซ้ำทุกรอบ
    • ข) finally ทำให้ออกยังไงก็เรียก edge_ai.stop() เครื่องยนต์ไม่รันค้าง
    • ค) seq คือความมั่นใจของโมเดลเป็นเปอร์เซ็นต์
    • ง) finally ทำให้โปรแกรมไม่มีวันเกิด error
    เฉลย

    ก, ข — seq เพิ่มขึ้นทุกครั้งที่มีผลใหม่ จึงบอกได้ว่าควรวาดไหม ส่วน finally ไม่ได้กัน error แต่รับประกันว่าตอนออกจะหยุดเครื่องยนต์เสมอ

  5. ถ้าทำท่าที่ก้ำกึ่งระหว่าง circle กับ shaking สิ่งที่มักเห็นบนจอคืออะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 4)

    • ก) คลาสใดคลาสหนึ่งชนะขาดที่ 100%
    • ข) คะแนนกระจายระหว่างสองคลาส conf ของผู้ชนะต่ำ อาจต่ำกว่า 50%
    • ค) โมเดลหยุดทำงาน
    • ง) latency_ms กลายเป็นศูนย์
    เฉลย

    ข — เมื่อข้อมูลคล้ายหลายคลาส softmax จะแบ่งคะแนนไปหลายคลาส ผู้ชนะจึงชนะแบบเฉียด นี่คือเหตุผลที่ต้องมี CONF_FLOOR

MVP ของชุดบทเรียน 1.1–1.3: รันเมนู edge_ai แล้วอ่านผลสดออก ทั้งคลาสที่ชนะ (label) และความมั่นใจ (conf) เปลี่ยนตามท่าทางหรือเสียงจริง

  • เติมไฟล์ฝึกครบสี่ช่อง รันได้บน Emulator หรือบอร์ด
  • สลับอย่างน้อยสามโมเดล แล้วจดลงบันทึกการเรียนว่าแต่ละตัวต้องทำอะไรถึงจะได้คลาสที่ชนะ
  • หาท่าหรือเสียงที่ทำให้ conf ต่ำกว่า 50% และอธิบายว่าทำไม
  • อธิบายได้ว่าโค้ดเรียก models, select, result และ stop ตรงไหน ทำอะไร

ชุดบทเรียนถัดไป (บทเรียน 1.4–1.5) เราจะแกะแอปเซนเซอร์ทีละส่วน จับโครงสี่จังหวะให้ขาด แล้ว remix เป็นของเราเอง

บทเรียนถัดไป: บทเรียน 1.4 — แกะแอปเซนเซอร์: โครงร่วมสี่จังหวะของทุกโปรแกรม

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

คำถามทบทวน

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

  1. เรียงสี่จังหวะของโปรแกรม MicroPython บน BENTO (เป้าหมายข้อ 1)

    1. ลูป: อ่านผลแล้วอัปเดตจอ
    2. import: edge_ai, ui, lcd, time
    3. ui.poll: รับปุ่มและการแตะจอ
    4. สร้างครั้งเดียว: อ่าน models() และสร้าง widget
    ดูเฉลย

    ลำดับที่ถูก: B. import: edge_ai, ui, lcd, time → D. สร้างครั้งเดียว: อ่าน models() และสร้าง widget → A. ลูป: อ่านผลแล้วอัปเดตจอ → C. ui.poll: รับปุ่มและการแตะจอ

    import → สร้างครั้งเดียว → ลูป → ui.poll แล้ววนกลับ widget สร้างนอกลูป ในลูปแค่เปลี่ยนค่า จอจึงไม่กระพริบ

  2. เติมไฟล์ฝึกแล้ว กด Load สถานะขึ้น RUNNING แต่ไม่มีผลอนุมานเลย ลืมเติมจุดใดมากที่สุด (เป้าหมายข้อ 2)

    1. จุดที่ 1: edge_ai.select(sel) ในปุ่ม Load
    2. จุดที่ 3: verdict.text(...)
    3. จุดที่ 4: edge_ai.stop()
    4. บรรทัด import lcd
    ดูเฉลย

    คำตอบ: A. จุดที่ 1: edge_ai.select(sel) ในปุ่ม Load

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

  3. แถบความมั่นใจขยับทุกคลาส แต่ตัวอักษรใหญ่ของคลาสที่ชนะไม่เปลี่ยนเลย ช่องใดยังไม่ได้เติม (เป้าหมายข้อ 2)

    1. r = edge_ai.result()
    2. verdict.text(r['label'] or '-')
    3. edge_ai.stop()
    4. edge_ai.select(sel)
    ดูเฉลย

    คำตอบ: B. verdict.text(r['label'] or '-')

    แถบมาจาก r['scores'] ที่ให้ไว้แล้ว แสดงว่า result() ทำงาน ส่วนตัวอักษรใหญ่ต้องเติม verdict.text เอง

  4. ข้อใดบอกเหตุผลของการเช็ก r['seq'] และบล็อก finally ได้ถูกต้อง (เลือกทุกข้อที่ถูก) (เป้าหมายข้อ 3)

    1. เช็ก seq เพื่อวาดจอเฉพาะเมื่อมีผลใหม่ ไม่วาดซ้ำทุกรอบ
    2. finally ทำให้ออกยังไงก็เรียก edge_ai.stop() เครื่องยนต์ไม่รันค้าง
    3. seq คือความมั่นใจของโมเดลเป็นเปอร์เซ็นต์
    4. finally ทำให้โปรแกรมไม่มีวันเกิด error
    ดูเฉลย

    คำตอบ: A. เช็ก seq เพื่อวาดจอเฉพาะเมื่อมีผลใหม่ ไม่วาดซ้ำทุกรอบ · B. finally ทำให้ออกยังไงก็เรียก edge_ai.stop() เครื่องยนต์ไม่รันค้าง

    seq เพิ่มขึ้นทุกครั้งที่มีผลใหม่ จึงบอกได้ว่าควรวาดไหม ส่วน finally ไม่ได้กัน error แต่รับประกันว่าตอนออกจะหยุดเครื่องยนต์เสมอ

  5. ถ้าทำท่าที่ก้ำกึ่งระหว่าง circle กับ shaking สิ่งที่มักเห็นบนจอคืออะไร (เป้าหมายข้อ 4)

    1. คลาสใดคลาสหนึ่งชนะขาดที่ 100%
    2. คะแนนกระจายระหว่างสองคลาส conf ของผู้ชนะต่ำ อาจต่ำกว่า 50%
    3. โมเดลหยุดทำงาน
    4. latency_ms กลายเป็นศูนย์
    ดูเฉลย

    คำตอบ: B. คะแนนกระจายระหว่างสองคลาส conf ของผู้ชนะต่ำ อาจต่ำกว่า 50%

    เมื่อข้อมูลคล้ายหลายคลาส softmax จะแบ่งคะแนนไปหลายคลาส ผู้ชนะจึงชนะแบบเฉียด นี่คือเหตุผลที่ต้องมี CONF_FLOOR

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

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

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

ข้อความอ้างอิงภาษาอังกฤษ: "Hands-on: your first model menu" 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/l03-first-inference-lab/

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

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

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