建议:先将自己的标注数据转换为YOLO格式,并遵从代码默认设置进行模型训练。
若训练结果不佳,则可考虑基于以下几点进行改进。这有助于明确模型性能基准并确定需要改进的地方。
一、准备工作
- 标注的正确性。【v4】检查你的数据是否被标注,或者在使用第三方标注转换脚本/工具转换标注时出错(我之前在数据格式转换的时候忘记换行,利用
-imgshow
参数看到的训练数据无异常,但是模型效果非常差)。可用的工具https://github.com/AlexeyAB/Yolo_mark;【v5】训练数据中出现的所有类的实例都必须标记,只标记 部分实例会让模型感到困惑。
v4可以在训练时加-show_imgs参数查看进入网络训练的图片。这里的图像会直接显示或保存在当前目录下
- 标注的数量。【v4】每类训练数据最好大于2k,且包含各类可能存在的目标物品状态;【v5】了每类涵盖的图像至少要1.5k,且每类的实例[bbox]最好超过10k并涵盖部署中所有可能的环境。
- 标注风格。【v4】在标注时最好不好遮挡,但是至于标注的Bbox的松紧程度由你自己决定;【v5】标签必须紧密包围每个对象。对象与其边界框之间不应存在任何空间。
- 添加负例。【v4】在训练数据中添加你不想检测的未标注物体。主要做法:添加与正样本同样多的未标注图像,同时还需要在labels文件夹中添加相同名称的空白.txt文件;【v5】建议使用大约0-10%的背景数据来帮助减少FP(COCO提供1000张背景图片作为参考,占总数的1%)。
- 训练次数。【v4】训练2000*classes迭代或以上次数;【v5】训练次数和数据集以及模型大小都有关,对于自定义数据集建议用300个epoch,再根据训练效果(是否过拟合)进行训练次数的调整。
- 数据分布问题。【v4】训练集与测试集最好独立同分布
object width in percent from Training dataset~=object width in percent from Test dataset
,且训练数据中至少包含一个希望被检测到的对象。如果训练数据中仅存在占图像80~90%的大物体,那么训练出来的网络将没办法检测到占图像大小的1~10%的物体;【v5】如果训练时指定了—img 1280参数,那么 测试和评估时也应该指定同的参数。
- 训练图像大小。高分辨率(32的倍数)有助于小物体的识别;多尺度图像输入也有助于模型精度的提升,这一点可以通过在v4的cfg文件中令random=1实现。
- batch大小。较大的batch可以更充分地利用GPU内存,并可以加快训练速度。
- 模型的选择。【v4】要检测的对象越多,场景越复杂,则应该使用越复杂的网络模型;【v5】诸如YOLOv5x之类的较大模型在几乎所有情况下都会产生(比小模型)更好的结果,但是参数更多且运行较慢。对于移动应用程序(mobile applications),建议使用YOLOv5s / m。对于云或桌面应用程序,建议使用YOLOv5l / x。有关所有型号的完整比较,请参见v5的readme_table。
二、cfg文件中的超参数设置
2.1 YOLOv4
- 令random=1,则利用多尺度图像作为模型输入。有一定帮助
- 将输入图像分辨率增加可以提高模型精度,在检测中同样适用。
- 如果你希望在一张图像中检测大量目标,那就在cfg文件的yolo层或者region层的最后一行加上max=200(200也可以改为其他你希望检测到最大值的值)(YOLOv3可以检测到的目标全局最大数量为0,0615234375(widthheight)其中width和height是在cfg文件中的[net]部分指定的,这里其实说的是:网络只能检测到大于1/16的对象 )
- 若检测对象为小目标(将图像resize到416 416后,目标对象小于16 16),则需要修改cfg文件中的layers=23和stride=4(共三个位置)
它们分别在yolov4.cfg文件的895行、892和989行。
- 对于既包含小目标,又包含大物体的训练数据,推荐使用以下cfg文件进行训练:YOLOv4-custom
- 若要检测分左右的物体,就要下数据输入部分添加flip=0
- 为了让检测框更准,可以在每个yolo层添加ignore_thresh = 0.9 iou_normalizer=0.5 iou_loss=giou。这会提到map@.9但会降低map@.5
- 修改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。
- 另外,如果训练自己的模型时,还需要确认修改每个yolo层的filters=(classes + 5)x
- 如果想加速训练(以模型准确度为代价)可以将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
参考链接: