Like Share Discussion Bookmark Smile

J.J. Huang   2026-04-03   Python OpenCV 07.物件偵測與辨識篇   瀏覽次數:次   DMCA.com Protection Status

Python | OpenCV YOLOv8 訓練結果分析

📚 前言

在上一篇 YOLOv8 模型訓練 中,我們完成了模型訓練。
這一篇介紹如何 解讀訓練結果,判斷模型是否訓練良好,以及找出需要改進的方向。

YOLOv8 在訓練過程中會自動產生大量的圖表與指標,學會解讀這些資訊,才能有效地改善模型。

🗃️ 訓練結果目錄結構

前一篇 train_full.py 跑完後,結果儲存在 runs/detect/custom_detector/(對應 name="custom_detector")。若目錄不存在,請先確認訓練是否正常跑完。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
runs/detect/custom_detector/
├── weights/
│ ├── best.pt ← 驗證 mAP 最高的模型(用於部署)
│ └── last.pt ← 最後一個 epoch 的模型(用於繼續訓練)
├── results.csv ← 每個 epoch 的詳細數值
├── results.png ← 訓練曲線圖(Loss + Metrics)
├── confusion_matrix.png ← 混淆矩陣
├── confusion_matrix_normalized.png
├── PR_curve.png ← Precision-Recall 曲線
├── F1_curve.png ← F1-Confidence 曲線
├── P_curve.png ← Precision-Confidence 曲線
├── R_curve.png ← Recall-Confidence 曲線
├── val_batch0_labels.jpg ← 驗證集標籤視覺化
├── val_batch0_pred.jpg ← 驗證集預測視覺化
└── args.yaml ← 本次訓練使用的所有參數

💡 best.pt 是部署時使用的模型,不要用 last.pt 做推論,因為最後一個 epoch 不一定是最好的。

🔎 Loss 曲線解讀

results.png 中包含三種 Loss 的訓練與驗證曲線:

Loss 名稱 說明
box_loss 邊界框座標的回歸損失,越低代表邊界框越準
cls_loss 類別分類損失,越低代表類別辨識越準
dfl_loss Distribution Focal Loss,邊界框分布損失(YOLOv8 特有)

正常的訓練曲線應該是:

  • train/box_losstrain/cls_losstrain/dfl_loss 持續穩定下降
  • val/box_lossval/cls_lossval/dfl_loss 同步下降,並趨於平穩

異常情況判斷:

現象 可能原因 解法
train loss 下降但 val loss 上升 過擬合 增加資料、提高 weight_decay、降低 epochs
train/val loss 都不下降 學習率太小或資料有問題 提高 lr0,重新確認標籤格式
Loss 震盪劇烈 學習率太大或 batch 太小 降低 lr0,增加 batch
Loss 為 NaN 標籤座標超出 0~1 範圍 重新確認標籤格式


圖:results.png 訓練曲線圖,包含各項 Loss 與 mAP 指標的每個 epoch 變化

🔎 mAP 指標解讀

mAP(mean Average Precision)是物件偵測最重要的評估指標,有三個地方可以看到:

  1. 訓練時的終端機輸出:每個 epoch 結束後會印出當前的 mAP50 與 mAP50-95
  2. results.png:訓練結束後自動產生,包含完整的 mAP 曲線圖,在 runs/detect/custom_detector/
  3. results.csv:每個 epoch 的詳細數值,可用程式讀取(見本篇下方的範例)

各指標的意義:

指標 說明
mAP50 IoU 閾值 = 0.5 時的 mAP,只要邊界框重疊超過 50% 就算正確,是最常用的指標
mAP50-95 IoU 閾值從 0.5 到 0.95 的平均 mAP,要求更嚴格的邊界框定位精度,通常比 mAP50 低很多
Precision 模型預測出的框中,有多少比例是真的有物件(誤報率低)
Recall 實際存在的物件中,有多少比例被模型找到了(漏報率低)

mAP50 一般參考標準:

mAP50 評估
< 0.3 效果差,需要更多資料或重新審視標註品質
0.3 ~ 0.5 基本可用,仍有改善空間
0.5 ~ 0.7 良好
> 0.7 優秀

💡 自訂資料集的 mAP 沒有絕對標準,最重要的是「是否滿足應用需求」。例如安全監控對 Recall 要求高(不能漏報),商品辨識則對 Precision 要求高(不能誤報)。


