☰
YOLOv8训练跌倒检测模型全流程指南:从数据集到部署
2026/9/28 12:06:29 网站建设 项目流程

简介:这套基于YOLOv8的跌倒检测完整毕业设计资源,面向计算机视觉方向学生及需要快速落地目标检测项目的开发者。资源包含带标注的跌倒/非跌倒图像数据集、完整训练与评估源码、预训练模型文件及说明文档,能够帮助使用者从数据准备到模型部署全流程复现跌倒检测方案,适用于老年人监护、室内安防等场景。压缩包共1437个文件,其中1428张jpg图像构成训练与验证数据,6个py脚本覆盖数据加载、模型训练与推理流程,另含1个pt权重、1个onnx导出模型及1个md说明文档,整体大小78.41MB,结构清晰便于按需检索。目前已有93人浏览学习。通过该资源可掌握YOLOv8的数据集组织方式、训练参数配置、模型评估与导出方法,还能参考其工程代码风格完成毕业设计文档与模块划分,是一份兼顾算法理解与工程实践的宝贵资料。

1. 跌倒检测模型为什么值得自己训练:YOLOv8 不是拿来即用的黑匣子

老人跌倒检测这几年从论文走向了社区和养老院,可真正落地时你会发现,拿通用目标检测模型直接去识别“倒地的人”根本不行。人体姿态、卧姿、遮挡、轮椅、地毯花纹这些干扰会把误报率抬到没法用的程度。而基于 YOLOv8 训练一个自己的跌倒检测模型,好处是能完全控制数据来源、标注口径和部署形态,最后产出一个几百 MB 的 .pt 权重,转成 ONNX 或 rknn 就能塞进边缘盒子。这篇笔记适合手里已经有一批图片、想从零跑通训练闭环的开发者,也适合做毕设选题的同学照着复现。我按“数据集怎么做 → 环境怎么搭 → 训练怎么调 → 踩了哪些坑 → 部署前怎么验”的顺序,把一套能出结果的路径完整讲清楚。

2. 训练跌倒检测前的数据集准备:标注格式、类别平衡与划分策略

2.1 跌倒检测数据集应该长什么样:从图片收集到统一成 YOLO 格式

自己训练的第一步不是装环境,而是把数据集整理成 YOLOv8 直接能读的格式。YOLOv8 训练自己的数据集要求图片和标注文件同目录或分目录存放,标注文件是 .txt,每行一个目标,格式为class x_center y_center width height,四个坐标值都是相对图片宽高的归一化小数。跌倒检测一般只做单类目标,类别名就叫fall,但如果你想把“站立”“行走”“跌倒”都识别出来,那就定义三个类。

常见做法是用 LabelImg 或 Labelme 标注。LabelImg 输出的是 PASCAL VOC 的 XML,Labelme 输出的是 JSON。我先说 LabelImg 这种更省事的路径:标注完拿到 XML 后,写个脚本把 XML 转成 YOLO 格式。下面这段脚本是我常用的转换逻辑,放在数据集根目录下执行:

import xml.etree.ElementTree as ET import os from pathlib import Path def convert_xml_to_yolo(xml_path, out_dir, classes): tree = ET.parse(xml_path) root = tree.getroot() img_w = int(root.find("size/width").text) img_h = int(root.find("size/height").text) out_lines = [] for obj in root.findall("object"): cls = obj.find("name").text if cls not in classes: continue box = obj.find("bndbox") xmin = int(box.find("xmin").text) ymin = int(box.find("ymin").text) xmax = int(box.find("xmax").text) ymax = int(box.find("ymax").text) x_center = ((xmin + xmax) / 2) / img_w y_center = ((ymin + ymax) / 2) / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h out_lines.append(f"{classes.index(cls)} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}") txt_path = Path(out_dir) / (Path(xml_path).stem + ".txt") txt_path.write_text("\n".join(out_lines), encoding="utf-8") classes = ["fall"] # 按你标注时的类别顺序写 xml_dir = "annotations" out_dir = "labels" os.makedirs(out_dir, exist_ok=True) for xml_file in Path(xml_dir).glob("*.xml"): convert_xml_to_yolo(str(xml_file), out_dir, classes)

