目录
前言
对YOLOv8手部检测模型进行训练,并分析训练结果,从而调优训练超参数。
手部检测数据集:基于YOLOv8的手部检测(1)- 手部数据集获取(数据集下载、数据清洗、处理与增强)
1.训练参数设置
1.1 data.yaml
这里没有控制每一轮的正负样本比和每一轮的长度,只加入额外负样本数,将一个epoch的训练数据量控制为36W张图片。因为原始训练集正样本有22W张,正负样本比接近3:2,已经算比较合理的范围了。
# path: /path/to/datasets
train: [""]
val: [""]
# Add negative image ----------------------------------------------------------
negative_setting:
neg_ratio: 0 # 小于等于0时,按原始官方配置训练,大于0时,控制正负样本。
use_extra_neg: True
extra_neg_sources: {"./datasets/hagrid/yolo_pose_neg/train/images": 42413,
# "./datasets/negative_dataset/neg_hand/train": 50000
}
fix_dataset_length: 0 # 是否自定义每轮参与训练的图片数量
# number of classes -----------------------------------------------------------
nc: 1
# Classes ---------------------------------------------------------------------
names:
0: hand
1.2 setting.yaml
override模型参数注意:需要把关闭马赛克增强置为0(close_mosaic: 0);将马赛克增强概率设置为0.9(mosaic: 0.9);开启多尺度会提高训练效果,但很消耗内存(multi_scale: True)。
# Train settings -------------------------------------------------------------------------------------------------------
task: detect # (str) YOLO task, i.e. detect, segment, classify, pose
mode: train # (str) YOLO mode, i.e. train, val, predict, export, track, benchmark
data: ./data.yaml # (str, optional) path to data file, i.e. coco8.yaml
epochs: 500 # (int) number of epochs to train for
batch: 80 # (int) number of images per batch (-1 for AutoBatch)
imgsz: 640 # (int | list) input images size as int for train and val modes, or list[w,h] for predict and export modes
patience: 300 # (int) epochs to wait for no observable improvement for early stopping of training
device: 4 # (int | str | list, optional) device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu
project: ./ # (str, optional) project name
name: # (str, optional) experiment name, results saved to 'project/name' directory
single_cls: True # (bool) train multi-class data as single-class
close_mosaic: 0 # (int) disable mosaic augmentation for final epochs (0 to disable)
multi_scale: True # (bool) Whether to use multiscale during training
# Hyperparameters ------------------------------------------------------------------------------------------------------
lr0: 0.01 # (float) initial learning rate (i.e. SGD=1E-2, Adam=1E-3)
lrf: 0.01 # (float) final learning rate (lr0 * lrf)
box: 8.0 # (float) box loss gain, default: 7.5
cls: 0.5 # (float) cls loss gain (scale with pixels), default: 0.5
dfl: 2.0 # (float) dfl loss gain, default: 1.5
degrees: 0.0 # (float) image rotation (+/- deg)
translate: 0.1 # (float) image translation (+/- fraction)
scale: 0.5 # (float) image scale (+/- gain)
fliplr: 0.5 # (float) image flip left-right (probability)
mosaic: 0.9 # (float) image mosaic (probability)
2.训练结果分析
2.1 HaGRID上训练结果的准确率分析
第一次训练使用55万张图训练(训练集+验证集用于训练,测试集用于验证)。
如下图,由于该数据集过于简单,训练1个epoch,目标框的准确率就到99%了(这里还是没有关闭马赛克增强进行训练的结果)。
所以,该验证结果意义不大,看着99%的准确率,实测效果可能会很差。
2.1 HaGRID上训练结果的LOSS分析
在HaGRID上训练,关闭马赛克增强,会导致“模型过拟合”。
如下图红色框内所示,在关闭马赛克增强后,每一项LOSS都迎来“断崖式”下跌。
因为马赛克增强的图片要比原始图片复杂的多。“马赛克”图片上的LOSS已经难以下降了,但简单图片上可以更容易预测,从而获得更低的LOSS。
但这又不是传统意义上的“过拟合”(训练集LOSS下降,验证集LOSS增加);模型只是更好拟合了原数据集,而我实测的数据集要比原数据集复杂很多。
所以,只用该数据数据集训练需要关闭马赛克增强,如果混合了其他复杂场景数据,则为了能按原场景进行训练,可以将马赛克增强的概率设置为0.9(默认是1.0)。
传统意义上的过拟合:
如下图红色框所示,在训练到200轮,就过拟合了,因为原始数据集只有2000张:
如下图所示,训练batch和验证batch(这里还加入旋转。实验证明,不需要加入,旋转还可能导致模型不收敛):
3.推理结果可视化分析
3.1 四宫格图片说明
训练模型均为:yolov8-m检测模型,使用HaGRID55万张图片训练的模型为M1;使用引言中36W张收集的图片训练的模型为M2。
第1行第1列,M1直接对整张图片预测。
第1行第2列,M2直接对整张图片预测。
第2行第1列,先预测出人,然后将人框的宽高放大5%,M1对放大后的框进行预测。
第2行第2列,先预测出人,然后将人框的宽高放大5%,M2对放大后的框进行预测。
3.2 HaGRID简单图片
下图是HaGRID的训练集中的(M1学习过,M2没学习过),二者结果差距不大(约1%),对于简单图片,先检测人再检测手,可以略微提高准确率(约1%)。
3.2 YOLO官图
下图也是较为简单的图片,M1在全图检测上,存在莫名奇妙误检。
下图相对复杂一些,直接检测M1只能识别最明显、张开的那只手。M2则可以全部识别出来,但误检了一个框(虽然置信度只有0.1)。而按人检测时,M1还是有一只手识别不出。
3.4 简单遮挡图片
全图检测M2可以识别被遮挡的左手,但是按人进行检测的时候却不行(猜测可能是缺乏了背景信息)。
3.4 多人多手图片
无论是直接还是按人进行识别,M2的效果显著要高于M1。下图也说明,一张图片按人识别手的时候,还需要对所有结果进行极大值抑制(两个人在视角上有接触,可能会导致同一只手被重复检测到)。
3.5 戴手套图片
M2对戴手套也可以识别:
3.6 非常规视角图片
M2在俯视视角上也可以识别(不过边缘处还是漏检了):
3.7 模糊图片
还是具有挑战性的,右上角女生没识别出。不过,这种模糊图片一般在前处理中,要做判断然后做预处理。
3.8 测试视频
video_plot_2024-08-13-20-16
4.结论
数据还是没白处理的,训练效果有明显提升。
HaGRID太简单,只适合简单任务,或者做个预训练。