yoloV4论文:《YOLOv4: Optimal Speed and Accuracy of Object Detection》 yoloV4 Github代码:https://github.com/AlexeyAB/darknet yoloV1~V3 Github代码:https://github.com/pjreddie/darknet darknet官网:https://pjreddie.com/darknet/
可以从指定链接或百度网盘下载: (1)yoloV4.weights(245MB): https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights https://pan.baidu.com/s/1pIGTyXrp1Py10DwSLtsPnw (提取码:g9b2) (2)yoloV4预训练权重:yolov4.conv.137 https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137 https://pan.baidu.com/s/1PIDlAtOEKYGN1YQ4lFBFlg (提取码:cs4k) (3)yolov4-tiny.weights(23.1MB): https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights https://pan.baidu.com/s/1rS3DIlARFCiqId0TmN1XYg (提取码:16ln)
(4)tiny yoloV4预训练权重:yolov4-tiny.conv.29: https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.conv.29 https://pan.baidu.com/s/16b7GpOU50B2YkjriVQl1UQ (提取码:xbqc)
下载darknet:
git clone https://github.com/AlexeyAB/darknet.git编译有两种方式Makefile和Cmake(推荐make),Makefile配置项及解释如下: 其中,GPU和CUDNN是GPU加速,CUDNN_HALF是特定硬件加速,OPENCV是否使用OpenCV,AVX和OPENMP是CPU加速
cd darknet make 或者 make -j8(加速编译)数据按照VOC或者COCO数据集的格式准备,以VOC格式示例(也可以自定义格式,直接生成label,后续加):
----VOCdevkit\ |----VOC2020\ # 目录 | |----Annotations\ | | |----00000001.xml # 图片标注信息 | |----ImageSets\ | | |----Main\ # 训练:验证:测试=1:1:2 | | | |----test.txt # 测试集 | | | |----train.txt # 训练集 | | | |----val.txt # 验证集 | |----JPEGImages\ | | |----00000001.jpg # 对应图片复制/darknet/scripts/VOC_label.py与VOCdevkit文件夹并列,修改VOC_label.py并运行
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join sets=[('2020', 'train'), ('2020', 'val'), ('2020', 'test')] # **对应VOC2020和Main下面的数据集** classes = ["car", "bus", "motor"] # **训练类别信息** def convert(size, box): dw = 1./(size[0]) dh = 1./(size[1]) x = (box[0] + box[1])/2.0 - 1 y = (box[2] + box[3])/2.0 - 1 w = box[1] - box[0] h = box[3] - box[2] x = x*dw w = w*dw y = y*dh h = h*dh return (x,y,w,h) def convert_annotation(year, image_id): in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id)) out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w') tree=ET.parse(in_file) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) for obj in root.iter('object'): difficult = obj.find('difficult').text cls = obj.find('name').text if cls not in classes or int(difficult)==1: continue cls_id = classes.index(cls) xmlbox = obj.find('bndbox') b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) bb = convert((w,h), b) out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') wd = getcwd() for year, image_set in sets: if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)): os.makedirs('VOCdevkit/VOC%s/labels/'%(year)) image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split() list_file = open('%s_%s.txt'%(year, image_set), 'w') for image_id in image_ids: list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id)) convert_annotation(year, image_id) list_file.close() os.system("cat 2020_train.txt 2020_val.txt > train.txt")生成yolo训练数据格式如下:
----train_data\ |----2020_test.txt |----2020_train.txt |----2020_val.txt |----train.txt |----VOCdevkit\ | |----VOC2020\ | | |----Annotations\ | | | |----00000001.xml | | |----ImageSets\ | | | |----Main\ | | | | |----test.txt | | | | |----train.txt | | | | |----val.txt | | |----JPEGImages\ | | | |----00000001.jpg | | |----labels\ | | | |----00000001.txt |----voc_label.py[net]层要改batch,[yolo]层要改classes,[convolutional]要改filters (t配置文件搜yolo,tiny改两处,V4改三处)
[net] # Testing #测试模式,测试时开启 #batch=1 # #subdivisions=1 # # Training #训练模式,训练时开启,测试时注释 **batch=256** # 每批数量,根据配置设置,如果内存小,改小batch和subdivisions, batch和subdivisions越大,效果越好 **subdivisions=16** # width=416 height=416 channels=3 # 输入图像width height channels 长宽设置为32的倍数,因为下采样参数是32,最小320*320 最大608*608 momentum=0.9 # 动量参数,影响梯度下降速度 decay=0.0005 # 权重衰减正则项,防止过拟合 angle=0 # 旋转 saturation = 1.5 # 饱和度扩增 exposure = 1.5 # 曝光度 hue=.1 # 色调 learning_rate=0.00261 # 学习率,权值更新速度 burn_in=1000 # 迭代次数小于burn_in,学习率更新;大于burn_in,采用policy更新 max_batches = 500200 # 训练达到max_batches停止 policy=steps # 学习率调整策略policy:constant, steps, exp, poly, step, sig, RANDOM steps=400000,450000 # 步长 scales=.1,.1 # 学习率变化比例 [convolutional] batch_normalize=1 filters=32 size=3 stride=2 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=64 size=3 stride=2 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=64 size=3 stride=1 pad=1 activation=leaky [route] layers=-1 groups=2 group_id=1 [convolutional] batch_normalize=1 filters=32 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=32 size=3 stride=1 pad=1 activation=leaky [route] layers = -1,-2 [convolutional] batch_normalize=1 filters=64 size=1 stride=1 pad=1 activation=leaky [route] layers = -6,-1 [maxpool] size=2 stride=2 [convolutional] batch_normalize=1 filters=128 size=3 stride=1 pad=1 activation=leaky [route] layers=-1 groups=2 group_id=1 [convolutional] batch_normalize=1 filters=64 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=64 size=3 stride=1 pad=1 activation=leaky [route] layers = -1,-2 [convolutional] batch_normalize=1 filters=128 size=1 stride=1 pad=1 activation=leaky [route] layers = -6,-1 [maxpool] size=2 stride=2 [convolutional] batch_normalize=1 filters=256 size=3 stride=1 pad=1 activation=leaky [route] layers=-1 groups=2 group_id=1 [convolutional] batch_normalize=1 filters=128 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=128 size=3 stride=1 pad=1 activation=leaky [route] layers = -1,-2 [convolutional] batch_normalize=1 filters=256 size=1 stride=1 pad=1 activation=leaky [route] layers = -6,-1 [maxpool] size=2 stride=2 [convolutional] batch_normalize=1 filters=512 size=3 stride=1 pad=1 activation=leaky ################################## [convolutional] batch_normalize=1 filters=256 size=1 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=512 size=3 stride=1 pad=1 activation=leaky [convolutional] size=1 stride=1 pad=1 **filters=24** # 3*(classes+5) activation=linear [yolo] mask = 3,4,5 anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 **classes=3** # 类别数,修改为实际需要数量 num=6 jitter=.3 scale_x_y = 1.05 cls_normalizer=1.0 iou_normalizer=0.07 iou_loss=ciou ignore_thresh = .7 truth_thresh = 1 random=0 resize=1.5 nms_kind=greedynms beta_nms=0.6 [route] layers = -4 [convolutional] batch_normalize=1 filters=128 size=1 stride=1 pad=1 activation=leaky [upsample] stride=2 [route] layers = -1, 23 [convolutional] batch_normalize=1 filters=256 size=3 stride=1 pad=1 activation=leaky [convolutional] size=1 stride=1 pad=1 **filters=24** # 3*(5+classes) activation=linear [yolo] mask = 1,2,3 anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 #预测框的初始宽高,第一个是w,第二个是h,总数量是num*2 **classes=3** # 类别数,修改为实际需要数量 num=6 # 每个grid预测的BoundingBox个数 jitter=.3 # # 利用数据抖动产生更多数据抑制过拟合.YOLOv2中使用的是crop,filp,以及net层的angle,flip是随机的,crop就是jitter的参数,tiny-yolo-voc.cfg中jitter=.2,就是在0~0.2中进行crop scale_x_y = 1.05 cls_normalizer=1.0 iou_normalizer=0.07 iou_loss=ciou ignore_thresh = .7 # # 决定是否需要计算IOU误差的参数,大于thresh,IOU误差不会夹在cost function中 truth_thresh = 1 random=0 # 如果为1每次迭代图片大小随机从320到608,步长为32,如果为0,每次训练大小与输入大小一致 resize=1.5 nms_kind=greedynms beta_nms=0.6可以根据需求设置不同的flag
(0,1, 指GPU索引,可以nvidia-smi查看)
./darknet detector train data\voc.data cfg\yolov4.cfg yolov4.conv.137 -gpus 0,1(GPU 0) ./darknet detector train data\voc.data cfg\yolov4.cfg yolov4.conv.137 -gpus 0
./darknet detector train data\voc.data cfg\yolov4.cfg yolov4.conv.137 -gpus 0类别平均精度,每4个epoch会算一次(Epoch = images_in_train_txt / batch)
./darknet detector train cfg/voc.data cfg/yolov4-tiny.cfg backup/yolov4-tiny_99000.weights -gpus 0,1 -map一般最好训练(类别数2000)迭代次数,停止标志: (1)当看到平均loss0.XXXXXXX avg**不下降时,平均loss小于 0.05 (小模型简单数据集) to 3.0 (大模型复杂数据集). (2)如果训练时加上 -map 控制台上mAp提示比loss下降更好,当精度不再上升时停止
训练结束后,/darknet/backup文件夹下有很多权重文件,如何知道哪个模型是最优模型 ./data/VOC.data有验证集路径,分别测试不同权重在验证集上测试效果
./darknet detector map data/VOC.data yolo-obj.cfg backup\yolo-obj_6000.weights比较最后一行,选mAP (mean average precision) 最大的 ,或者IoU(intersect over union)最好的
darknet文件夹也有darknet.py和darknet_video.py示例 不过都是输入路径,如果想读取图片输入接口,后续加。