這是我初次使用 YOLOv7 的操作紀錄,依照當時的環境整理安裝、標註、訓練與偵測步驟。讀取範例前,先確認程式版本與環境設定,再依自己的資料集調整路徑和參數。

本篇重點
  • 建立 Python 環境並安裝相依套件
  • 準備訓練/驗證資料與模型設定
  • 完成訓練後載入權重,測試圖片、影片或相機

原始實作記錄於 2022 年;以下操作畫面與程式範例保留當時版本。

以下記錄我初次建立 YOLOv7 環境,以及準備資料、訓練模型和執行偵測的過程。

參考文獻:


操作說明

  • 使用 Anaconda 管理 Python 環境,讓相依套件與其他專案分開。
  • 至Anaconda官網選擇符合系統與專案需求的版本:https://www.anaconda.com/products/distribution
  • 安裝完成後,使用 Anaconda Prompt (anaconda3) 來建立 YOLOv7 開發環境。

建立 YOLOv7 開發環境

  1. 建立 Python 新環境

    1
    2
    conda create -n yolov7 python=3.9.13
    conda activate yolov7
  2. 至Yolov7的Github下載:https://github.com/WongKinYiu/yolov7
    建立Yolov7環境:原文圖片 01

  3. 解壓縮下載的yolov7-main.zip的檔案

  4. 由於YOLO各版本都會有提供安裝模組清單,cd 至 yolov7-main 的資料夾,就可以安裝 Yolov7 所需套件

    1
    pip install -r requirements.txt

    建立Yolov7環境:原文圖片 02






  5. 開啟Anaconda Navigator,切換環境到剛剛建立的yolov7
    Anaconda Navigator

  6. 在上個步驟的Anaconda Navigator介面下安裝:

  • Notebook、CMD.exe Prompt
    若有其他開發需求,再安裝相應工具。

  1. 安裝Pytorch-cuda,官網:https://pytorch.org/
    Pytorch官網歷史版本:https://pytorch.org/get-started/previous-versions/
    原始實作選用 PyTorch 1.11,以下保留當時的安裝指令。相依版本應依所下載的 requirements.txt 核對;不要把舊筆記中的版本選擇解讀成所有後續版本都無法使用。

建立Yolov7環境:原文圖片 04

1
conda install pytorch==1.11.0 torchvision==0.12.0 torchaudio==0.11.0 cudatoolkit=11.3 -c pytorch
  • 示意圖:
    建立Yolov7環境:原文圖片 05
  1. 完成 Yolov7 環境安裝後,先確認能從這個環境啟動專案,再整理圖片與標註。

使用 labelImg 標註圖片

先確定類別名稱與順序,再以一致的規則標註。完成後抽查圖片與標籤是否配對,避免類別編號或儲存位置不一致,直到訓練時才發現問題。

1
pip install labelimg
  • 執行時,在Anaconda Prompt (yolov7)上輸入labelimg,會跳出以下畫面:
    1
    labelimg

示意圖


擷取影像與建立樣本

利用工業相機拍攝影片,將影片的各幀畫面擷取成照片,每張以名稱與流水號存入影像資料夾,再篩選需要的樣本。

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import cv2
import os
import shutil

a=input("請輸入資料夾名稱(請以英文命名):")
b=input("請輸入張數:")
enter=int(b)
# ----------
# 開啟攝像頭
cap = cv2.VideoCapture(0) # 選擇運行攝影機(預設為0)
# 視訊大小設定,獲取幀寬度,獲取幀高度
sz = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fps = 30
# 輸出格式
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# open and set props
vout = cv2.VideoWriter()
vout.open(a+'.mp4', fourcc, fps, sz, True)

cnt = 1
while cnt <= enter:
_, frame = cap.read()
# putText輸出到視訊上,各引數依次是:照片/新增的文字/左上角座標/字型/字型大小/顏色/字型粗細
cv2.putText(frame, str(cnt), (10, 20), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0), 1, cv2.LINE_AA)
vout.write(frame)
cnt += 1

cv2.imshow('vidio', frame)
cv2.waitKey(30)

vout.release()
cap.release()
# ----------------------------------------
video_path = a+'.mp4'
output_folder = './'+a+'/'

if os.path.isdir(output_folder):
print("刪除資料夾: {}".format(output_folder))
shutil.rmtree(output_folder)