逻辑说明:脚本先读 XML 里的图片宽高和每个目标的左上、右下坐标,再换算成归一化的中心点坐标和宽高。需要注意classes列表的顺序必须和训练时的data.yaml保持一致,否则类别会错位。参数说明里最容易被忽略的就是坐标系:YOLO 格式不接受像素绝对坐标,归一化时把 xmin、ymax 除以宽高即可,不要乘回去。

2.2 跌倒样本太少怎么办:数据增强与负样本策略

跌倒检测的训练集难点在于正样本稀缺,网上公开的跌倒数据集要么数量少、要么场景单一。我的做法是三类数据混着来:第一类是公开的跌倒检测图片集,数量不够就做增强;第二类是从视频里抽帧,把连续跌倒动作每隔 2 到 3 帧截一张,能凑出上千张;第三类是负样本,也就是大量正常坐、蹲、躺、弯腰捡东西的图片,这些能让模型学会区分“跌倒”和“主动躺下”。

增强不能无脑用 YOLOv8 自带的 mosaic,因为 mosaic 会把多张图拼一起,跌倒目标在拼接后可能被切掉一半。我一般只开轻微的水平翻转、缩放和亮度变化。另外非常关键的一点是类别不平衡:跌倒样本数和其他干扰样本数最好控制在 1:1 到 1:3 之间,太少模型会学不到跌倒特征,太多误报飙升。你可以在data.yaml里直接写训练集和验证集路径,然后跑通一次训练看看 loss 曲线的走势,这点后面会展开。

2.3 制作 VOC 与 YOLO 的目录对照:images、labels 与 data.yaml 的最小约定

YOLOv8 的data.yaml不需要像老版本那样建 JPEGImages、Annotations 一堆目录,最小约定是这样:

path: ./ train: images/train val: images/val names: 0: fall

path是数据集根目录的相对或绝对路径,train和val指向存放图片的目录。注意 YOLOv8 会默认在同级目录下找labels目录,所以如果你的图片在images/train,标注文件必须放在labels/train,图片和标注的文件名要一致,否则训练时会警告 “WARNING no labels found”。这个目录结构是我踩过最多坑的地方——很多人把标注文件跟图片混在一起,训练直接跑不起来。有一个验证命令我建议在训练前一定先执行:

python -c "from ultralytics import YOLO; YOLO('yolov8n.pt').val(data='data.yaml', split='val', imgsz=640)"

逻辑说明:这行命令不是为了真的验证精度,而是让 Ultralytics 加载你的数据集配置,如果目录结构或标注文件有问题,它会在报错信息里指出具体缺了什么。参数split='val'指定用验证集做评估,imgsz=640是推理时缩放尺寸。如果数据集正常,输出里会出现all这一行的 mAP 指标;如果输出里有0 labels之类的提示,说明标注对不上,回去检查目录结构。

3. Ubuntu 20.04 搭建 YOLOv8 环境并跑通跌倒检测训练:从 CPU 到 GPU 的选择

3.1 环境搭建的最小步骤:conda 创建环境与安装 ultralytics

对于 Ubuntu 20.04,搭建 YOLOv8 环境最好别直接用系统 Python,我通常用 conda 隔离。下面是最小安装命令:

conda create -n fall python=3.8 -y conda activate fall pip install ultralytics

逻辑说明:ultralytics这个包已经包含了 YOLO 模型定义、训练器和推理接口,不需要再单独装 darknet 或 mmdetection。Python 3.8 在 Ubuntu 20.04 下兼容性最好,torch 和 torchvision 都能找到对应 wheel。如果你只是 CPU 版本,那么到这里其实已经能跑了,只是速度慢;你希望用 GPU 加速就继续装:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118

注意这个命令假设你的机器是 NVIDIA 显卡且驱动已装好。参数说明里有个细节:cu118对应 CUDA 11.8,如果你的显卡较新,建议装cu121或更新版本。装完可以用python -c "import torch; print(torch.cuda.is_available())"验证。必须说清楚,CPU 版本不是不能用,只是训练一个小数据集几百张图,同样 100 轮要跑两三个小时,GPU 可能十分钟就完事。

3.2 用 GPU 训练跌倒检测模型:命令行参数逐项拆解

环境装好后,训练命令并不复杂,但参数含义必须吃透。我一般这样启动训练:

yolo detect train model=yolov8n.pt data=data.yaml epochs=120 imgsz=640 batch=16 device=0 patience=20

逻辑说明:model=yolov8n.pt是预训练权重,n是 nano 版本,参数量最小,适合跌倒检测这种相对简单的单类任务。epochs=120是训练轮数,imgsz=640是输入图片尺寸,batch=16是批大小,device=0指定第一张 GPU,patience=20是早停耐心值,如果连续 20 轮验证集指标没提升就自动停止。

参数说明里最容易翻车的是batch和显存的关系。跌倒检测图片通常 1080p 分辨率,缩放到 640 后单张占用约 6GB 显存(batch=16 时需要),如果你的显卡只有 8GB,建议改成batch=8。epochs不是越多越好,跌倒检测数据集小,120 轮足够,再加就容易过拟合,表现为训练 loss 降了、验证 mAP 反而掉。

3.3 画损失函数曲线图:训练日志里的 box_loss、cls_loss 与 dfl_loss

YOLOv8 训练过程中的输出日志包含box_loss(边界框回归损失)、cls_loss(分类损失)、dfl_loss(分布焦点损失),还有验证集上的对应指标。训练结束后,Ultralytics 会在runs/detect/train目录下生成results.png,这张图天然就是损失函数曲线图。不过很多人想自己画更细的曲线,用训练日志里的 CSV 是更好的方式。

打开runs/detect/train/results.csv,里面每一行对应一轮,列有epoch, train/box_loss, train/cls_loss, train/dfl_loss, metrics/precision, metrics/recall, metrics/mAP50(B), val/box_loss等。用 pandas 直接读取并画图:

import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv("runs/detect/train/results.csv") fig, ax = plt.subplots(1, 2, figsize=(12, 4)) ax[0].plot(df["epoch"], df["train/cls_loss"], label="train_cls") ax[0].plot(df["epoch"], df["val/cls_loss"], label="val_cls") ax[0].set_title("Classification Loss") ax[0].legend() ax[1].plot(df["epoch"], df["train/box_loss"], label="train_box") ax[1].plot(df["epoch"], df["val/box_loss"], label="val_box") ax[1].set_title("Box Loss") ax[1].legend() plt.tight_layout() plt.savefig("loss_curve.png")

逻辑说明:这个脚本把原版results.csv里的两列连续画出来,方便观察训练是否收敛。关键看两个点:训练 loss 持续下降而验证 loss 上升,说明过拟合;验证 loss 在 60 轮后进入平台期,说明模型差不多到头了。参数说明里train/cls_loss和val/cls_loss列名前半部分是分组,后半部分是指标,不同版本列名可能带(B)或(M)后缀,画图前先打印df.columns确认。

4. 把 YOLOv8 跌倒检测模型的精度提上去:锚框、预训练权重与数据清洗三个关键点

4.1 用 yolov8s 还是 yolov8n:单类检测任务的选型逻辑

YOLOv8 提供 n/s/m/l/x 五个尺寸,跌倒检测这种单类任务不需要追求极致精度,因为类间差异很大——人倒在地上和站着走路的视觉特征足够明显。我通常先拿yolov8n跑通流程,确认数据集没问题后再切yolov8s做最终训练。yolov8s的参数量大约是 nano 的三倍,但推理速度在边缘设备上还能接受。如果你的部署平台是 RK3588 这类 NPU,nano 版本往往更友好,因为量化后的精度损失更小。

选型时要看你的数据规模。500 张图用yolov8s很容易过拟合,1000 张以上才建议从 s 起步。m/l 版本对跌倒检测来说收益很小,还拖慢训练速度,不建议新手一上来就尝试。

4.2 训练参数再调优:从 data.yaml 到默认超参数的改动清单

Ultralytics 默认的超参面向 COCO 这种多类别通用场景,跌倒检测需要改几个值。第一个是lr0,默认 0.01,小数据集建议降到 0.005,否则前期震荡太剧烈。第二个是mosaic,老版本默认 1.0,新版本在augment模型参数里控制,跌倒检测建议设成 0.5 或 0.0。第三个是close_mosaic,数据不足时不要用它的默认 10,可以设成 5。

