使用Darknet训练yolo模型
本文将通过训练一个人形检测模型来描述使用Darknet训练yolo模型的过程。
文章目录
图像标注
1.图像标注工具labelImg安装方法:
https://www.cnblogs.com/new-age/p/7071289.html
2.labelImg的使用:
注:labelImg有两种输出方式,这里可以在左侧栏中选择yolo的txt格式输出,也可以使用xml输出再通过darknet包中的代码将xml格式转为txt。
标注快捷键:
W :创建矩形窗
Ctrl + S :保存
A :上一张
D :下一张
图像分类保存
1.在标注完成后,将制作好的数据集数据集文件夹内,其文件夹构成如图:
其中,JPEGImages里是你的所有图片,Annotation里是与你的图片一一对应的XML标注文件,若生成的为txt标注文件,则在voc2007文件夹下新建labels文件夹,并将标注文件放入其中。(如果某个图不包含物体,请在标注时随便圈一下再删除,随后保存,否则不会生成XML,会报错!)
2.接下来,在Main里创建一个训练与测试列表。在VOC2007文件夹内创建一个split.py,将下列代码复制进去:
import os
import random
# 训练集和测试比例分配
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations' # xml 位置
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
接着,命令行执行该文件
$ python split.py
执行后你应该能在Main里看到4个文件,里面分别存储了被作为四类数据的文件的名称。
使用darknet训练模型
1.下载darknet
git clone https://github.com/pjreddie/darknet
cd darknet
make
2.数据格式转换:
(1)将xml文件转换为txt文件
在darknet/scripts文件夹下有一个文件voc_label就是干这个用的。
将该文件复制至darknet文件夹内,然后修改该文件:
sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
classes = ["person"]
#最后两行删除。
#os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
#os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")
(2)若标注就是txt文件
修改voc_label.py
将该文件复制至darknet文件夹内,然后修改该文件:
sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
classes = ["person"]
#最后两行删除。
#os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
#os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")
运行voc_label.py文件:python3 voc_label.py
3.文件配置:
(1)voc.names
创建修改新的data/voc.name,里面放检测类别的名称。
(2)cfg / yolov3-tiny.cfg
创建修改新的cfg / yolov3-tiny.cfg最上面部分,注释掉test对应部分,使用train部分。这里batch指每次读取了多少张图片,subdivisions是指将数据分为多少份输入,例如batch=64,subdivisions=16则是每次输入64/16=4张图同时训练,最后64张图的所有结果视为一个batch,共同优化。这里需要根据GPU显存自行调整。(想提高训练速度的话,应该是提高cfg中的batch值,并适当较少subdivision,这样net->batch=batch / subdivision适当变大,意味着每次参加训练的图片数目增加)
修改[yolo]层中 classes 个数 ,以及[yolo]层上面的[convolutuonal]层中的filters的个数 filters = 3 * (classes +5).共有两处需要修改:
(3)创建修改新的cfg/voc.data
classes = 1
train = /.../.../2007_train.txt
valid = /.../.../2007_test.txt
names = data/voc.names
backup = backup
(4)修改权重存储频率
Darknet 在模型训练中,保存的weights,1000以内每过100 保存一次,1000以后每10000保存一次。一般来说前面的weights效果都不好,因此可以改成每2000次保存一次。
修改: /darknet/examples/detector.c
修改darknet/makefile文件:
NVCC=/usr/local/cuda-10.0/bin/nvcc
命令:make
sudo install /home/huadian/darknetnew/libdarknet.a /home/huadian/darknetnew/libdarknet.so /usr/local/lib
4.开始训练
使用yolov3-tiny训练模型时,需要加载预训练模型,而官网没给tiny版的预训练模型,可以在原yolov3-tiny.weights上得到,只需如下指令。参考https://blog.csdn.net/chengyq116/article/details/83213699
生成 yolov3-tiny.conv.15
./darknet partial ./cfg/yolov3-tiny.cfg ./yolov3-tiny.weights ./yolov3-tiny.conv.15 15
训练命令:
./darknet detector train cfg/voc_person2.0.data cfg/yolov3-tiny.cfg yolov3-tiny.conv.15
随着训练过程进行,IOU应当会越来越高。训练好的模型会被存储在darknet/backup中,名字如yolov3-voc_900.weights,这里的数字是执行epoch的数目。
5.测试
修改cfg文件为测试模式:
测试命令:
./darknet detect cfg路径 weights路径 图片路径