os.mkdir(output_folder)
print("新建資料夾: {}".format(output_folder))
# ----------------------------------------
# 建立圖片
vc = cv2.VideoCapture(video_path)
fps = vc.get(cv2.CAP_PROP_FPS)
frame_count = int(vc.get(cv2.CAP_PROP_FRAME_COUNT))
#print(frame_count)
video = []

for idx in range(frame_count):
vc.set(1, idx)
ret, frame = vc.read()
height, width, layers = frame.shape
size = (width, height)

if frame is not None:
file_name = '{}{}{:04d}.jpg'.format(output_folder,a,idx+1)
cv2.imwrite(file_name, frame)

print("\rprocess: {}/{}".format(idx+1 , frame_count), end = '')
vc.release()
# ----------------------------------------
# 移動影片到資料夾
shutil.move(str(a)+'.mp4',str(a))

參考:【OpenCV】OpenCV 利用 python OpenCV 將一部影片拆成一張張圖片 sample code (內附程式碼) get images from video
詳閱:【永成的學習部落格】使用相機攝影截圖取AI辨識樣本
這一篇是我過去所寫的一篇文章。


訓練與驗證資料

先把圖片分成訓練集與驗證集,再各自整理圖片和標籤。訓練集參與模型學習,驗證集則用來觀察未參與訓練的資料表現。

  1. 訓練模型
    資料增加時,要同時留意圖片品質、標註一致性與場景差異,而不是只追求張數。資料量也會影響訓練時間。
    依本篇配置,將圖片放在.\yolov7-main\data\train裡面
  • 示意圖:
    訓練與驗證資料:原文圖片 07



  1. 驗證模型
    原始練習以至少 20 張驗證圖片作為起點,實際張數仍應能涵蓋各類別與預期使用情境,不能當作通用標準。
    依本篇配置,將圖片放在.\yolov7-main\data\val裡面
  • 示意圖:
    訓練與驗證資料:原文圖片 08



這裡以 7:3 或 8:2 作為資料切分比例的例子。切分後要確認驗證圖片沒有同時出現在訓練集中,避免結果過度樂觀。


整理資料與模型設定檔

  1. 將.\yolov7-main\data\coco.yaml的檔案複製,將檔名取為custom_data.yaml,然後編輯檔案:

    1
    2
    3
    4
    5
    6
    7
    8
    train: ./data/train  # 訓練的圖片&labels的資料夾索引
    val: ./data/val # 驗證的圖片&labels的資料夾索引

    # number of classes # 數字為訓練圖片類別的數量
    nc: 1

    # class names
    names: [ 'bad' ] # 類別名稱的設置
  2. 將.\yolov7-main\cfg\training\yolov7.yaml的檔案複製,將檔名取為yolov7-custom.yaml,然後編輯檔案:

    1
    2
    3
    4
    # parameters
    nc: 1 # number of classes # 數字為訓練圖片類別的數量
    depth_multiple: 1.0 # model depth multiple # 模型深度倍數
    width_multiple: 1.0 # layer channel multiple # 層通道多
  3. 到Yolov7-Github的Releases地方下載兩個檔案(yolov7-tiny.pt和yolov7.pt),將檔案存放在.\yolov7-main目錄下:
    下載連結:https://github.com/WongKinYiu/yolov7/releases

    訓練驗證前的準備參數:原文圖片 09


模型訓練

執行訓練前,逐一核對圖片路徑、標籤路徑、類別數與權重檔案。以下指令沿用原始目錄配置,請先替換成自己的檔案與參數。

1
python train.py --workers 1 --device 0 --batch-size 11 --epochs 200 --img 640 640 --data data/custom_data.yaml --hyp data/hyp.scratch.custom.yaml --cfg cfg/training/yolov7-custom.yaml --weights yolov7.pt --name yolov7-train --project runs/train

訓練完之後,將最新的.\runs\train的目錄下,yolov7-train最新資料夾之.\weights\best.pt的檔案複製到主目錄.\yolov7-main之下!
執行 detect 偵測時,請讓 --weights 指向訓練產生的 best.pt 檔案。原範例將權重複製到主目錄,方便使用相對路徑;也可在指令中指定原本的完整路徑。

  • 如示意圖:
    模型訓練:原文圖片 10

