โมดูล 4/5 · สัปดาห์ 10–12 · 27 ชม.

ชุดข้อมูลและการประเมิน

UAT 315 ปัญญาประดิษฐ์ การวิเคราะห์ข้อมูล และการมองเห็นด้วยคอมพิวเตอร์สำหรับระบบอากาศยานไร้คนขับ

เวลาเรียนประมาณ 90 นาทีร่าง รอตรวจปรับปรุงล่าสุด 27 กันยายน 2569

บทเรียน

เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ

  1. อธิบายการรั่วของข้อมูลเมื่อภาพจากเที่ยวบินเดียวกันอยู่ทั้งชุดฝึกและชุดทดสอบ และแบ่งชุดตามกลุ่มด้วย GroupShuffleSplit
  2. คำนวณ confusion matrix precision recall F1 และ IoU และอ่านความหมายให้ตรงงาน
  3. อธิบายความต่างระหว่าง mAP50 กับ mAP50–95 ของ COCO
  4. เลือกจุดตัดความมั่นใจตามผลเสียของความผิดพลาด และจัดทำ data card

ความรู้พื้นฐานที่ควรมี: UAT 315 โมดูล 2–3

ทำไมต้องรู้

ทีมหนึ่งรายงานว่าแบบจำลองตรวจจับผู้ประสบภัยได้ความแม่นยำ 99% แต่เมื่อบินในป่าที่ไม่เคยบิน ระบบพลาดเกือบหมด สาเหตุไม่ได้อยู่ที่แบบจำลอง แต่อยู่ที่ วิธีแบ่งข้อมูลและวิธีวัดผล การประเมินที่ผิดทำให้ทั้งทีมเชื่อผิด และอาจทำให้ผู้บังคับบัญชาตัดสินใจใช้ระบบที่ยังไม่พร้อม หน่วยความรู้ “ตรวจชุดข้อมูลก่อนเทรน AI” และ “ตรวจคุณภาพภาพและอ่านตัวชี้วัด AI” ของคลังความรู้โดรนเป็นพื้นฐานของโมดูลนี้

ข้อมูลรั่วจากเที่ยวบินเดียวกัน

ภาพหลายเฟรมจากเที่ยวบินเดียวกันคล้ายกันมาก ถ้าสุ่มแบ่ง รายภาพ เฟรมที่เกือบเหมือนกันจะอยู่ทั้งในชุดฝึกและชุดทดสอบ แบบจำลองจึงได้คะแนนสูงเพราะจำฉากได้ ไม่ใช่เพราะเรียนรู้สิ่งที่ต้องการ เรียกว่า การรั่วของข้อมูล (data leakage) ทางแก้คือแบ่ง ตามกลุ่ม เช่น ทั้งเที่ยวบินอยู่ชุดเดียว ถ้าต้องใช้กับพื้นที่ใหม่ ก็ต้องแบ่งตามพื้นที่

สองคอลัมน์ ด้านซ้ายแบ่งสุ่มรายภาพ จุดสีเดียวกันซึ่งมาจากเที่ยวบินเดียวกันกระจายอยู่ทั้ง train validation และ test ด้านขวาแบ่งตามเที่ยวบิน จุดแต่ละสีอยู่ในชุดเดียว ด้านล่างเขียนว่าสีเดียวกันคือภาพจากเที่ยวบินเดียวกัน
ภาพที่ 1 แบ่งชุดข้อมูลตามเที่ยวบินเพื่อกันข้อมูลรั่ว

ตัวอย่างที่ 1 คะแนนที่ดีเกินจริงจากการแบ่งแบบสุ่ม

ข้อมูลสังเคราะห์ 40 เที่ยวบิน เที่ยวละ 30 เฟรม แต่ละเที่ยวมี “ลายเซ็น” ของฉากเฉพาะตัว และป้ายของทั้งเที่ยวเป็นแบบเดียวกัน สัญญาณที่เกี่ยวกับป้ายจริงมีอยู่น้อยมาก ใช้แบบจำลองเพื่อนบ้านใกล้สุด (1-NN) ซึ่งทำนายตามตัวอย่างฝึกที่คล้ายที่สุด

import numpy as np
from sklearn.model_selection import GroupShuffleSplit, train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

rng = np.random.default_rng(345)
flights, frames = 40, 30
signature = rng.normal(0, 1, (flights, 5))
flight_label = rng.integers(0, 2, flights)
X = np.repeat(signature, frames, axis=0) + rng.normal(0, 0.1, (flights * frames, 5))
X[:, 0] += 0.3 * np.repeat(flight_label, frames)
y = np.repeat(flight_label, frames)
groups = np.repeat(np.arange(flights), frames)

