建议:先将自己的标注数据转换为YOLO格式,并遵从代码默认设置进行模型训练。
若训练结果不佳,则可考虑基于以下几点进行改进。这有助于明确模型性能基准并确定需要改进的地方。

一、准备工作

  1. 标注的正确性。【v4】检查你的数据是否被标注,或者在使用第三方标注转换脚本/工具转换标注时出错(我之前在数据格式转换的时候忘记换行,利用-imgshow参数看到的训练数据无异常,但是模型效果非常差)。可用的工具https://github.com/AlexeyAB/Yolo_mark;【v5】训练数据中出现的所有类的实例都必须标记,只标记 部分实例会让模型感到困惑。

v4可以在训练时加-show_imgs参数查看进入网络训练的图片。这里的图像会直接显示或保存在当前目录下

  1. 标注的数量。【v4】每类训练数据最好大于2k,且包含各类可能存在的目标物品状态;【v5】了每类涵盖的图像至少要1.5k,且每类的实例[bbox]最好超过10k并涵盖部署中所有可能的环境。
  2. 标注风格。【v4】在标注时最好不好遮挡,但是至于标注的Bbox的松紧程度由你自己决定;【v5】标签必须紧密包围每个对象。对象与其边界框之间不应存在任何空间。
  3. 添加负例。【v4】在训练数据中添加你不想检测的未标注物体。主要做法:添加与正样本同样多的未标注图像,同时还需要在labels文件夹中添加相同名称的空白.txt文件;【v5】建议使用大约0-10%的背景数据来帮助减少FP(COCO提供1000张背景图片作为参考,占总数的1%)。
  4. 训练次数。【v4】训练2000*classes迭代或以上次数;【v5】训练次数和数据集以及模型大小都有关,对于自定义数据集建议用300个epoch,再根据训练效果(是否过拟合)进行训练次数的调整。
  5. 数据分布问题。【v4】训练集与测试集最好独立同分布object width in percent from Training dataset~=object width in percent from Test dataset,且训练数据中至少包含一个希望被检测到的对象。如果训练数据中仅存在占图像80~90%的大物体,那么训练出来的网络将没办法检测到占图像大小的1~10%的物体;【v5】如果训练时指定了—img 1280参数,那么 测试和评估时也应该指定同的参数。

YOLOv4/v5如何提高模型精度 - 图1

  1. 训练图像大小。高分辨率(32的倍数)有助于小物体的识别;多尺度图像输入也有助于模型精度的提升,这一点可以通过在v4的cfg文件中令random=1实现。
  2. batch大小。较大的batch可以更充分地利用GPU内存,并可以加快训练速度。
  3. 模型的选择。【v4】要检测的对象越多,场景越复杂,则应该使用越复杂的网络模型;【v5】诸如YOLOv5x之类的较大模型在几乎所有情况下都会产生(比小模型)更好的结果,但是参数更多且运行较慢。对于移动应用程序(mobile applications),建议使用YOLOv5s / m。对于云或桌面应用程序,建议使用YOLOv5l / x。有关所有型号的完整比较,请参见v5的readme_table

二、cfg文件中的超参数设置

2.1 YOLOv4

  1. 令random=1,则利用多尺度图像作为模型输入。有一定帮助
  2. 将输入图像分辨率增加可以提高模型精度,在检测中同样适用。
  3. 如果你希望在一张图像中检测大量目标,那就在cfg文件的yolo层或者region层的最后一行加上max=200(200也可以改为其他你希望检测到最大值的值)(YOLOv3可以检测到的目标全局最大数量为0,0615234375(widthheight)其中width和height是在cfg文件中的[net]部分指定的,这里其实说的是:网络只能检测到大于1/16的对象 )
  4. 若检测对象为小目标(将图像resize到416 416后,目标对象小于16 16),则需要修改cfg文件中的layers=23和stride=4(共三个位置)

它们分别在yolov4.cfg文件的895行、892和989行。

  1. 对于既包含小目标,又包含大物体的训练数据,推荐使用以下cfg文件进行训练:YOLOv4-custom
  2. 若要检测分左右的物体,就要下数据输入部分添加flip=0
  3. 为了让检测框更准,可以在每个yolo层添加ignore_thresh = 0.9 iou_normalizer=0.5 iou_loss=giou。这会提到map@.9但会降低map@.5
  4. 修改anchor:
    • 运行命令anchors:darknet.exe detector calc_anchors data/obj.data -num_of_clusters 9 -width 416 -height 416 可以得到将训练数据resize为416*416大小后的Bbox聚类尺寸
    • 在cfg文件的每层anchor中都放入上述代码的结果;
    • 同时修改每个[yolo]层的masks参数,让第一个[yolo]层的anchors尺寸大于60x60,第二个[yolo]层的anchors尺寸大于30x30,剩下就是第三个[yolo]层的mask。
      • 如果,计算出来的anchor都找不到合适的层,还是建议使用默认anchor。
  5. 另外,如果训练自己的模型时,还需要确认修改每个yolo层的filters=(classes + 5)x
  6. 如果想加速训练(以模型准确度为代价)可以将cfg文件中的stopbackward设为1.

2.2 YOLOv5
建议使用默认参数,有关超参数的优化方法请参见Hyperparameter Evolution Tutorial》
其他的神经网络训练思路请参见:http://karpathy.github.io/2019/04/25/recipe/

其他:yolov4与yolov5的一些实验性比较结果https://github.com/ultralytics/yolov5/issues/6

参考链接:

  1. https://github.com/AlexeyAB/darknet
  2. v4的模型特性和相关文件下载地址https://github.com/AlexeyAB/darknet/wiki/YOLOv4-model-zoo
  3. https://github.com/ultralytics/yolov5/wiki/Tips-for-Best-Training-Results