--weights:初始weights路徑。ex:--weights yolov7.pt
--cfg:model.yaml路徑。 ex:--cfg cfg/training/yolov7-custom.yaml
--data:data.yaml路徑。ex:--data data/custom_data.yaml
--hyp:hyperparameters路徑。ex:--hyp data/hyp.scratch.custom.yaml
--epochs:訓練回合,預設為300回合。ex:--epochs 200
--batch-size:預設=16, 所有 GPU 的總批大小。ex:--batch-size 11
--img-size:[訓練, 測試] 圖片大小,預設為【640,640】。ex:--img 640 640
--workers:訓練資料讀取工作的最大數量。ex:--workers 1
--name:將訓練結果資料夾名稱命名。ex:--name yolov7-train
--project:將訓練結果保存到自訂資料夾。ex:--project runs/train
--device :指定運算裝置,例如 GPU 編號或 cpu。預設值請以所用腳本的 --help 為準;原文的 --cuda device 標示應對照實際 --device 參數。ex:--device 0

  • (查看更多指令說明):

    在 Anaconda Prompt (yolov7) 上輸入:

    1
    python train.py -h

圖片、影片與串流偵測

先用一張已知內容的圖片確認模型能載入,再測試影片和相機來源。畫面能顯示、模型能推論,以及結果符合需求,是不同的檢查項目。

#除了可偵測圖片外,也能偵測影片、資料夾、webcam、即時串流、網頁上的影片

  • 範例(即時辨識):
    1
    python detect.py --weights best.pt --conf-thres 0.5 --img-size 640 --source 0 --view-img --no-trace --exist-ok --name yolov7-detect --project runs/detect
    --weights :則可用來指定預訓練的模型。ex:--weights best.pt
    --source:file.jpg#圖片、file.mp4#影片、dir/#資料夾、0#攝像頭(即時辨識)。
    --img-size :可以指定影像的大小,對於偵測比較小的物件時,可以加大影像的大小,預設的影像大小為 640。
    --iou-thres :是設定 IoU 門檻值。
    --conf-thres :則是設定信心度門檻值。
    --cuda device :指定運算裝置,例如 GPU 編號或 cpu。預設值請以所用腳本的 --help 為準;原文的 --cuda device 標示應對照實際 --device 參數。
    --save-txt:保存結果到*.txt。
    --save-conf:搭配 --save-txt 保存偵測框的信心值。
    --view-img:顯示視窗圖片。
    --nosave:不儲存輸出的圖片或影片。
    --classes:依類別編號過濾;實際參數拼法應為 --classes,並依腳本說明提供編號。
    --update:更新所有模型。
    --project:將驗證結果保存到自訂資料夾。ex:--project runs/detect
    --name:設定本次輸出資料夾名稱。ex:--name yolov7-detect
    --exist-ok:允許使用既有輸出名稱,不自動遞增編號;執行前留意原有輸出。
    --no-trace:不跟踪模型。
  • (查看更多指令說明):

    在 Anaconda Prompt (yolov7) 上輸入:

    1
    python detect.py -h

常見錯誤與處理方式

  1. OMP: Error #15: Initializing libomp.dylib, but found libiomp5.dylib already initialize
    原紀錄曾在 train.py 中使用下方 KMP_DUPLICATE_LIB_OK 繞行方式。它可能掩蓋 OpenMP 重複載入的衝突,應先檢查套件來源與相依版本,不把此設定視為已修復:
    1
    2
    import os
    os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
  • 示意圖:
    常見錯誤與處理方式:原文圖片 11
  1. UnicodeDecodeError: 'cp950' codec can't decode byte 0x93 in position 25: illegal multibyte sequence
    這類錯誤表示讀取編碼與檔案內容不相符。先檢查 .yaml 的儲存編碼與程式讀取方式,不要直接把原因歸結為中文內容或作業系統。
  • 此專案使用 UTF-8 設定檔時,檔案的儲存與程式讀取編碼需一致。
    常見錯誤與處理方式:原文圖片 12

回顧這次流程

可以依序檢查:環境能否執行、資料是否正確配對、訓練是否產生權重,以及偵測是否載入預期權重。出現問題時,先找出停在哪一個階段,比一次修改多個設定更容易定位原因。

版本相依條件可對照 YOLOv7 專案 requirements.txt。本文保留舊版範例,沒有重新執行相機或 GPU 訓練。