YoloV3 darknet 系列 | 训练自己的VOC数据集

YoloV3 darknet 系列 | 训练自己的VOC数据集

系列简介

最近使用darknet下的YoloV3框架实现自己的项目,所以对yoloV3有了一定的了解,在使用过程中查了许多博客、踩了许多坑,所以希望写一个系列来介绍自己使用yoloV3的流程。本人是在ubuntu16.04、cuda10.1、opencv3.2的环境下完成yoloV3在darknet下的训练以及测试。
系列目前准备包括三个部分:

  1. VOC数据集的制作
  2. 如何使用yoloV3训练自己的数据集
  3. yoloV3批量测试以及将识别的目标切割保存

工程文件获取及测试

yoloV3的GitHub主页为:https://github.com/pjreddie/darknet
在自己新建的一个目录下打开终端并输入以下命令clone工程文件:

1git clone https://github.com/pjreddie/darknet.git 2 3

下载好工程文件后:cd darknet进入darknet所在目录,如果需要使用GPU或opencv则输入gedit Makefile或直接在图形化界面打开Makefile文件。
原文件显示的是:

1GPU=0 2CUDNN=0 3OPENCV=0 4 5

在这里作者修改了为:

1GPU=1 2CUDNN=1 #GPU和CUDNN用于GPU加速,前提是电脑已经安装了显卡对应的CUDA和CUDNN 3OPENCV=1 #开启opencv用于调用电脑摄像头以及显示测试结果,前提是安装了opencv否则会提示编译错误 4 5

在完成了对Makefile文件的修改后,在终端输入

1make 2 3

编译工程文件,如果在之前编译并生成了darknet可执行文件,则可输入:

1make clean 2 3

清除已经编译的可执行文件
如果想加速编译速度(编译darknet用处不是特别大, 但其他时候编译速度能有明显提升)则输入:

1make -j8 #具体使用几个内核进行编译根据自己电脑实际情况而定 2 3

编译好darknet工程文件后,需要下载测试所需的weights文件,具体是进入darknet目录并在终端输入:

1wget https://pjreddie.com/media/files/yolov3.weights 2 3

之后便是测试,在终端输入:

1./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg 2 3

用于使用给定的模型和自带的图片进行测试:
测试结果如下:
在这里插入图片描述

训练自己的VOC数据集

如何制作用于darknet yoloV3训练的VOC数据集请参考:VOC数据集的制作
首先我们下载训练所需的预权重文件在终端输入:

1wget https://pjreddie.com/media/files/darknet53.conv.74 2 3

紧接着进入darknet/data目录打开voc.names和coco.names将其中的标签名改为自己所需的标签名,由于作者只训练了一类标签所以改为了:insulator,如有多类标签请用换行符隔开。其中voc.names的标签名用于训练使用而coco.names的标签名用于测试使用。如不修改会使测试结果得到的标签与预期的不一致。
之后便是进入 darknet/cfg目录找到voc.data文件,内容如下:

1classes= 20 #训练的类别数 2train = /home/pjreddie/data/voc/train.txt #训练集txt文件所在的绝对路径 3valid = /home/pjreddie/data/voc/2007_test.txt #测试集txt文件所在的绝对路径 4names = data/voc.names #训练使用的标签名文件,即刚修改的voc.names文件所在目录,这里也可是绝对路径 5backup = backup #训练生成weights文件存放的路径 6 7

作者这里修改为:

1classes= 1 2train = /home/user/darknet/scripts/train.txt 3valid = /home/user/darknet/scripts/2007_test.txt 4names = data/voc.names 5backup = backup 6 7

供大家参考
接下来修改 darknet/data目录下的yolov3-voc.cfg文件,主要是将开头的:

1# Testing 2 batch=1 3 subdivisions=1 4# Training 5# batch=64 6# subdivisions=16 7 8

修改为:

1# Testing 2# batch=1 3# subdivisions=1 4# Training 5batch=64 6subdivisions=16 7 8

其实就是使用大的batch和subdivisions用于训练
紧接着使用ctrl+F搜索 yolo(共三处)

1[convolutional] 2size=1 3stride=1 4pad=1 5filters=75 6activation=linear 7 8[yolo] 9mask = 6,7,8 10anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 11classes=20 12num=9 13jitter=.3 14ignore_thresh = .5 15truth_thresh = 1 16random=1 17 18

主要修改的地方有三处:classes表示自己训练的标签类别数,filters使用3×(classes+5)计算得出,很多教程建议将random修改为0,表示关闭多尺度训练,如果电脑性能足够的话不建议修改。(注意:有三出yolo需要按照以上方法修改)
接下来便可以进行训练了,但是为了达到刚好的效果作者建议打开 darknet/examples目录下的detect.c文件,并找到一下代码的位置

1if(i%100==0){ 2#ifdef GPU 3 if(ngpus != 1) sync_nets(nets, ngpus, 0); 4#endif 5 char buff[256]; 6 sprintf(buff, "%s/%s.backup", backup_directory, base); 7 save_weights(net, buff); 8 } 9 if(i%10000==0 || (i < 1000 && i%100 == 0)){ 10#ifdef GPU 11 if(ngpus != 1) sync_nets(nets, ngpus, 0); 12#endif 13 char buff[256]; 14 sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i); 15 save_weights(net, buff); 16 } 17 18

以上代码用于控制训练生成的weights文件,细看代码能够发现,当训练次数少于1000次时,每100次输出一个weights文件,但是当训练次数大于1000次时每10000次输出一个weights。如果直接使用这个规则输出,想得到一个合适的weights文件得等到猴年马月咯!建议修改为:低于1000次每200次或500次输出一个weights文件,大于1000次每1000次输出一个weights文件。作者修改为了:

1if(i%1000==0 || (i < 1000 && i%500 == 0)) 2 3

在修改了任何源文件之后记得:在darknet的终端目录下输入:

1make clean 2make -j16 3 4

重新编译,以使修改的文件生效。
接下来便在darknet终端输入:

1./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 2 3

开始训练自己的模型,记得使用的.data文件和.cfg文件要和自己修改的文件对应,不然就是一堆不知名的bug(作者就因为这个徘徊了很久)。
接下来便是漫长的等待…

在训练达到合理的次数后终止训练,在darknet终端输入:

1./darknet detect cfg/yolov3-voc.cfg backup/yolov3-voc_4500.weights data/1.jpg 2 3

cfg/yolov3-voc.cfg 测试使用的配置文件,与训练使用的测试文件相同 backup/yolov3-voc_4500.weights 测试使用的权重文件,训练生成位于backup目录下 data/1.jpg 测试使用的测试图片,放置在data目录下

最后,便是观察测试效果的时候了:
在这里插入图片描述
以上便是使用darknet yolov3训练自己的voc数据集的完整操作。快去训练你自己的专属模型吧!
由于本人水平有限,以上博客难免会有误差。如有问题请联系:QQ:2458707789 加好友请备注:yoloV3训练

代码交流 2021