圖:終端機輸出、results.png、results.csv,包含各項 Loss 與 mAP 指標的每個 epoch 變化

💻 用程式讀取訓練結果

本節需要額外安裝 pandasmatplotlib

1
pip install pandas matplotlib


圖:執行 pip install 安裝 pandas 與 matplotlib 的結果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# analyze_results.py
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("runs/detect/custom_detector/results.csv")
df.columns = df.columns.str.strip() # 去除欄位名稱的空白

print(df.columns.tolist()) # 查看所有欄位名稱
print(df.tail(5)) # 查看最後 5 個 epoch 的數值

# 找出最佳 epoch
best_epoch = df["metrics/mAP50(B)"].idxmax()
print(f"\n最佳 epoch:{best_epoch + 1}")
print(f"最佳 mAP50:{df['metrics/mAP50(B)'].max():.4f}")
print(f"最佳 mAP50-95:{df['metrics/mAP50-95(B)'].max():.4f}")

# 繪製 mAP 曲線
plt.figure(figsize=(10, 4))
plt.plot(df["metrics/mAP50(B)"], label="mAP50")
plt.plot(df["metrics/mAP50-95(B)"], label="mAP50-95")
plt.xlabel("Epoch")
plt.ylabel("mAP")
plt.legend()
plt.title("mAP Training Curve")
plt.savefig("mAP_curve.png")
plt.show()


圖:讀取 results.csv 找出最佳 epoch 並繪製 mAP50 與 mAP50-95 的訓練曲線圖

💻 執行驗證取得詳細報告

訓練完成後,可單獨對驗證集執行評估取得更詳細的結果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# evaluate.py
import torch
from ultralytics import YOLO

model = YOLO("runs/detect/custom_detector/weights/best.pt")

metrics = model.val(data="data.yaml",
device=0 if torch.cuda.is_available() else "cpu")

print(f"mAP50: {metrics.box.map50:.4f}")
print(f"mAP50-95: {metrics.box.map:.4f}")
print(f"Precision:{metrics.box.mp:.4f}")
print(f"Recall: {metrics.box.mr:.4f}")

# 各類別的 AP
print("\n各類別 AP50:")
for i, (name, ap) in enumerate(zip(metrics.names.values(), metrics.box.ap50)):
print(f" {name}: {ap:.4f}")


圖:載入最佳模型對驗證集執行評估,輸出 mAP50、mAP50-95、Precision、Recall 及各類別 AP50

🔎 混淆矩陣解讀

confusion_matrix_normalized.png 顯示各類別的預測分布:

  • 對角線高(接近 1.0):模型對該類別預測準確
  • 非對角線有數值:模型把某類別錯誤預測為其他類別
  • background FP:偵測到不存在的物件(假陽性多)
  • background FN:漏掉了實際存在的物件(假陰性多)


圖:confusion_matrix_normalized.png 範例,對角線數值越高代表各類別分類越準確

🔎 val_batch 視覺化

val_batch0_labels.jpgval_batch0_pred.jpg 是驗證集第一批次的對照圖:

  • Labels:實際標註的邊界框
  • Pred:模型預測的邊界框

直接比較這兩張圖,能快速判斷模型的偵測品質與定位精度。


圖:val_batch0_labels.jpg — 驗證集實際標註的邊界框


圖:val_batch0_pred.jpg — 模型預測的邊界框,與上圖對照判斷偵測品質

⚠️ 注意事項

  • mAP 低不一定代表模型差:如果資料量少、類別困難、或標註品質差,mAP 自然偏低,先確認資料品質。
  • best.ptlast.pt 的差異best.pt 是 mAP 最高的 epoch,不一定是最後一個 epoch。建議以 best.pt 部署。
  • Early Stopping 後的 last.pt:若訓練因 Early Stopping 提早結束,last.pt 是停止時的狀態,不一定是最好的,還是要用 best.pt

🎯 結語

學會解讀訓練結果,才能有效判斷模型是否需要更多資料、更長訓練時間,或調整超參數。
下一步是 YOLOv8 推論與匯出,把訓練好的模型實際應用在圖片、影片或即時攝影機上。

📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。

註:以上參考了
Ultralytics YOLOv8 官方文件 — Val
Ultralytics YOLOv8 官方文件 — Train
Mean Average Precision — 物件偵測評估指標說明