knn = KNeighborsClassifier(n_neighbors=1)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.25, random_state=0)
print(f"random split by frame:  accuracy {accuracy_score(y_te, knn.fit(X_tr, y_tr).predict(X_te)):.3f}")
train_idx, test_idx = next(GroupShuffleSplit(test_size=0.25, random_state=0).split(X, y, groups))
print(f"split by flight:        accuracy {accuracy_score(y[test_idx], knn.fit(X[train_idx], y[train_idx]).predict(X[test_idx])):.3f}")
print("flights shared between train and test:", len(set(groups[train_idx]) & set(groups[test_idx])))
random split by frame:  accuracy 1.000
split by flight:        accuracy 0.300
flights shared between train and test: 0

แบ่งแบบสุ่มได้ 100% เพราะเฟรมทดสอบทุกเฟรมมีฝาแฝดจากเที่ยวเดียวกันอยู่ในชุดฝึก แต่เมื่อแบ่งตามเที่ยวบิน คะแนนเหลือเพียง 30% ซึ่งไม่ดีกว่าการเดาสุ่มของปัญหาสองคลาส (ชุดทดสอบมีเพียง 10 เที่ยวบิน ตัวเลขนี้จึงแกว่งได้มาก) ตัวเลขหลังคือความสามารถจริงกับเที่ยวบินใหม่ ซึ่งในข้อมูลนี้แทบไม่มีเลย

Confusion matrix และตัวชี้วัด

Confusion matrix นับผลสี่แบบ ได้แก่ TP (มีจริงและระบบบอกว่ามี) FP (ไม่มีจริงแต่บอกว่ามี หรือเตือนผิด) FN (มีจริงแต่พลาด) และ TN (ไม่มีและบอกว่าไม่มี) จากนั้นคำนวณ

  • precision สิ่งที่ระบบแจ้งว่าพบ ถูกกี่ส่วน
  • recall สิ่งที่มีจริง ระบบพบกี่ส่วน
  • F1 ค่าเฉลี่ยฮาร์มอนิกของทั้งสอง

ตัวอย่างนี้ใช้ยอดนับจากหน่วยความรู้ “Computer Vision และการต่อยอดสู่ Edge AI” คือ TP = 8, FP = 2, FN = 4

from sklearn.metrics import confusion_matrix, precision_recall_fscore_support

y_true = np.array([1] * 12 + [0] * 8)
y_pred = np.array([1] * 8 + [0] * 4 + [1] * 2 + [0] * 6)
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
p, r, f1, _ = precision_recall_fscore_support(y_true, y_pred, average="binary")
print(f"TP {tp}  FP {fp}  FN {fn}  TN {tn}")
print(f"precision {p:.4f}  recall {r:.4f}  F1 {f1:.4f}")
TP 8  FP 2  FN 4  TN 6
precision 0.8000  recall 0.6667  F1 0.7273

ถ้าเป็นงานค้นหาผู้ประสบภัย recall 0.67 หมายถึงพลาดผู้ประสบภัยหนึ่งในสามคน ซึ่งร้ายแรงกว่าการเตือนผิดที่ทำให้ต้องส่งคนไปตรวจเพิ่ม คะแนนความมั่นใจ (confidence) ของแบบจำลองก็ไม่ใช่ความแม่นยำ คะแนน 0.9 ของภาพหนึ่งไม่ได้แปลว่าแบบจำลองถูก 90% ของทุกภาพ

IoU และ mAP

สำหรับการตรวจจับวัตถุ กรอบทำนายต้องจับคู่กับกรอบจริงแบบหนึ่งต่อหนึ่งก่อน โดยต้องมี IoU ถึงเกณฑ์จึงนับเป็น TP กรอบสองกรอบที่ทับวัตถุเดียวนับเป็น TP ได้เพียงกรอบเดียว

กรอบสีฟ้าคือป้ายจริง A และกรอบประสีชมพูคือทำนาย B ซ้อนกันบางส่วน พื้นที่ทับแรเงาสีทองเขียน 60 ด้านขวามีสามกล่อง ส่วนทับเท่ากับ 60 พิกเซลกำลังสอง ส่วนรวมเท่ากับ 100 บวก 100 ลบ 60 เท่ากับ 140 และ IoU เท่ากับ 60 หาร 140 ประมาณ 0.43 น้อยกว่า 0.5
ภาพที่ 2 Intersection over Union ของกรอบสองกรอบ

AP (average precision) สรุปความสัมพันธ์ระหว่าง precision กับ recall เมื่อเปลี่ยนจุดตัดความมั่นใจ ส่วน mAP เฉลี่ย AP ของทุกคลาส การประเมินของ COCO ใช้ AP ที่เฉลี่ยจาก IoU 0.50 ถึง 0.95 ทีละ 0.05 เป็นตัวชี้วัดหลัก ส่วน AP50 ใช้ IoU 0.50 ค่าเดียว ซึ่งผ่อนปรนกว่ามาก ตัวเลขสองแบบนี้จึงเทียบกันตรง ๆ ไม่ได้

iou_thresholds = np.round(np.arange(0.50, 0.96, 0.05), 2)
print("COCO IoU thresholds:", iou_thresholds.tolist(), "count", len(iou_thresholds))
ap_per_class = {"person": 0.6, "vehicle": 0.8}
print("mAP =", round(sum(ap_per_class.values()) / len(ap_per_class), 2))
COCO IoU thresholds: [0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95] count 10
mAP = 0.7

ค่า AP ของแต่ละคลาสในตัวอย่างเป็นค่าสมมติจากคลังความรู้ AP คำนวณจากยอดนับที่จุดตัดเดียวไม่ได้ ต้องใช้โปรแกรมประเมินที่เรียงคะแนนความมั่นใจทั้งหมด และเมื่อรายงานต้องระบุชื่อตัวชี้วัดให้ชัด เช่น “mAP50–95 บนชุดทดสอบที่แบ่งตามพื้นที่”

เลือกจุดตัดตามผลเสีย

scores = np.array([0.95, 0.91, 0.88, 0.84, 0.80, 0.74, 0.69, 0.62, 0.55, 0.48,
                   0.44, 0.39, 0.33, 0.28, 0.22, 0.18, 0.12, 0.09, 0.05, 0.03])
labels = np.array([1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0])
for threshold in (0.7, 0.5, 0.3):
    pred = (scores >= threshold).astype(int)
    p, r, f1, _ = precision_recall_fscore_support(labels, pred, average="binary")
    print(f"threshold {threshold}: alerts {pred.sum():>2}  precision {p:.2f}  recall {r:.2f}  F1 {f1:.2f}")
threshold 0.7: alerts  6  precision 0.83  recall 0.50  F1 0.62
threshold 0.5: alerts  9  precision 0.78  recall 0.70  F1 0.74
threshold 0.3: alerts 13  precision 0.69  recall 0.90  F1 0.78

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

Data card

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

กิจกรรมในชั้นเรียน

กิจกรรม: ตรวจรายงานผลของแบบจำลอง

  1. อาจารย์แจกรายงานสมมติที่อ้าง “แม่นยำ 98%” ให้แต่ละกลุ่มหาอย่างน้อยห้าคำถามที่ต้องถามก่อนเชื่อ เช่น แบ่งชุดอย่างไร ตัวชี้วัดชื่ออะไร ชุดทดสอบมาจากพื้นที่ใด
  2. ทำแบบฝึก “ตรวจชุดข้อมูลก่อนเทรน AI” ในคลังความรู้โดรน หาข้อผิดพลาดห้าประเภทใน manifest ก่อนรันโปรแกรมตรวจ
  3. สำหรับงานค้นหาผู้ประสบภัยและงานนับต้นไม้ เลือกจุดตัดจากตารางในบทพร้อมเหตุผล
  4. เขียน data card หนึ่งหน้าสำหรับชุดภาพที่กลุ่มจะเก็บในอนาคต

ข้อผิดพลาดที่พบบ่อย

ระวัง

  • สุ่มแบ่งรายภาพ ทั้งที่ภาพมาจากเที่ยวบินหรือพื้นที่เดียวกัน
  • รายงานความแม่นยำอย่างเดียว ในงานตรวจจับที่ของจริงมีน้อย
  • เทียบ mAP50 กับ mAP50–95 ราวกับเป็นตัวเลขเดียวกัน
  • ใช้ชุดทดสอบเลือกจุดตัดความมั่นใจ
  • ไม่มี data card ผู้ใช้จึงไม่รู้ว่าแบบจำลองไม่เคยเห็นภาพกลางคืนหรือภาพจากพื้นที่อื่น

สรุป

  • ภาพจากเที่ยวบินเดียวกันต้องอยู่ชุดเดียวกัน มิฉะนั้นคะแนนจะดีเกินจริง
  • precision recall และ F1 ตอบคนละคำถาม เลือกตัวชี้วัดตามผลเสียของความผิดพลาด
  • การตรวจจับต้องจับคู่กรอบด้วย IoU และ mAP50 กับ mAP50–95 เป็นตัวชี้วัดคนละตัว
  • เลือกจุดตัดด้วยชุดตรวจสอบ และบันทึกข้อมูลด้วย data card

แบบฝึกตรวจความเข้าใจ

  1. TP = 30, FP = 10, FN = 20 มี precision และ recall เท่าใด
  2. ถ้า FP ลดเป็น 0 แต่ TP และ FN เท่าเดิม F1 เป็นเท่าใด เมื่อ TP = 8 และ FN = 4
  3. ทำไมการแบ่งแบบสุ่มรายภาพจึงให้คะแนนสูงเกินจริง
  4. mAP50–95 ของ COCO เฉลี่ย AP จาก IoU กี่ระดับ
  5. งานใดควรเน้น recall มากกว่า precision ระหว่าง “ค้นหาผู้ประสบภัย” กับ “เลือกภาพสวยไปทำสื่อประชาสัมพันธ์”
เฉลย
  1. precision และ recall
  2. เฟรมที่เกือบเหมือนกันจากเที่ยวบินเดียวกันอยู่ทั้งชุดฝึกและชุดทดสอบ แบบจำลองจึงจำฉากได้
  3. 10 ระดับ คือ 0.50, 0.55, …, 0.95
  4. ค้นหาผู้ประสบภัย เพราะการพลาดคนที่ต้องการความช่วยเหลือร้ายแรงกว่าการเตือนผิด

สรุปสูตรสำคัญ

precision
recall
F1
mAP

แหล่งอ้างอิงหลัก

  1. scikit-learn developers. Cross-validation: Evaluating estimator performance (scikit-learn 1.9). link
  2. scikit-learn developers. Metrics and scoring: Quantifying the quality of predictions (scikit-learn 1.9). link
  3. COCO Consortium. Detection evaluation. Common Objects in Context. link
  4. Ultralytics. Models supported by Ultralytics (YOLO11, YOLO26). Ultralytics documentation. link
  5. Géron, A. (2025). Hands-on machine learning with Scikit-Learn and PyTorch. O'Reilly. link
  6. National Institute of Standards and Technology. (2023). Artificial intelligence risk management framework (AI RMF 1.0) (NIST AI 100-1). link

อ่านเพิ่มเติม

ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล

พร้อมใช้D11

ตรวจชุดข้อมูลก่อนเทรน AI

ฝึกตรวจข้อมูลรั่วจากเที่ยวบินเดียวกัน ภาพซ้ำ และข้อมูลไม่ครบด้วย CSV และ Python ก่อนเริ่มเทรนโมเดลตรวจจับวัตถุ
พร้อมใช้D18D11

ตรวจคุณภาพภาพและอ่านตัวชี้วัด AI

แยกภาพที่ยังตัดสินไม่ได้ ฝึก precision และ recall จากข้อมูลสมมติ และอธิบายขอบเขตของผลประเมิน
พร้อมใช้D11

เตรียมและแบ่งชุดข้อมูล

โมเดลเรียนได้เท่าที่ข้อมูลและ labels สนับสนุน ต้องกำหนดวัตถุที่จะตรวจ ขอบเขตภาพ และสิทธิ์ก่อนรวบรวม แยกข้อมูลตามกลุ่มที่อาจคล้ายกัน เช่น เที่ยวบินหรือสถานที่ ก่อนใช้ validation เลือกค่าและพัก test ไว้
พร้อมใช้D11

ฝึกและประเมิน object detection

Object detection ต้องทำนายทั้งชนิดและตำแหน่งวัตถุ IoU คือพื้นที่กรอบที่ทับกันหารพื้นที่รวม ใช้ช่วยจับคู่คำทำนายกับคำตอบ ส่วน mAP ของระบบประเมินยังรวมการจัดอันดับและหลายเงื่อนไข ไม่เท่ากับ accuracy ระดับภาพ

ในชั้นเรียน / ภาคสนาม

บรรยาย อภิปรายกรณีศึกษา และแก้โจทย์ในชั้นเรียน

หลักฐานการเรียนรู้: ผล quiz และแบบฝึกหัดที่ส่ง

แบบทดสอบประจำโมดูล

แบบทดสอบนี้ใช้ตรวจความเข้าใจ (formative) ไม่ใช่การสอบเก็บคะแนน

โดเมนความรู้: ปัญญาประดิษฐ์และคอมพิวเตอร์วิทัศน์ · การจัดการ นวัตกรรม และวิชาชีพ · กฎหมาย ความปลอดภัย และความเสี่ยง