最近使用darknet下的YoloV3框架实现自己的项目,所以对yoloV3有了一定的了解,在使用过程中查了许多博客、踩了许多坑,所以希望写一个系列来介绍自己使用yoloV3的流程。本人是在ubuntu16.04、cuda10.1、opencv3.2的环境下完成yoloV3在darknet下的训练以及测试。
系列目前准备包括三个部分:
yoloV3的GitHub主页为:https://github.com/pjreddie/darknet
在自己新建的一个目录下打开终端并输入以下命令clone工程文件:
git clone https://github.com/pjreddie/darknet.git
下载好工程文件后:cd darknet
进入darknet所在目录,如果需要使用GPU或opencv则输入gedit Makefile
或直接在图形化界面打开Makefile文件。
原文件显示的是:
GPU=0
CUDNN=0
OPENCV=0
在这里作者修改了为:
GPU=1
CUDNN=1 #GPU和CUDNN用于GPU加速,前提是电脑已经安装了显卡对应的CUDA和CUDNN
OPENCV=1 #开启opencv用于调用电脑摄像头以及显示测试结果,前提是安装了opencv否则会提示编译错误
在完成了对Makefile文件的修改后,在终端输入
make
编译工程文件,如果在之前编译并生成了darknet可执行文件,则可输入:
make clean
清除已经编译的可执行文件
如果想加速编译速度(编译darknet用处不是特别大, 但其他时候编译速度能有明显提升)则输入:
make -j8 #具体使用几个内核进行编译根据自己电脑实际情况而定
编译好darknet工程文件后,需要下载测试所需的weights文件,具体是进入darknet目录并在终端输入:
wget https://pjreddie.com/media/files/yolov3.weights
之后便是测试,在终端输入:
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
如何制作用于darknet yoloV3训练的VOC数据集请参考:VOC数据集的制作
首先我们下载训练所需的预权重文件在终端输入:
wget https://pjreddie.com/media/files/darknet53.conv.74
紧接着进入darknet/data
目录打开voc.names
和coco.names
将其中的标签名改为自己所需的标签名,由于作者只训练了一类标签所以改为了:insulator
,如有多类标签请用换行符隔开。其中voc.names的标签名用于训练使用而coco.names的标签名用于测试使用。如不修改会使测试结果得到的标签与预期的不一致。
之后便是进入darknet/cfg目录找到voc.data
文件,内容如下:
classes= 20 #训练的类别数
train = /home/pjreddie/data/voc/train.txt #训练集txt文件所在的绝对路径
valid = /home/pjreddie/data/voc/2007_test.txt #测试集txt文件所在的绝对路径
names = data/voc.names #训练使用的标签名文件,即刚修改的voc.names文件所在目录,这里也可是绝对路径
backup = backup #训练生成weights文件存放的路径
作者这里修改为:
classes= 1
train = /home/user/darknet/scripts/train.txt
valid = /home/user/darknet/scripts/2007_test.txt
names = data/voc.names
backup = backup
供大家参考
接下来修改darknet/data目录下的yolov3-voc.cfg
文件,主要是将开头的:
# Testing
batch=1
subdivisions=1
# Training
# batch=64
# subdivisions=16
修改为:
# Testing
# batch=1
# subdivisions=1
# Training
batch=64
subdivisions=16
其实就是使用大的batch和subdivisions用于训练
紧接着使用ctrl+F搜索yolo(共三处
)
[convolutional]
size=1
stride=1
pad=1
filters=75
activation=linear
[yolo]
mask = 6,7,8
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=20
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
主要修改的地方有三处:classes
表示自己训练的标签类别数,filters
使用3×(classes+5)
计算得出,很多教程建议将random
修改为0,表示关闭多尺度训练,如果电脑性能足够的话不建议修改。(注意:有三出yolo需要按照以上方法修改)
接下来便可以进行训练了,但是为了达到刚好的效果作者建议打开darknet/examples目录下的detect.c
文件,并找到一下代码的位置
if(i%100==0){
#ifdef GPU
if(ngpus != 1) sync_nets(nets, ngpus, 0);
#endif
char buff[256];
sprintf(buff, "%s/%s.backup", backup_directory, base);
save_weights(net, buff);
}
if(i%10000==0 || (i < 1000 && i%100 == 0)){
#ifdef GPU
if(ngpus != 1) sync_nets(nets, ngpus, 0);
#endif
char buff[256];
sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i);
save_weights(net, buff);
}
以上代码用于控制训练生成的weights文件,细看代码能够发现,当训练次数少于1000次时,每100次输出一个weights文件,但是当训练次数大于1000次时每10000次输出一个weights。如果直接使用这个规则输出,想得到一个合适的weights文件得等到猴年马月咯!建议修改为:低于1000次每200次或500次输出一个weights文件,大于1000次每1000次输出一个weights文件。作者修改为了:
if(i%1000==0 || (i < 1000 && i%500 == 0))
在修改了任何源文件之后记得:在darknet的终端目录下输入:
make clean
make -j16
重新编译,以使修改的文件生效。
接下来便在darknet终端输入:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
开始训练自己的模型,记得使用的.data
文件和.cfg
文件要和自己修改的文件对应,不然就是一堆不知名的bug(作者就因为这个徘徊了很久)。
接下来便是漫长的等待…
在训练达到合理的次数后终止训练,在darknet终端输入:
./darknet detect cfg/yolov3-voc.cfg backup/yolov3-voc_4500.weights data/1.jpg
参数 | 含义 |
---|---|
cfg/yolov3-voc.cfg | 测试使用的配置文件,与训练使用的测试文件相同 |
backup/yolov3-voc_4500.weights | 测试使用的权重文件,训练生成位于backup目录下 |
data/1.jpg | 测试使用的测试图片,放置在data目录下 |
最后,便是观察测试效果的时候了:
以上便是使用darknet yolov3训练自己的voc数据集的完整操作。快去训练你自己的专属模型吧!
部分由于制作数据集的原始数据已上传,下载链接为:无人机航拍瓷瓶数据集-yoloV3训练数据集.zip。
由于本人水平有限,以上博客难免会有误差。如有问题请联系:QQ:2458707789 加好友请备注:yoloV3训练