参考https://pjreddie.com/darknet/yolo/网站介绍,下载VOC数据。
wget https://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar
wget https://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar
wget https://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar
tar xf VOCtrainval_11-May-2012.tar
tar xf VOCtrainval_06-Nov-2007.tar
tar xf VOCtest_06-Nov-2007.tar
将VOC数据集的xml文件里的标注转为darknet能够解析的txt文件,每个文件的格式如下:
每行中分别对应目标的类别,ground truth框的横坐标中心坐标,纵坐标中心坐标,groundtruth框的宽度和groundtruth框的高度。
使用scripts/
文件夹下的voc_label.py
文件可以将VOC标签转为YOLO标签,将voc_label.py
文件拷到VOCdevkit/
文件夹下,运行以下命令:
python voc_label.py
完成运行后,输入ls
,可以在终端中看到以下内容:
2007_test.txt VOCdevkit
2007_train.txt voc_label.py
2007_val.txt VOCtest_06-Nov-2007.tar
2012_train.txt VOCtrainval_06-Nov-2007.tar
2012_val.txt VOCtrainval_11-May-2012.tar
VOC训练需要将2007_train,2007_val,2012_train,2012_val四个数据集合并形成训练集,使用2007_test作为验证集。输入以下命令,将相应的数据集合并。
cat 2007_train.txt 2007_val.txt 2012_*.txt > train.txt
最后修改cfg.data
文件,配置VOC数据路径,classes数目必须要写对。
classes= 20
train = /train.txt
valid = 2007_test.txt
names = data/voc.names
backup = backup
1. 基于ImageNet预训练模型开始训练
预训练模型下载位置在https://drive.google.com/open?id=1JKF-bdIklxOOVy-2Cr5qdvjgGpmGfcbp,完成预训练模型下载后,将yolov4.conv.137
文件放在指定位置。
2. 基于COCO预训练模型开始训练
如果基于作者开源的COCO预训练模型yolov4.weights
开始训练,则需要对文件中的seen进行修改,修改之后才能基于该预训练模型进行训练,修改代码如下。
import numpy as np
# Read weights file
with open('weights/yolov4.weights', 'rb') as f:
version = np.fromfile(f, dtype=np.int32, count=3) # (int32) version info: major, minor, revision
seen = np.fromfile(f, dtype=np.int64, count=1) # (int64) number of images seen during training
weights = np.fromfile(f, dtype=np.float32) # the rest are weights
seen = np.array([0])
# Write weights file
with open('darknet_yolov4.weights', 'wb') as f:
version.tofile(f) # (int32) version info: major, minor, revision
seen.tofile(f)
weights.tofile(f)
修改cfg文件夹下的yolov4-custom.cfg文件名称为yolov4-voc.cfg
,修改训练迭代步数:
max_batches = 50500
policy=steps
steps=40000,45000
scales=.1,.1
将3个yolo层的classes的类别修改为20,yolo层前的convolutional层的filters数目为75, ( c l a s s e s + 5 ) × 3 (classes + 5) \times 3 (classes+5)×3。
[convolutional]
size=1
stride=1
pad=1
filters=75
activation=linear
[yolo]
mask = 6,7,8
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=20
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
scale_x_y = 1.05
iou_thresh=0.213
cls_normalizer=1.0
iou_normalizer=0.07
iou_loss=ciou
nms_kind=greedynms
beta_nms=0.6
在终端中输入touch train.sh
和gedit train.sh
,编辑训练脚本文件,输入./darknet detector train data/voc.data cfg/yolov4-voc.cfg backup/yolov4.conv.137 -map
,执行./train.sh
即可开始训练。./darknet
为编译好的可执行文件,detector
表示执行目标检测任务,train
表示执行训练任务,data/voc.data
,cfg/yolov4-voc.cfg
和backup/yolov4.conv.137
文件路径位置必须正确,-map
表示可以在训练的同时,进行检测精度评估,每4个epoch评估一次。
完成训练后,在darknet文件夹中可以得到以下图片,图片显示训练存在过拟合情况,在迭代到10000多步时,在VOC数据集上的mAP达到了最高,之后虽然Loss一直在下降,但是mAP没有再提高,反而有所下降,在VOC数据集上的训练还需要进一步调参。经过voc_all_map.py的评估,YOLOv4在VOC数据集上的0.5:0.95mAP能够达到52.98,0.5mAP能够达到84.27,0.75mAP能够达到58.64。这个结果,比这篇文章介绍的https://blog.csdn.net/linghu8812/article/details/105708001faster_rcnn_R_50_FPN的mAP提高了不少。
下图是使用YOLOv3在VOC数据集上训练的结果,可以看到,在VOC数据集上YOLOv4的检测效果比YOLOv3提高了不少。
在终端中输入以下命令./darknet detector test cfg/voc.data cfg/yolov4-voc.cfg backup/yolov4-voc.weights -thresh 0.25 data/dog.jpg
可以对单张图片进行测试,查看训练效果。cfg文件和weights文件可以在这里下载,提取码为ia4x。inference结果如下:
终端中输出的结果如下:
data/dog.jpg: Predicted in 14.562000 milli-seconds.
bicycle: 97%
dog: 94%
car: 99%