修改超参有两种方式:命令行直接传参(例如lr0=0.005 mosaic=0.5),或者改模型配置文件。我更推荐命令行传参,因为每轮实验的参数都留在训练日志里,方便对比。下面是我针对跌倒检测调过的一版参考命令:

yolo detect train model=yolov8n.pt data=data.yaml epochs=120 imgsz=640 batch=16 lr0=0.005 mosaic=0.5 close_mosaic=5 patience=30

逻辑说明:mosaic=0.5表示每批样本中 50% 使用马赛克增强,剩下一半保持原始图。参数说明里close_mosaic是最后 5 轮关闭马赛克,这样能让模型适应正常宽高比的目标。如果你不设置这两个参数,模型会把跌倒的人拼成奇怪形状,验证时遇到完整人体反而检测不到。

4.3 识别率低先别调参:先检查标注框是否贴合人体

训练出来的模型 recall 低,最常见的原因是标注框太紧或太松。跌倒检测里人倒地后身体呈对角线,标注框如果只包住上半身,模型学到的特征就不完整。我的经验是标注框要包含整个人体轮廓,哪怕把边缘留出 5% 的余量也不要切掉四肢。你可以用可视化工具把标注框画在图片上检查,代码非常简单:

import cv2 from pathlib import Path img = cv2.imread("images/train/001.jpg") h, w = img.shape[:2] label_path = Path("labels/train/001.txt") for line in label_path.read_text().strip().splitlines(): cls, xc, yc, bw, bh = map(float, line.split()) x1 = int((xc - bw / 2) * w) y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w) y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite("check_001.jpg", img)

逻辑说明:这个脚本把 YOLO 格式的标注框还原成像素坐标画在图上,用于抽检标注质量。参数说明里xc, yc是中心点坐标,bw, bh是宽高比例,换算回像素时必须要乘以图片宽高,很多人写脚本时忘记这一步,画的框全部偏到左上角。抽检 20 张如果超过 5 张框没贴合,就回去重新标注,这比调任何参数都管用。

5. YOLOv8 跌倒检测训练高频踩坑:环境、数据与显存问题的排查记录

5.1 训练时提示 CUDA out of memory,但换小 batch 还是崩

现象:yolo detect train启动后没跑几步就报CUDA out of memory,把 batch 改成 2 仍然崩溃。原因是 YOLOv8 默认开启缓存图片到显存(cache=True),小数据集整图缓存会额外占用几个 GB。解决方法是关闭缓存并限制 worker 数:

yolo detect train model=yolov8n.pt data=data.yaml batch=8 cache=False workers=2

这样cache参数设为False后每轮从磁盘读图,虽然慢一点但显存占用骤降。如果还是崩,检查你是不是同时开了多个进程或终端占用显存,用nvidia-smi看一下。

5.2 WARNING no labels found 循环提示,但标注文件明明存在

现象:训练日志里不断出现WARNING no labels found in labels/train,打开目录发现.txt文件都在。原因是文件名不一致:图片是001.jpg,标注是001.txt,看起来没问题,但如果标注文件是从 XML 转换时带了额外后缀,比如001.xml.txt,就会匹配不上。另外检查data.yaml最后是否有空行或隐藏字符,我遇到过一次从 Windows 复制过来的data.yaml里路径带\r导致读取失败。解决方法是统一重命名标注文件,再执行一遍我前面给过的验证命令。

5.3 模型训练完检测不到跌倒,但训练时 mAP 很高

现象:验证集 mAP@0.5 到 0.95,看起来不错,拿到现场视频里一测,跌倒的人完全检测不到。这通常不是模型问题,而是数据分布偏差——训练集里的跌倒图片多为正面视角、光线均匀,现场是俯拍或侧视,模型没见过。解决方法是补充多视角数据,尤其要加俯视 45 度角、夜间红外、昏暗走廊场景。如果现场只有枪机固定视角,最好单独收集该视角的 100 张跌倒图做微调,而不是指望通用权重泛化。

5.4 跌倒检测把坐下、蹲下也报成跌倒

现象:误报集中在老人弯腰系鞋带、坐在矮凳上起身这几类动作。原因在于“跌倒”和“低位姿态”在单帧图像上真的很难区分——人躺在地上和蹲下时,检测框的宽高比都大于 1。解决思路有两个:第一个训练时加入大量干扰负样本,明确标注为normal,让模型学习区分;第二个在推理端加后处理逻辑,用连续帧的位移和速度判断,只有目标在短时间内从站立高度变为倒地高度才算跌倒。后处理不是 YOLOv8 自带能力,需要自己写几行规则或接入跟踪器。

5.5 CPU 训练慢得无法忍受,但只有 CPU 可用

现象:Ubuntu 20.04 上搭好 CPU 版本环境,训练 120 轮耗时 8 小时。解决方法是降低输入尺寸和轮数:imgsz=416,epochs=60,配合workers=0。另外可以先用model=yolov8n.pt冻结前 10 层做迁移学习。如果做毕设只需要一个能跑的模型,CPU 训练小数据集完全可行,不必为了加速去租 GPU。我建议你先跑通几轮epochs=5,确认数据加载、损失计算正常后,再挂机跑完整训练。

6. 训练完成后的验证与部署前检查:用验证集指标和实际视频把模型逼到极限

6.1 用混淆矩阵和 PR 曲线判断模型是否值得用

Ultralytics 训练结束后会在runs/detect/train下生成confusion_matrix.png和PR_curve.png。打开混淆矩阵,重点关注fall类的假正例和假负例。如果假正例集中出现在背景或normal类,说明负样本不够;如果假负例多,说明姿态多样性不足。PR 曲线的曲线下面积如果大于 0.9,模型基本可用;0.8 左右就得考虑回炉。没有这两张图也能通过输出日志里的metrics/precision(B)和metrics/recall(B)判断,但图能告诉你到底是哪一类出错。

6.2 视频推理测试的固定脚本:检测置信度与帧率的作用

不要只拿图片测,跌倒检测最终面对的是视频流。一个用于验证的视频推理脚本要能控制置信度、显示帧率,并统计连续检测结果。下面是我常用的测试脚本:

import cv2 from ultralytics import YOLO model = YOLO("runs/detect/train/weights/best.pt") cap = cv2.VideoCapture("test_fall.mp4") conf = 0.35 while cap.isOpened(): ret, frame = cap.read() if not ret: break results = model(frame, conf=conf, imgsz=640, verbose=False)[0] annotated = results.plot() fps = cap.get(cv2.CAP_PROP_FPS) cv2.putText(annotated, f"{fps:.1f} FPS", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow("fall test", annotated) if cv2.waitKey(1) & 0xFF == ord("q"): break cap.release() cv2.destroyAllWindows()

逻辑说明:这个脚本用model(frame, conf=conf)对每一帧做推理,conf=0.35是置信度阈值。results.plot()把检测框画到原图上。参数说明里conf的取值直接决定误报率——跌倒检测建议先跑一遍统计 mAP50 对应的置信度阈值,通常 0.25 到 0.5 之间选择。现场误报严重时调高到 0.6,但如果召回率明显下降,就退回 0.4 并靠后处理过滤。

6.3 导出 ONNX 与 RKNN 时的精度验证技巧

训练完的.pt文件不能直接部署到大多数嵌入式设备,转 ONNX 是标准动作。用 YOLOv8 自带导出命令转换:

yolo export model=runs/detect/train/weights/best.pt format=onnx imgsz=640

转换后一定要对比 PyTorch 模型和 ONNX 的推理结果是否一致,用同样的图片,分别跑model.predict和onnxruntime推理,比较检测框坐标和置信度差异。差异超过 2% 通常是因为你用了动态尺寸导出,建议固定imgsz=640。如果是 RK3588 这类 NPU,ONNX 还要转成 RKNN,转换过程里量化校准集最好从训练集里随机抽 100 张,不要用验证集,否则精度会被高估。

我自己的习惯是,最终验收模型时不只看 mAP,而是拿一段 5 分钟的真实监控视频,里面包含 3 次跌倒和 5 次弯腰、蹲下动作,然后数模型框出多少次。只要这个测试通过,项目才算真正落地。这些验证步骤做下来,你才会知道 YOLOv8 跌倒检测模型原来比想象中更需要场景适配,而不是训练完就万事大吉。希望这些经验帮到你,至少让你少走我当初走过的弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询