使用C版YOLOv4在自己的數據集上訓練測試


本文記錄了如何在Ubuntu/Docker中使用Alexey實現的C版YOLOv4在自己的數據集上進行訓練與測試。

YOLO

論文 :

YOLOv4: Optimal Speed and Accuracy of Object Detection

代碼 :

https://github.com/AlexeyAB/darknet

環境配置

建議使用docker容器配置環境,docker的安裝不在此贅述,docker安裝好后拉取一個nvidia/cuda鏡像,docker的一些用法可以看這里。如果你不使用docker的話可以跳過docker相關部分。

首先把我們的docker跑起來

$docker run -itdp 0.0.0.0:32774:22 --gpus '"device=1,2"' --name yolo -v /home/usr/:/home -v /data0:/data0 nvidia/cuda-10.0-cudnn7-devel-ubuntu16.04:v1 /bin/bash

"-itdp 0.0.0.0:32774:22"表示在后台運行一個交互式容器並將主機的32774端口映射到docker容器的22/tcp端口,如果不需要指定端口可以將其改為"-itdP",這表示我們不指定tcp端口映射而是隨機映射。

"--gpus '"device=1,2"表示我們使用主機的1、2號GPU。docker的gpu命令用法可以看這里

"--name yolo"表示容器名稱,可自定義。

"-v /home/usr/:/home -v /data0:/data0"表示將物理機的/home/usr/目錄掛載在docker容器的/home路徑下,后面同理,需要掛載幾個目錄就寫幾個-v參數。

"nvidia/cuda-10.0-cudnn7-devel-ubuntu16.04:v1"表示要運行的容器名稱:容器標簽

"/bin/bash"表示容器內使用的命令程序。

docker的一些常用命令用法可以看這里

接着我們安裝依賴

CUDA : 需要CUDA 10.0,安裝看這里

cuDNN : 需要和CUDA 10.0對應的cuDNN,cuDNN在這里獲取,選擇最新的cuDNN for CUDA 10.0並下載cuDNN Library for Linux,安裝看這里

CMake : 需要CMake>=3.8,CMake在這里獲取,選擇"Unix/Linux Source (has \n line feeds)"后對應的文件下載,使用如下命令編譯安裝

$tar xvzf cmake-3.17.1.tar.gz  # 注意替換你下載的版本號,下同
$cd cmake-3.17.1
$./configure
$make -j
$make install

OpenCV : 需要OpenCV>=2.4,OpenCV在這里獲取,選擇Sources下載,使用如下命令編譯安裝

$unzip opencv-4.2.0.zip  # 注意替換成你下載的文件名,下同
$cd opencv-4.2.0.zip
$mkdir build
$cd build
$cmake ..
$make -j
$make install

上述各項依賴安裝期間有權限問題則使用sudo;各項安裝完成后應查看版本號;必要時通過修改~/.bashrc添加相關的環境變量並使用source ~/.bashrc激活,此處不再贅述。

然后我們編譯YOLOv4的darknet

將項目克隆至本地

$git clone https://github.com/AlexeyAB/darknet
$cd darknet

使用下列方式之一進行編譯

  1. 使用CMake
$mkdir build-release
$cd build-release
$cmake ..
$make -j
$make install

如果期間報錯,可能是之前的依賴安裝有問題,按錯誤提示Google解決,然后再次編譯,注意再次編譯前使用make clean清除之前編譯失敗后遺留的中間文件。

  1. 使用make

make前可修改darknet/Makefile文件前幾行的相關參數,參數含義在這里,一般至少將GPUCUDNN設置為1,以使用GPU加速。

$make -j

如果有報錯,解決后報錯后同樣記得make clean

編譯完成后執行

$./darknet
usage: ./darknet <function>

有如上結果說明編譯成功。

最后我們簡單測試一下編譯好的darknet

將yolov4.weights下載到darknet目錄中,可能需要機智上網。

Google Drive 地址 :

https://drive.google.com/open?id=1cewMfusmPjYWbrnuJRuKhPMwRe_b9PaT

GitHub 地址 :

https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights

然后執行

$./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg
CUDA-version: 10000 (10010), cuDNN: 7.6.5, GPU count: 2  
 OpenCV version: 4.2.0
 compute_capability = 750, cudnn_half = 0 
net.optimized_memory = 0 
mini_batch = 1, batch = 8, time_steps = 1, train = 0
...
...
[yolo] params: iou loss: ciou (4), iou_norm: 0.07, cls_norm: 1.00, scale_x_y: 1.05
nms_kind: greedynms (1), beta = 0.600000 
Total BFLOPS 128.459 
avg_outputs = 1068395 
 Allocate additional workspace_size = 52.43 MB 
Loading weights from yolov4.weights...
 seen 64, trained: 32032 K-images (500 Kilo-batches_64) 
Done! Loaded 162 layers from weights-file 
data/dog.jpg: Predicted in 103.595000 milli-seconds.
bicycle: 92%
dog: 98%
truck: 92%
pottedplant: 33%
...

可以看到最后輸出的檢測結果等,目錄下會生成預測結果。

訓練

按下面的格式組織我們的數據

最后用於訓練的命令是

./darknet detector train xxx.data xxx.cfg xxx.weights

因此在訓練前我們需要先組織好三個文件: 用於描述數據集信息的.data文件、用於描述網絡信息的.cfg文件和一個.weights預訓練權重文件。另外我們需要為數據集准備labels文件。

  1. 下載預訓練權重

在下面的地址之一下載預訓練權重,將其放入darknet目錄。

  1. 調整.data文件,文件內容示例如下
classes= 2
train  = data/train.txt
valid  = data/test.txt
names  = data/obj.names
backup = backup/
  • classes設置為你數據集的目標類別數。
  • train設置為訓練集文件train.txt的路徑,train.txt中包含所有的訓練集數據路徑,每行一條,注意相對路徑或絕對路徑均可,相對路徑是相對於可執行文件darknet的,如下所示:
data/obj/img1.jpg
data/obj/img2.jpg
data/obj/img3.jpg
  • valid設置為測試集文件test.txt的路徑,方法同train
  • names設置為一個.names文件的路徑,.names文件中包含了你數據集目標的所有類別,每行一個,如下所示:
dog
cat
person
...
  • backup設置為你將要存放中間權重的目錄路徑,訓練過程中每100個iteration會更新一次latest權重,每10000個iteration會保存一次中間權重,這些權重文件將存儲在你設置的backup目錄中。
  1. 調整.cfg文件。

我們首先將cfg/yolov4-custom.cfg復制一份並重命名為yolov4-obj.cfg(或其他名字),然后基於yolov4-obj.cfg進行修改。

yolov4-obj.cfg文件中,開頭部分描述了用於訓練網絡的一些超參數,然后描述了完整的網絡結構。我們將修改一部分超參數和網絡結構使其適應我們的數據集和訓練環境。

  • 設置batch=64
  • 設置subdivisions=16,如果稍后訓練時顯存溢出的話,可將此處調整為32、64。
  • 設置max_batches=classes*2000,但是不要小於訓練集的數據量,也不要小於6000,比如你有5類目標,則設置max_batches=10000
  • 設置stepsmax_batches的80%, 90%。
  • 設置width=416height=416或任何32的整數倍,根據數據特點和顯存容量決定。
  • 將每個[yolo]層的classes設置為你的數據集目標類別數。注意一共有3[yolo]層。
  • 將每個[yolo]層的上一層中的filters設置為(classes + 5)x3,其中classes就是剛才設置的類別數。
  1. 准備label文件。

我們需要為每個數據圖像准備一份label文件,里面每一行描述該圖像中標注的一個object的類別和bbox信息,如下所示:

<object-class> <x_center> <y_center> <width> <height>

其中object-class
# TODO: Detail

  1. 最后,我們的數據集應該組織為如下形式:
Annotations
JPEGImages
labels
trainval.txt
test.txt

其中Annotations中放置所有圖片的.xml標注文件,JPEGImages中放置所有的圖片,labels中放置上文所述的label文件,trainval.txttest.txt為上文所述訓練集和測試集文件。

開始訓練

# TODO: Start Train

測試

# TODO: Test


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM