Like Share Discussion Bookmark Smile

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

Python | OpenCV YOLOv8 模型訓練

📚 前言

在上一篇 YOLOv8 預標籤(Pre-Label) 中,我們用預訓練模型自動產生標籤草稿,再透過 LabelImg 人工修正,完成了標記工作。
這一篇進入最核心的環節:YOLOv8 模型訓練

YOLOv8 的訓練指令非常簡潔,但背後有許多重要參數影響訓練效果。
這一篇將完整說明每個關鍵參數的意義,以及內建的增強與防過擬合機制。

🔎 本篇起點確認

在開始訓練之前,請確認前幾篇的工作都已完成,你手上應該有以下結構:

1
2
3
4
5
6
7
8
9
10
11
12
project/
├── raw_images/ ← 原始圖片(20260324 收集)
├── raw_labels/ ← 預標籤 + 人工修正後的 .txt(20260401 完成)
├── dataset/
│ ├── images/
│ │ ├── train/ ← 訓練集圖片
│ │ └── val/ ← 驗證集圖片
│ └── labels/
│ ├── train/ ← 訓練集標籤
│ └── val/ ← 驗證集標籤
├── data.yaml ← 訓練用設定檔(20260331 建立)
└── train.py ← 本篇將撰寫此檔案

其中 dataset/ 的切分是由 YOLOv8 資料集準備 篇的 split_dataset.py 完成的,data.yaml 也是在該篇建立、放在專案根目錄。
若尚未完成上述步驟,建議先補齊再繼續。

💻 基本訓練指令

指令列方式

1
2
3
4
5
6
7
yolo detect train \
model=yolov8n.pt \
data=data.yaml \
epochs=100 \
imgsz=640 \
batch=16 \
device=0 # 無 GPU 請改為 device=cpu

Python API 方式

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

model = YOLO("yolov8n.pt") # 以預訓練模型為起點(第一次執行會自動下載)

start = time.time()

results = model.train(
data="data.yaml", # 資料集設定檔路徑(由 20260331 的 create_yaml.py 產生)
epochs=100, # 訓練總輪數,初次建議先設 3~5 確認流程
imgsz=640, # 輸入圖片尺寸,越大越準確但越慢、越吃記憶體
batch=16, # 每批次圖片數,GPU 記憶體不足時調小(8、4)
device=0 if torch.cuda.is_available() else "cpu", # 自動偵測 GPU,無 GPU 退回 CPU
name="my_model", # 訓練結果子目錄名稱,結果存在 runs/detect/my_model/
)

elapsed = time.time() - start
print(f"訓練完成,總耗時:{elapsed // 3600:.0f}{elapsed % 3600 // 60:.0f}{elapsed % 60:.0f} 秒")


圖:使用 Python API 呼叫 model.train() 啟動 YOLOv8 訓練,指定資料集、訓練輪數與裝置

訓練完成後,結果會自動儲存在 runs/detect/my_model/ 目錄下。

關於 train.cache 與 val.cache

第一次訓練時,YOLOv8 會掃描所有圖片與標籤、驗證格式並建立索引,結果存成快取檔:

1
2
dataset/labels/train.cache
dataset/labels/val.cache

下次訓練直接讀快取,跳過重新掃描,啟動速度會快很多。

⚠️ 若修改了標籤或新增、刪除圖片,舊快取不會自動更新,需手動刪除後重新訓練才會重建。建議將這兩個檔案加進 .gitignore,不需要 commit。

🧠 重要訓練參數說明

參數 預設值 說明
model 起點模型,yolov8n.pt 為預訓練,yolov8n.yaml 為從頭訓練
data data.yaml 路徑
epochs 100 訓練總輪數
imgsz 640 輸入圖片尺寸,越大越準確但越慢
batch 16 每次訓練的圖片數量,依 GPU 記憶體調整
device 0/0,1/cpu,不設定則自動偵測
patience 50 Early Stopping:連續 N 個 epoch 無改善則停止
lr0 0.01 初始學習率
lrf 0.01 最終學習率比例(lr0 × lrf)
weight_decay 0.0005 L2 正規化係數,防止過擬合
dropout 0.0 Dropout 比率(僅分類頭,0 為停用)
workers 8 資料載入的執行緒數,Windows 建議設 0
save_period -1 每 N 個 epoch 儲存一次,-1 為停用
resume False 從上次中斷的 checkpoint 繼續訓練
val True 每個 epoch 後執行驗證
plots True 自動產生訓練曲線圖表

模型選擇建議

YOLOv8 有三種起點,初次使用選第一種即可:

① 從預訓練權重微調(一般情況,推薦)
載入 Ultralytics 在 COCO 資料集上訓練好的權重,再用自己的資料繼續訓練。模型已具備基本的影像辨識能力,收斂快、所需資料量少,是最常見的做法。

1
2
3
# demo_pretrained.py
from ultralytics import YOLO
model = YOLO("yolov8n.pt") # 第一次執行會自動下載,約 6MB

② 從頭訓練(特殊情況)
只載入網路架構定義,權重全部隨機初始化,需要大量資料(通常數千張以上)才能訓練出好的模型。若你的類別與 COCO 差異極大(例如醫療影像、衛星圖)才考慮。

1
2
3
# demo_from_scratch.py
from ultralytics import YOLO
model = YOLO("yolov8n.yaml") # 只有架構,無預訓練權重

③ 繼續訓練中斷的 checkpoint
訓練途中若因斷電、關機等原因中斷,可從上次儲存的 last.pt 繼續,不需要從頭跑。詳細用法見本篇 中斷後繼續訓練 章節。

1
2
3
# demo_resume.py
from ultralytics import YOLO
model = YOLO("runs/detect/my_model/weights/last.pt")

💻 GPU 加速設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# setup_gpu.py
import time
import torch
from ultralytics import YOLO

# 確認 GPU 是否可用
if torch.cuda.is_available():
gpu_count = torch.cuda.device_count()
if gpu_count >= 2:
device = "0,1"
print(f"使用多張 GPU 訓練(共 {gpu_count} 張)")
else:
device = 0
print(f"使用單張 GPU 訓練:{torch.cuda.get_device_name(0)}")
else:
device = "cpu"
print("未偵測到 GPU,使用 CPU 訓練(速度慢,建議僅用於測試流程)")

model = YOLO("yolov8n.pt")

start = time.time()
model.train(data="data.yaml", epochs=100, device=device)
elapsed = time.time() - start
print(f"訓練完成,總耗時:{elapsed // 3600:.0f}{elapsed % 3600 // 60:.0f}{elapsed % 60:.0f} 秒")


圖:自動偵測 GPU 數量,依情況選擇多張 GPU、單張 GPU 或 CPU 進行訓練

GPU 記憶體不足(OOM)

訓練啟動後若出現類似以下錯誤,表示 GPU 記憶體不夠:

1
RuntimeError: CUDA out of memory.

調整方向是縮小 batchimgsz,二選一或同時調整,直到不再 OOM:

1
2
3
4
5
6
7
8
9
10
11
12
13
# fix_oom.py
import torch
from ultralytics import YOLO

model = YOLO("yolov8n.pt")

# 方法一:只縮小 batch size(優先嘗試)
model.train(data="data.yaml", epochs=100, imgsz=640, batch=8,
device=0 if torch.cuda.is_available() else "cpu")

# 方法二:batch 和 imgsz 同時縮小(記憶體非常有限時)
# model.train(data="data.yaml", epochs=100, imgsz=416, batch=8,
# device=0 if torch.cuda.is_available() else "cpu")

💻 內建資料增強設定

YOLOv8 在訓練時內建了豐富的資料增強,預設已自動啟用,不需要額外撰寫增強程式碼。
一般情況下預設值已夠用,不需要動。但以下幾種情況可能需要調整:

  • 資料集很小(< 100 張):可以加強增強強度,讓模型看到更多變化,減少過擬合
  • 物件方向固定(如俯視圖):可以關閉 fliplrflipud,避免產生現實中不存在的翻轉角度
  • 室內固定光源場景hsv_shsv_v 可以調低,不需要大幅模擬色彩變化
  • 訓練結果不穩定或 mAP 很低:可以嘗試關閉 mosaic=0.0,有時過強的增強反而干擾學習

可透過參數調整增強強度:

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
27
# augmentation_params.py
import torch
from ultralytics import YOLO

model = YOLO("yolov8n.pt")

model.train(
data="data.yaml",
epochs=100,
device=0 if torch.cuda.is_available() else "cpu",
# 幾何增強
fliplr=0.5, # 水平翻轉機率(預設 0.5)
flipud=0.0, # 垂直翻轉機率(預設 0.0,通常不需要)
degrees=0.0, # 旋轉角度範圍 ±degrees
translate=0.1, # 平移比例
scale=0.5, # 縮放範圍(0.5 表示 0.5x ~ 1.5x)
shear=0.0, # 剪切角度
perspective=0.0, # 透視變換
# 色彩增強
hsv_h=0.015, # 色相抖動
hsv_s=0.7, # 飽和度抖動
hsv_v=0.4, # 明度抖動
# 進階增強
mosaic=1.0, # Mosaic 增強(將 4 張圖拼成 1 張,1.0 = 100% 啟用)
mixup=0.0, # MixUp 增強機率
copy_paste=0.0, # Copy-Paste 增強機率
)


圖:設定 YOLOv8 內建資料增強參數,調整幾何變換、色彩抖動及 Mosaic 拼接的增強強度

💡 Mosaic 增強是 YOLO 的招牌技術,將 4 張圖片拼接在一起,讓模型學習更多背景多樣性,對偵測小物件特別有效。

💻 防止過擬合設定

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

model = YOLO("yolov8n.pt")

model.train(
data="data.yaml",
epochs=200,
device=0 if torch.cuda.is_available() else "cpu",
patience=30, # 連續 30 個 epoch val/mAP50 無改善則 Early Stop
weight_decay=0.0005, # L2 正規化
dropout=0.0, # 分類頭 Dropout(預設關閉)
# 若 val Acc 下降、train Acc 持續上升,可嘗試:
# augment=True # 推論時也套用增強(TTA,提升準確度)
)


圖:設定 patience、weight_decay 與 dropout 等參數,啟用 Early Stopping 與 L2 正規化防止過擬合

如何判斷是否過擬合、怎麼讀懂這些指標,將在下一篇 YOLOv8 訓練結果分析 中完整說明。

💻 中斷後繼續訓練

YOLOv8 每個 epoch 都會儲存 last.pt,可隨時從中斷點繼續:

1
2
3
4
5
6
7
8
9
# resume_training.py
from ultralytics import YOLO

# 方法一:Python API
model = YOLO("runs/detect/my_model/weights/last.pt")
model.train(resume=True)

# 方法二:指令列
# yolo detect train resume model=runs/detect/my_model/weights/last.pt

💻 完整訓練範例

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
27
28
29
30
31
32
33
34
35
36
# train_full.py
import time
import torch
from ultralytics import YOLO

print(f"使用裝置:{'GPU - ' + torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'CPU'}")

model = YOLO("yolov8s.pt")

start = time.time()

model.train(
data="data.yaml",
epochs=150,
imgsz=640,
batch=16,
device=0 if torch.cuda.is_available() else "cpu",
workers=0, # Windows 請設 0
patience=30,
weight_decay=0.0005,
lr0=0.01,
lrf=0.01,
mosaic=1.0,
fliplr=0.5,
hsv_h=0.015,
hsv_s=0.7,
hsv_v=0.4,
name="custom_detector", # 訓練結果子目錄名稱,結果存在 runs/detect/custom_detector/
save_period=10, # 每 10 epoch 存一次
plots=True,
verbose=True,
)

elapsed = time.time() - start
print(f"訓練完成,總耗時:{elapsed // 3600:.0f}{elapsed % 3600 // 60:.0f}{elapsed % 60:.0f} 秒")
print("最佳模型:runs/detect/custom_detector/weights/best.pt")


圖:完整的 YOLOv8s 訓練範例,整合增強、Early Stopping、定期儲存等設定並輸出最佳模型路徑

⚠️ 注意事項

  • CPU 訓練速度非常慢:無 GPU 環境下,100 epochs 可能需要數小時甚至更長。第一次執行建議先將 epochs 設為 3~5,確認資料集路徑、格式、流程都正確後,再調回正式輪數。若需要完整訓練,強烈建議使用有 CUDA 的環境或 Google Colab(免費 GPU)。
  • Windows 上 workers 需設為 0:設成其他數值可能造成 DataLoader 死鎖,訓練無法啟動。
  • patience 不要設太小:YOLOv8 訓練初期的 mAP 可能波動較大,patience=10 可能會太早停止。建議至少設 20~30。
  • batch=-1 自動計算:可設定 batch=-1 讓 YOLOv8 根據 GPU 記憶體自動計算最大 batch size,但不夠穩定,建議手動設定。
  • 訓練過程中不要刪除 runs/ 目錄:中斷恢復需要依賴其中的 last.ptargs.yaml

🎯 結語

YOLOv8 的訓練流程非常完整,內建了增強、Early Stopping、自動儲存等功能,讓訓練過程更穩定。
下一步是 YOLOv8 訓練結果分析,學習如何解讀訓練輸出的各種圖表與指標,判斷模型是否訓練良好。

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

註:以上參考了
Ultralytics YOLOv8 官方文件 — Train
Ultralytics YOLOv8 官方文件 — Configuration
Ultralytics YOLOv8 官方文件 — Augmentation