AlexeyAB 以及兩位台灣中研院的資訊科學研究所的研究員在 2020 年 11 月 16 日提出改進 YOLOv4 的論文 — Scaled-YOLOv4: Scaling Cross Stage Partial Network,本文就來示範如何使用 YOLOv4-CSP 進行訓練
以下是 YOLOv4-CSP 的 github
我的作業系統是 Ubuntu 18.04.5,版本為 CUDA 10.2, cuDNN 7.6.5, python 3.7.9, torch 1.7.0, torchvision 0.8.1
安裝 mish cuda
(我在 CUDA 10.2 安裝 thomasbrandon/mish-cuda 沒成功,但在 CUDA 10.1, cuDNN 7.6.5, python 3.6.9, torch 1.6.0, torchvision 0.7.1 能夠成功)
$ pip install git+https://github.com/JunnYu/mish-cuda.git
下載 yolov4-csp
$ sudo apt install subversion$ svn checkout https://github.com/WongKinYiu/ScaledYOLOv4/branches/yolov4-csp
準備資料集
$ pip install kaggle
- 建立 kaggle_api_token.py
- 下載資料集
$ mkdir Face_Mask_data && cd Face_Mask_data$ kaggle datasets download -d andrewmvd/face-mask-detection — force$ unzip face-mask-detection.zip
下載完後會看到 annotations, images 的資料夾
annotations 是 xml 格式,需要將其轉換為 yolo 的格式,轉換格式可以參考以下文章
因為口罩資料集沒有分訓練集和驗證集,因此有稍微更改一下轉換 code
然後進行格式轉換
$ cd ..$ python xml_covert_to_yolo.py
執行完畢會新增 /yolov4-csp/data/train.txt, /yolov4-csp/data/val.txt, yolo_data,目錄會呈現以下樣子
下載 yolov4-csp.weights
$ cd yolov4-csp$ mkdir weights
新增一個 sh 檔,目的是下載 yolov4-csp.weights,內容如下
然後執行
$ chmod +x download.sh$ ./download.sh
執行完後會在 weights 資料夾中看到 yolov4-csp.weights
修改 cfg 中的 width, height, filters, classes
$ cp models/yolov4-csp.cfg models/yolov4-csp_416.cfg# 查看原本參數
$ sed -n -e 8p -e 9p -e 1022p -e 1029p -e 1131p -e 1138p -e 1240p -e 1247p models/yolov4-csp_416.cfg
這裡我將 width, height 修改為 416x416,而口罩資料集的 label 有 3 個類別,因此 → filters=(classes + 5)*3 = (3+5)*3 = 24
$ sed -i ‘8s/512/416/’ models/yolov4-csp_416.cfg$ sed -i ‘9s/512/416/’ models/yolov4-csp_416.cfg$ sed -i ‘1022s/255/24/’ models/yolov4-csp_416.cfg$ sed -i ‘1029s/80/3/’ models/yolov4-csp_416.cfg$ sed -i ‘1131s/255/24/’ models/yolov4-csp_416.cfg$ sed -i ‘1138s/80/3/’ models/yolov4-csp_416.cfg$ sed -i ‘1240s/255/24/’ models/yolov4-csp_416.cfg$ sed -i ‘1247s/80/3/’ models/yolov4-csp_416.cfg# 查看修改後的參數
$ sed -n -e 8p -e 9p -e 1022p -e 1029p -e 1131p -e 1138p -e 1240p -e 1247p models/yolov4-csp_416.cfg
修改預設 anchors 值
因為要使用 darknet 來計算 anchors 值,要先編譯 darknet
$ cd .. && git clone https://github.com/AlexeyAB/darknet$ sed -i “s/GPU=0/GPU=1/g” darknet/Makefile$ sed -i “s/CUDNN=0/CUDNN=1/g” darknet/Makefile$ sed -i “s/CUDNN_HALF=0/CUDNN_HALF=1/g” darknet/Makefile$ sed -i “s/OPENCV=0/OPENCV=1/g” darknet/Makefile$ cd darknet; make
❗ 使用 GPU 和 opencv 編譯 darknet 可能遇到的問題: /usr/bin/ld: cannot find -lcuda
💬 錯誤表示在 /usr/local/cuda/lib64 資料夾中找不到 libcuda.so,因此先搜尋 cuda 相關 library,然後再將 cuda library 鏈結到 /usr/local/cuda/lib64/libcuda.so
# 搜尋 cuda 相關 library
$ locate libcuda# 鏈結
$ sudo ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /usr/local/cuda/lib64/libcuda.so
- 建立 face.data,並輸入以下內容
$ nano face.data
train = ../yolov4-csp/data/train.txt
val = ../yolov4-csp/data/val.txt
classes = 3
- 計算 anchors 值
$ ./darknet detector calc_anchors face.data -num_of_clusters 9 -width 416 -height 416 -showpause# 輸出: anchors =9, 16, 15, 27, 23, 39, 33, 55, 46, 82, 74, 59, 73,120, 132,131, 160,198
- 更改 anchors 值
# 查看原本 anchors 值$ cd ../yolov4-csp$ sed -n -e 1028p -e 1137p -e 1246p models/yolov4-csp_416.cfg
$ sed -i ‘1028s/ 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401/9, 16, 15, 27, 23, 39, 33, 55, 46, 82, 74, 59, 73,120, 132,131, 160,198/’ models/yolov4-csp_416.cfg$ sed -i ‘1137s/ 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401/9, 16, 15, 27, 23, 39, 33, 55, 46, 82, 74, 59, 73,120, 132,131, 160,198/’ models/yolov4-csp_416.cfg$ sed -i ‘1246s/ 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401/9, 16, 15, 27, 23, 39, 33, 55, 46, 82, 74, 59, 73,120, 132,131, 160,198/’ models/yolov4-csp_416.cfg
訓練模型
- 安裝需要的依賴庫
$ pip install pyyaml tqdm matplotlib scipy
- 建立 face.yaml,並修改其內容
$ cd ../yolov4-csp$ cp data/coco.yaml data/face.yaml
train: data/train.txt
val: data/val.txt
# number of classes
nc: 3
# class names
names: [‘with_mask’, ‘without_mask’, ‘mask_weared_incorrect’]
- 建立 face.names,並修改其內容
$ cp data/coco.names data/face.names
with_mask
without_mask
mask_weared_incorrect
- 下圖是我檔案放置的位置路徑
- 執行訓練
$ python train.py --device 0 --batch-size 16 --data data/face.yaml --cfg models/yolov4-csp_416.cfg --weights '' --name yolov4-csp
❗ 執行 train.py 可能遇到的問題: AttributeError: module ‘yaml’ has no attribute ‘FullLoader’
💬 因為 FullLoader 類僅在 PyYAML 5.1及更高版本中可用,因此安裝 PyYAML
$ pip install -U PyYAML
- 訓練完後會在資料夾下看到 runs 資料夾,裡面會有訓練過程的資訊、結果及權重檔
測試模型
- 查看 detect.py 需要的參數
建立檢測資料夾
$ mkdir inference && mkdir inference/images
- 將要檢測的照片放入 inference/images 資料夾中,然後執行以下指令
$ python detect.py --weights runs/exp2_yolov4-csp/weights/last_yolov4-csp.pt --source inference/images/001.jpg --cfg models/yolov4-csp_416.cfg --names data/face.names
檢測結果會出現在 inference/output
也可以使用鏡頭讀取,更改為--source 0 即可
$ python detect.py --weights runs/exp2_yolov4-csp/weights/last_yolov4-csp.pt --source 0 --cfg models/yolov4-csp_416.cfg --names data/face.names
也能檢測影片,一樣將要檢測的影片放入 inference/images 資料夾中,更改 --source
$ python detect.py --weights runs/exp2_yolov4-csp/weights/last_yolov4-csp.pt --source inference/images/001.mp4 --cfg models/yolov4-csp_416.cfg --names data/face.names
📌 訓練步驟可以參考我的 github,於 Colab 上進行訓練
📌 ScaledYOLOv4 訓練也可參考: