尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

YOLOv5行人跌倒检测数据集实战:从目录解析到训练调优

YOLOv5行人跌倒检测数据集实战:从目录解析到训练调优 简介面向行人跌倒检测的YOLOv5目录格式数据集包含person、fall等5个类别图像为800×800 RGB图片无需额外处理即可接入YOLOv5训练流程适合目标检测初学者快速上手行人姿态与跌倒识别项目。压缩包共2000个文件其中1999个txt为图片标签与类别信息另1个py为可视化脚本整体大小438.48MB训练集7609张图片与对应标签、验证集1902张图片与标签均按datasets-images-train和datasets-images-val目录整理txt标签可直接用于YOLO系列模型训练。包内附带可视化py脚本随机传入一张图片即可自动绘制边界框并保存到当前目录无需修改配置即可运行方便对标注质量进行即时检查。目前已有404人学习/下载适合需要标准数据集快速完成跌倒检测方案验证或开展相关课程设计的研究者与开发者。1. 目标检测数据集行人跌倒的 YOLOv5 目录格式为什么值得先拆一遍做目标检测的同行估计都有过这种经历模型和训练环境都备好了数据集一上来就卡住尤其是行人跌倒这种对标注格式和类别边界敏感的任务。这个 YOLOv5 目录格式的行人跌倒检测数据集把最磨人的预处理省掉了。它按 YOLOv5 官方目录约定组织5 个类别覆盖跌倒前后的主要行人姿态train/val 已划分标注是标准 txt 格式拿过来改完 data.yaml 就能直接开训。适合正在做监控场景跌倒识别、或者项目/毕设需要现成数据集快速验证效果的从业者。下面我把目录结构、训练参数和踩过的坑完整过一遍。2. 目录结构与 5 类标注先看懂标签约定再谈训练效果2.1 YOLOv5 目录格式的约定images/labels 与 train/val 怎么对应YOLOv5 的官方数据加载逻辑写得很死训练时你只需要在 data.yaml 里给一个图片路径它会自动把路径中的images替换成labels去找同名 txt。所以目录层级、文件命名一致性、标签目录必须叫labels这三样东西任何一个不对训练都会在数据加载阶段出问题而且这类错误往往是以静默跳过图片的方式存在日志里只有一个不显眼的 WARNING。标准结构长这样fall_dataset/ ├── images/ │ ├── train/ # 训练图片建议统一为 *.jpg │ └── val/ # 验证图片*.jpg ├── labels/ │ ├── train/ # 与图片一一对应的标注*.txt │ └── val/ └── fall.yaml # 训练入口配置这套数据集的切分是常见的 8:2train 和 val 各占一个目录没有单独建 test。如果你习惯留独立测试集做最终评估可以从 train 里再匀出一部分这个后面细说。每张图对应的 txt 里每一行代表一个目标框格式是五个字段class_id x_center y_center width height四个坐标值全部做了归一化范围在 0 到 1 之间除以的是图片本身的宽和高。拿第一行举例4 0.6234 0.5120 0.2105 0.4123逻辑说明第一个数字 4 是类别 id对应 data.yaml 里 names 列表下标为 4 的类后面四个数字依次是框中心点的 x、y以及框的宽、高全部是归一化后的比例。训练时 YOLOv5 会按原图分辨率还原成像素框所以只要比例算对图片原始尺寸是 640 还是 1920 都不影响。参数说明这里最容易出问题的就是归一化。如果你从 LabelImg 或 CVAT 导出的是绝对像素坐标直接粘贴进 txt 是不行的必须先除以图片宽高再写入。另外这套目录格式和 YOLOv8、RT-DETR 的约定基本一致以后换框架只需要改 data.yaml 里 path 的写法标签文件可以原样复用。2.2 5 个类别怎么定义跌倒检测里最容易混的三种姿态这版数据集把 5 个类别定义为跌倒检测里最常用的划分方式覆盖一个人从正常活动到倒地全过程的主要姿态class_id类别名典型姿态标注要点0standing站立、原地停留完整身体框头顶到脚底不切肢体1walking行走、小跑框整个身体允许短时遮挡2sitting坐在椅子/地面/台阶包含臀部和躯干不要只框上半身3bending弯腰、蹲下、拾物躯干明显前倾框高度被压缩4fallen跌倒、倒地、躺卧身体主轴水平框宽度大于高度这个类别顺序不是随意的data.yaml 里的 names 列表顺序必须和 txt 里的 class_id 一一对应。顺序错了模型会把跌倒当站立学结果就是训练指标一切正常、实际推理全错这是这类数据集最隐蔽的翻车点。多讲几句边界情况。最容易混的是 bending 和 fallen蹲下捡东西时人体高度压缩到站立时的一半以下框的宽高比接近 1而真正跌倒的人躯干是水平的框通常是宽大于高。标注经验上以人体主轴相对地面的角度为判据——主轴与地面夹角小于 30 度且持续贴地标 fallen夹角 30 到 60 度、姿态不稳定标 bending。sitting 和 fallen 也有混淆场景人瘫坐在墙角时躯干后倾、臀部着地很容易被标成 fallen。区分原则看大腿与躯干的夹角sitting 通常躯干直立、大腿水平fallen 是躯干与大腿都接近水平。这套数据集在整理时就按这个原则把边界样本重标过一轮但拿到手后你还是应该随机抽 50 张图看一遍标注建立视觉直觉再开训比对着指标猜强得多。2.3 校验脚本30 行代码排查数据集的硬伤拿到任何 YOLOv5 格式数据集我习惯先跑一段校验脚本把图片和标签对不上、坐标越界、类别 id 超范围这三类硬伤一次性暴露出来。这比训练到一半再回头查快得多。# check_dataset.py from pathlib import Path def check_split(split: str, num_classes: int 5, ext: str jpg): img_dir Path(fimages/{split}) lbl_dir Path(flabels/{split}) imgs {p.stem for p in img_dir.glob(f*.{ext})} lbls {p.stem for p in lbl_dir.glob(*.txt)} # 1. 图片与标签一一对应 missing imgs - lbls orphan lbls - imgs print(f[{split}] images{len(imgs)} labels{len(lbls)}) print(f 缺标签的图片: {list(missing)[:5]}) print(f 无图片的标签: {list(orphan)[:5]}) # 2. 逐行检查标注内容 bad_boxes 0 class_cnt {i: 0 for i in range(num_classes)} for txt in lbl_dir.glob(*.txt): for line in txt.read_text().strip().splitlines(): parts line.strip().split() if len(parts) ! 5: bad_boxes 1 continue cid int(parts[0]) xc, yc, w, h map(float, parts[1:]) if cid 0 or cid num_classes: bad_boxes 1 if not (0 xc 1 and 0 yc 1 and 0 w 1 and 0 h 1): bad_boxes 1 if cid in class_cnt: class_cnt[cid] 1 print(f 异常标注行数: {bad_boxes}) print(f 各类别框数量: {class_cnt}) if __name__ __main__: check_split(train) check_split(val)逻辑说明第一步把 images 和 labels 两个目录里的文件名不含后缀各取成一个集合做差集就能直接找出有图没标签和有标签没图的文件第二步逐行解析 txt检查字段数量是否为 5、类别 id 是否落在[0, num_classes)内、四个坐标是否都在 0 到 1 之间同时顺手统计每个类别的框数量为后面处理类别不平衡提供依据。参数说明num_classes默认 5增删类别时改这个值ext默认jpg如果数据集里有 png改成png即可。任何一项输出不为 0都建议先处理完再开训练否则这些脏数据会在训练中变成奇怪的 loss 波动或类别错学。提示校验脚本只做语法层面的检查标注框是否贴目标、类别是否标错这种语义错误它看不出来。语义问题要靠抽图可视化后面章节会给出具体办法。3. data.yaml 与训练配置把数据集跑进 YOLOv5 的关键参数3.1 data.yaml 的正确写法路径指向哪一层很关键YOLOv5 训练入口只需要一个 data.yaml写法和常见误区一起说# fall.yaml train: /home/user/fall_dataset/images/train val: /home/user/fall_dataset/images/val # test: /home/user/fall_dataset/images/test # 可选 nc: 5 names: 0: standing 1: walking 2: sitting 3: bending 4: fallen逻辑说明train 和 val 填的是 images 子目录的绝对路径不是数据集根目录。YOLOv5 拿到路径后执行str(path).replace(images, labels)去找对应标签所以标签目录必须叫 labels不能叫 annotations、label 或别的名字否则这些图片会被静默跳过训练集实际数量远少于预期。参数说明names 这块有两个注意点。第一列表顺序必须和 2.2 节的 class_id 一一对应这是全流程最容易翻车的地方第二nc必须等于 names 的长度。用names: [standing, walking, ...]这种列表写法 YOLOv5 会自动推断 nc但显式写出来更稳排查时不至于两头猜。关于路径我踩过一个典型坑在 Windows 上写C:\Users\...这种反斜杠路径YAML 解析会把\U、\t当成转义字符轻则路径不对重则直接报 found unknown escape character。常见做法是统一用正斜杠/或者用原始字符串拼接。路径里尽量别带中文和空格YOLOv5 底层调一些工具时中文路径偶尔会触发编码问题这种问题排查成本极高不如一开始就规避。3.2 训练命令与核心参数从 yolov5s 起步的合理配置确认数据集没问题之后我用的训练命令是python train.py \ --data fall.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 150 \ --patience 30 \ --project runs/fall \ --name exp1 \ --exist-ok逻辑说明--weights指定预训练权重yolov5s.pt 是在 COCO 80 类上训好的模型。YOLOv5 检测到nc5和权重头不匹配时会自动把检测头重新初始化只保留 backbone 的预训练参数不需要你手动裁剪最后一层这是它和很多老框架不同的地方。如果你不用预训练权重直接--weights 从零训跌倒检测这种小数据集通常收敛慢、精度低不建议。参数说明--img 640是输入分辨率监控画面通常是 1080p 甚至更高但训练统一缩放到 640 能大幅降低显存占用。跌倒检测的目标在中近距离640 一般够用小目标多再上 960。--batch 16和显存强相关8G 显存用 816G 显存用 16显存不足会直接 OOM。--patience 30表示验证集 mAP 连续 30 个 epoch 不提升就提前停止避免无效空转。epochs 给 150 是考虑了数据集规模。YOLOv5 的官方经验是数据集每 1000 张图约需 50 个 epoch 收敛跌倒检测数据总量如果在 5000 张以下150 个 epoch 配合 early stop实际在 40 到 90 个 epoch 就能收到最优权重。只想验证流程通不通可以先用--epochs 10跑一遍 smoke test确认数据加载和 loss 下降正常再跑完整训练这个习惯能省下大量排错时间。3.3 预训练权重与 anchors按显存和精度需求选型号YOLOv5 给了一套从 n 到 x 的模型家族跌倒检测这种场景我一般只在 n、s、m 里选模型参数量8G 显存参考 batch推理速度适用场景yolov5n约 1.9M32最快边缘设备、实时性优先yolov5s约 7.2M16快常规监控性价比最高yolov5m约 21.2M8中等小目标多、精度优先表里的 batch 是 640 输入下的参考值实际以你自己的显存为准。anchors 这块多说一句。YOLOv5 默认会在训练开始前从你的训练集自动聚类生成 anchorsautoanchor不需要手动指定。但跌倒检测有个特殊性fallen 类的框几乎都是宽大于高的横框和常规行人竖框的比例差异大。如果标签框比例分布和 COCO 差太多开训后看日志里 Autoanchor: 4.86 anchors/target, 0.999 Best Possible Recall 这行BPR 接近 1 说明 anchors 适配没问题如果 BPR 低于 0.95常见做法是删掉预训练权重里缓存的历史 anchors让模型重新聚类。注意第二次训练时把--weights换成自己上一次训出的 best.pt 继续 fine-tune比每次都从 COCO 权重开始更稳尤其是跌倒姿态这种和通用目标差异较大的类别迁移收益很明显。4. 跌倒检测的针对性调优把 fallen 类别从带不动救回来4.1 增强策略哪些内置增强对跌倒姿态有效YOLOv5 的默认超参文件 hyp.scratch-low.yaml 里已经开了不少增强对跌倒检测来说有几个值得单独调# hyp.scratch-low.yaml 关键增强项按数据集调整 hsv_h: 0.015 # 色相抖动幅度 hsv_s: 0.7 # 饱和度抖动幅度 hsv_v: 0.4 # 明度抖动幅度 degrees: 10.0 # 旋转角度上限单位度 translate: 0.1 # 平移比例 scale: 0.5 # 缩放比例 fliplr: 0.5 # 水平翻转概率 mosaic: 1.0 # mosaic 增强开关 mixup: 0.0 # mixup 增强开关逻辑说明跌倒场景里摄像头视角、室内外光线变化都很大hsv 三项是给监控场景准备的增强能显著提升泛化fliplr 对 fallen 类尤其有效——一个人向左倒和向右倒在几何上是镜像关系水平翻转相当于把跌倒样本量翻倍且不引入不真实的姿态。scale 开到 0.5 模拟行人由远到近的尺度变化能缓解小目标漏检。参数说明mixup 默认是 0对跌倒检测我建议第一轮训练先不开。mixup 会把两张图重叠人体轮廓被破坏后模型对人体水平贴地这种强结构特征的识别会变差fallen 类本身样本就少特征再被糊掉得不偿失。等你把第一轮跑通、确认基线没问题再开mixup: 0.2做一组对比实验用数据说话。如果 fallen 类还是不够常见做法是对该类做离线增强。我把 fallen 类训练图用 OpenCV 生成几个版本水平翻转、亮度 ±30%、轻度透视变形生成后和原图一起放进 train 目录。注意只增强 fallen 类不要动其他四类否则类别分布又被拉偏了得不偿失。4.2 类别不平衡fallen 样本少的问题不能只靠 loss 解决跌倒检测数据集的老问题是 fallen 类样本占比低——跌倒事件本身稀有采集成本又高。第一轮训练出来的模型standing 和 walking 的 AP 可能到 0.85fallen 只有 0.4 上下这是不平衡的典型表现。我处理这个问题的顺序是固定的。第一步先统计用 2.3 节的脚本改一下看各类别框数量占比。如果 fallen 类占比低于 10%先做过采样如果高于 10%先查标注质量而不是急着加数据。过采样的做法很直接把 fallen 类的图片在目录里多放几份副本文件名加后缀避免相互覆盖# oversample_fallen.sh cd fall_dataset for f in $(grep -l ^4 labels/train/*.txt | xargs -n1 basename); do cp images/train/$f images/train/${f%.jpg}_dup1.jpg cp labels/train/$f labels/train/${f%.txt}_dup1.txt done逻辑说明先用grep -l ^4 找出标注里包含类别 id 4 的标签文件再对每个文件把图片和标签各复制一份到对应目录YOLOv5 加载时把_dup1当成独立样本fallen 类样本量直接乘 2。注意图片和标签要成对复制只复制图片不复制标签校验脚本立刻会报有图无标签。参数说明过采样倍数建议 2 到 3 倍。超过 3 倍模型会对 fallen 类固定的几种姿态过拟合换个角度的摄像头就掉链子。另一个常见做法是调损失权重YOLOv5 的 hyp 里cls_pw可以按类别给分类损失加权把 fallen 的系数从 1.0 提到 1.5 或 2.0模型训练时会更重视这个类。但我的经验是过采样的收益通常比调cls_pw更直观先过采样损失权重作为第二层手段两个不要同时拉满。4.3 输入分辨率与验证集质量别让整体指标骗了你很多人在调优这一步只盯整体 mAP。整体 mAP 是各类别 AP 的均值standing 类样本多、AP 高会把 fallen 的低 AP 稀释掉看起来 0.75 好像还行一上现场就漏检。所以调优期间我只看两个指标val 输出里 fallen 类的单类 AP以及混淆矩阵里 fallen 和 bending 的互相错分数。如果 fallen 的 AP 上不去优先试输入分辨率。监控画面里行人往往只占图像的 5% 到 15%缩放到 640 之后跌倒的人可能只有 20 像素高。常见做法是把--img从 640 提到 960代价是显存占用和训练时间明显上升。如果 960 也救不回来问题多半在标注而不是分辨率——回到 2.2 节重新核对 fallen 类的边界标注。另一个容易被忽略的点是 val 集划分。如果 val 集里 fallen 类只有几十个框它的 AP 方差会非常大两个 epoch 之间跳 0.2 都是正常的你根本判断不了是真提升还是噪声。我一般会把 val 集里各类别占比统计出来确保 fallen 在验证集里至少有 50 个框以上评估才有参考意义。具体做法是按类别分层抽样先把 fallen 类图片单独列出来按比例随机分到 train 和 val再混合其他类别而不是直接全量随机切分。5. 避坑手册跌倒检测训练里最容易翻车的五个现场这一章的内容全部来自实际复现过程中踩过的坑按现象→原因→解决整理。每一条都值得在你自己的项目里提前排查。5.1 标签加载与类别映射的坑现象一训练一开始日志里出现大量WARNING: image with no labels数据加载数量比预期少很多最终 val 的 mAP 全是 0。原因最常见的是目录结构不完整——val 下没有对应的 labels 子目录或者标注文件被放到了别的位置。另一个高频原因是 data.yaml 的 train/val 路径写到了数据集根目录而不是 images 子目录导致执行replace(images, labels)时替换不命中标签全部找不到。解决先跑 2.3 节的校验脚本如果显示缺标签的图片不为空对照标准目录结构把文件归位如果校验正常但训练仍告警检查 data.yaml 路径是否精确指向 images/train。我一般会顺便打印一张图的标注路径确认标签替换逻辑实际命中的是哪个文件一步定位。现象二训练能跑loss 也正常下降但 val 出来 AP 极低随机抽推理图发现模型把站着的人框成 fallen或者所有预测类别整体偏移一位。原因data.yaml 里 names 的顺序和标注 txt 里的 class_id 定义不一致。比如 txt 里 0 代表 standing而 names 列表第一项写的是 fallen整个类别映射就整体错位了。这个问题在训练日志里完全看不出来因为模型只是把类别 A 的特征学成了类别 B 的标签loss 照样收敛。解决训练前用 2.3 节脚本加一段输出随机挑 5 个 txt把每行的 class_id 和它对应的 names 名称打出来人工核对一眼。更彻底的做法是抽几张图用 OpenCV 画框和类别名输出一张预览图映射对不对一眼就看出。这个检查我每次都会做花两分钟省两天。5.2 样本分布与标注质量的坑现象三fallen 类的单类 AP 在 0.3 以下徘徊其他四类都正常而且 fallen 的 recall 特别低——真实跌倒场景里漏检率过半。原因两件事叠加。一是 fallen 样本占比太少模型没见过足够正例二是 fallen 和 bending 在框形态上高度相似模型倾向于把跌倒预测成弯腰因为弯腰样本多、梯度贡献大学得更充分。解决按 4.2 节做 fallen 类过采样把样本占比拉到 10% 以上然后用第 6 章的方法看混淆矩阵定位 fallen 和 bending 的错分集中在哪里。如果错分集中在某个拍摄角度把这部分样本找出来补标注或补数据。切记过采样后重新跑一遍校验脚本别让重复文件搞乱标签对应关系。现象四训练时 loss 曲线好看但随机抽检发现很多框圈进了大片的背景跌倒的人被框成矩形包住整个墙角。原因标注时把影子、地面反光、背景物体轮廓圈进了框里。跌倒的人贴地时头和地面阴影的边界在标注软件里很容易看走眼框一松模型学的目标就成了影子人的混合体推理时遇到阴影就误检。解决对 fallen 类做一次逐框人工抽检重点看框的上下边界是否贴着人体主体。我常用一个土办法按框宽高比筛出所有w 1.5h的 fallen 框这类横框最容易混入地面背景逐张过一遍发现框松的直接重标。这类语义错误任何脚本都查不出来只能靠眼睛所以数据集的 fallen 类质量决定了你交付的模型上限。5.3 训练稳定性与推理部署的坑现象五训练进行到中途loss 突然变成 NaN然后整个训练进程直接崩掉。原因三个高频来源。一是学习率过高尤其在你手动调大了 hyp 里的lr0时二是 mixup 和 mosaic 组合后某些增强图像产生极端像素值配合高学习率触发梯度爆炸三是训练集里存在损坏的图片文件比如截断的 jpg、零字节文件、纯黑帧读取时像素数组异常。解决先降lr0从默认 0.01 降到 0.005 再试然后关 mixup只保留 mosaic最后跑一遍图片完整性检查用 Python 的 PIL 逐个打开捕获解码异常并剔除损坏文件。三步做完NaN 基本不会再出现。我在监控项目里还遇到过一种情况摄像头抓帧产生的纯黑图像被当训练样本hsv 增强后整张图的损失贡献异常过滤纯色图也是必要的数据清洗步骤。那之后我养成了一个习惯任何数据集进训练前先过一遍校验脚本再跑 10 个 epoch 的 smoke test确认数据加载、类别映射、loss 下降都正常才放行跑完整训练。这个流程拦下了至少一半训练三天发现白训的惨案。6. 用混淆矩阵和单类别 AP 做交付验证跌倒类别到底有没有救回来6.1 验证命令与统计口径训练完别急着部署先把验证指标跑全python val.py \ --data fall.yaml \ --weights runs/fall/exp1/weights/best.pt \ --conf-thres 0.25 \ --iou-thres 0.45 \ --save-conf逻辑说明val.py 会输出每个类别的 AP、整体 mAP以及 PR 曲线和混淆矩阵图默认存在 runs/fall/exp1 目录下。--conf-thres是置信度阈值val 统计时取 0.25 是 YOLOv5 的常规口径--save-conf会把每张图的预测框连同置信度写进 txt方便后续做时序分析或二次筛选。读结果时我的顺序是先看混淆矩阵图确认 fallen 和 bending 没有大面积互相错分再看 fallen 类的单类 AP 是否接近其他类别的水平而不是盯着整体 mAP 一个数。整体 mAP 只用来和上一轮训练对比趋势不作为交付依据。6.2 部署端的后处理习惯阈值与时序投票验证通过之后部署时我还有一个习惯不直接使用单一阈值。常见做法是给 fallen 类单独放低置信度阈值比如 0.3以提升召回代价是误检会变多。再用时序逻辑过滤误报——同一位置连续三帧以上检测到 fallen 才触发告警。这个三帧投票能把单帧误检压掉一大半尤其适合跌倒这种持续状态的检测目标比单纯调高阈值有效得多。这套数据集整体复现下来我最大的感受是格式标准带来的省心比类别多少更重要。目录干净、标签规范训练和验证就都是确定性的工作反之数据集本身有硬伤后面所有调参都是在错误的地基上盖楼。从那以后我每次拿到新数据集都会强制走一遍校验脚本 → smoke test → 混淆矩阵检查的流程确认 fallen 类不是看起来能用、实际漏检的状态才敢交付。希望帮到你。本文还有配套的精品资源点击获取
返回列表