论文题目:YOLOv4: Optimal Speed and Accuracy of Object Detection

今天,使用YOLOv4对进行目标检测,将自己的训练过程记录下来,总的来说,和之前Darknet的YOLOv3版本的操作完全相同。

环境

  Ubuntu 16.04

  Python: 3.6.2

  OPENCV:2.4.9.1

  CUDA: 9.0

  GPU: GTX1050Ti

  首先下载代码:

git clone https://github.com/AlexeyAB/darknet.git
由于都是AlexeyAB大神的杰作,在使用上与YOLOv3使用过程几乎相同。

1. 编译make

  如果硬件设备包含GPU加速,需要对makefile文件进行修改,修改后如下图所示。

训练肯定需要使用GPU加速,那么得打开项目里面的makefile文件修改一些参数的值,

1-4、7行中的0改为1
makefile前面几行:打开GPU 加速,打开opencv,打开libdarknet.so生成开关

yolov8 ubuntu gpu 实时_CUDA

yolov8 ubuntu gpu 实时_搜索_02

  然后在终端进行编译:

# cd到darknet文件夹下: 
make # 或make -j8

yolov8 ubuntu gpu 实时_数据集_03

 

2. 下载开源权重,并测试:

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

  yolov4.conv.137: https://drive.google.com/open?id=1JKF-bdIklxOOVy-2Cr5qdvjgGpmGfcbp

  下载后放在主目录下

使用与训练的权重进行测试:

./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg

yolov8 ubuntu gpu 实时_数据集_04

yolov8 ubuntu gpu 实时_CUDA_05

成功则在主目录下出现predictions.jpg 图片为预测后的图片,打开 OPENCV=1的可以直接显示出图片。说明我们的环境配置好了,否则先去配置环境。

3. 训练自己的数据集

3.1 数据集制作

  构建与YOLOv3相同的数据文件夹(此处仍以YOLOv3的方式构建):

在根文件夹下按如下目录创建VOCdevkit 文件夹,放自己的训练数据。

VOCdevkit --VOC2007 ----Annotations #(放XML标签文件) ----ImageSets ------Main ----JPEGImages # (放原始图片)

中:

  • Anontations用于存放标签xml文件
  • JPEGImage用于存放图像
  • ImageSets内的Main文件夹用于存放生成的图片名字,例如:

yolov8 ubuntu gpu 实时_搜索_06

 

yolov8 ubuntu gpu 实时_CUDA_07

3.2. 准备YOLOv4需要的label和txt

首先,从路径为"./scripts"文件夹下有voc_label.py,复制到VOCdevkit 文件夹同等级下,打开后修改自己的类别信息,,并对其内容进行修改。

yolov8 ubuntu gpu 实时_搜索_08

其中,#后为注释掉的为原先的,未被注释掉的是修改后的,sets中为年份(VOC后的数字,例如VOC2007中的2007)和包含的数据集(Main文件夹中划分数据集的txt的种类),classes中填写标注文件中包含的待识别物体的类别标签。

然后将所有出现的 VOCdevkit修改为 相应的路径 ,因为我的目录是voc_label.py在VOCdevkit 文件夹同等级下 ,所以不需要对相关文件的路径进行修改,其他修改内容如下(这里根据你们的数据集更改 要求找到对应的目录就可以了)

 

yolov8 ubuntu gpu 实时_搜索_09

执行voc_label.py,在同等级目录下将会生成训练需要的文件,即各个训练集中包含图像的路径。

yolov8 ubuntu gpu 实时_数据集_10

 

yolov8 ubuntu gpu 实时_搜索_11

 

3.3 在主目录下创建yolo-obj.cfg 配置文件。将 yolov4-custom.cfg 中的内容复制到 yolo-obj.cfg里面,并做以下修改。

 

yolov4-custom.cfg 参数说明及调参经验https://zhuanlan.zhihu.com/p/91587361

https://zhuanlan.zhihu.com/p/114530609

  --3.3.1修改batch=64,修改subdivisions=32(如果显卡是1050TI的,可以把batch设置为96,如果报内存不足,将batch改回64将,或者subdivisions设置为32)
  --3.3.2修改max_batches=classes*2000 例如有2个类别人和车 ,那么就设置为4000,N个类就设置为N乘以2000,
  --3.3.3修改steps为80% 到 90% 的max_batches值 比如max_batches=4000,则steps=3200,3600
  --3.3.4修改classes,先用ctrl+F搜索 [yolo] 可以搜到3次,每次搜到的内容中 修改classes=你自己的类别 比如classes=2
  --3.3.5修改filters,一样先搜索 [yolo] ,每次搜的yolo上一个[convolutional] 中 filters=(classes + 5)x3 比如filters=21
  --3.3.6(可以跳过)如果要用[Gaussian_yolo] ,则搜索[Gaussian_yolo] 将[filters=57] 的filter 修改为 filters=(classes + 9)x3 (这里我没用到,但是还是修改了)

yolov8 ubuntu gpu 实时_搜索_12

3.4制作obj.names

在build\darknet\x64\data\ 文件夹下创建obj.names文件。内容为你的类别 比如人和车 那么obj.names 为如下

person car

yolov8 ubuntu gpu 实时_CUDA_13

3.5制作obj.data

在build\darknet\x64\data\文件夹下创建obj.data文件。内容如下

classes= 2 train = data/train.txt valid = data/test.txt #做测试用的测试txt,(voc_label.py生成的) names = data/obj.names #类别标签名称,找不到的话,修改为自己的绝对路径 backup = backup/ #权重存放位置

我在这读取不到相对路径下文件 所以改为绝对路径 就可以了 这是我的obj.data文件

yolov8 ubuntu gpu 实时_数据集_14

 

 3.6  开始训练

./darknet detector train build/darknet/x64/data/obj.data yolo-obj.cfg yolov4.conv.137 -map

如果要使用gpu的话输入以下

./darknet detector train build/darknet/x64/data/obj.data yolo-obj.cfg yolov4.conv.137 -gpus 0 -map

#若训练2000此后在之前训练的基础上继续训练(适合中途停止后继续训练)

./darknet detector train build/darknet/x64/data/obj.data yolo-obj.cfg backup/yolo-obj_2000.weights -gpus 0 -map

在训练过程中,与之前yolov3不同的是yolov4在训练过程中会弹出训练过程中的loss的实时图像,如下图所示,会动态的显示每一代的损失,当前代数和预计剩余时间。

 

出现问题:

报错 CUDA status Error: file: ./src/dark_cuda.c : () : line: 373 CUDA Error: out of memory CUDA Error: out of memory:

yolov8 ubuntu gpu 实时_数据集_15

  

解决方法:参考:  的问题中的回复

降低batch和subdivisions都设为16;然后把cfg文件中的width和height减小(但要是32的倍数,我的是416,416)直到能训练。

如下

yolov8 ubuntu gpu 实时_搜索_16

 

 

对于下图,值得一提的是起初loss在图像上看到的是平的,并不是意味着损失不下降,只是loss相对与18.0而言都太大了,在固定坐标的图像上难以显示,因此可视化的是平的。

yolov8 ubuntu gpu 实时_搜索_17

 

 

3.7. 预测

预测指令:

./darknet detector test build/darknet/x64/data/obj.data yolo-obj.cfg backup/yolo-obj_xxxx.weights

  然后在提示的Enter Path中输入待测图像的路径。如下图所示。

 

 

 

参考map图

./darknet detector map obj.data yolo-obj.cfg backup/yolo-obj_final.weights