YOLOv5异常行为检测实战:目标检测与规则判断
简介面向计算机专业本科毕业生、课程设计学生与目标检测初学者的YOLOv5异常行为检测实战资源。内容覆盖数据标注、模型训练、评估与部署的关键环节既可直接作为毕业设计选题实现参照也可用于系统学习YOLOv5工程化开发适合在答辩前需要快速搭建可演示系统的开发者。压缩包共212个文件包含105个yaml配置、45个py源码、20张jpg效果图以及pyc预编译文件、sh脚本、md文档、Dockerfile等yaml与py构成核心算法与训练配置jpg直观展示检测和标注效果目录结构清晰整体仅2.81MB便于下载与本地复现。目前已有637人浏览学习。作者基于真实毕业设计系统整理沉淀了调试思路与工程经验代码模块划分明确可按需查阅Dockerfile与ipynb教程可帮助快速还原运行环境理解数据处理、训练调参和结果验证的完整流程对准备毕业答辩或希望借鉴成熟代码结构的开发者具有较高参考价值。1. 毕业设计做基于YOLOv5的异常行为检测一个目标检测项目能走多远把“基于YOLOv5的异常行为检测”拆开看它其实不是传统意义上的行为识别而是一个目标检测任务。你用YOLOv5检测出画面里的人再根据人的坐标、类别和出现规律去判断“摔倒、打架、闯入、徘徊”这类异常事件。这个思路之所以在本科毕业设计里被反复使用是因为它把最难的时序建模问题简化成了单帧检测加上规则判断训练成本低、可视化效果好而且答辩时能现场演示。你不需要复现SlowFast或者骨骼点检测只需要搞定YOLOv5的检测能力再写一层薄薄的后处理逻辑。这篇文章面向两类人用这个题目做毕业设计、需要跑通全流程的在校生以及想在企业项目里快速验证“检测规则”方案的工程师。适合你照着复现的最小路径我会按数据准备、训练调参、推理后处理、部署踩坑的顺序讲完。2. 为什么是YOLOv5而不是行为识别网络异常检测的本质是目标检测加规则2.1 单帧检测与序列建模的边界先想清楚你的异常类型做异常行为检测第一件事不是下载代码而是定义“异常”由谁来判断。摔倒、打架、翻越围栏、人员倒地、静默徘徊这些行为里真正需要视频时序信息的只有少数。比如“摔倒”在单帧里就是一个人横躺在地检测出“人”和“人”的姿态即可“徘徊”是同一ID在画面里反复出现这需要目标跟踪而“打架”本质上是两个人距离过近且持续重叠。绝大多数本科毕设的异常检测题目在帧级别用YOLOv5检测出目标再用一些几何规则就能覆盖。YOLOv5的核心价值在于提供了一个稳定、可微调、能导出ONNX和TensorRT的目标检测基线它的架构由BackboneCSPDarknet、NeckPANet和Head多尺度预测组成开箱即用。你需要做的不是改网络结构而是改造数据。2.2 数据集的三种做法公开异常数据集、自建数据集、混合策略常见做法是使用公开的异常行为数据集来预训练再用自己的视频数据微调。比如UCF-Crime等公共安全数据集可以作为预训练来源但直接拿来做毕设有两个问题一是类不平衡严重异常帧只占很小比例二是很多公开集分辨率低YOLOv5的Anchor尺寸和它不匹配导致小目标漏检。我一般会建议混合策略先用公共数据集训练一个通用人检测模型作为基线再录5到10段自己场景的视频用工具标注后微调。注意异常检测项目里最容易犯的错误是只标注异常样本。如果你的检测器没见过“正常行走”的人它在推理时会疯狂误报。正确做法是把正常行为也标注成独立类别比如normal、fall、fight、squat最后用分类概率而不是单纯的位置信息来做判断。标注工具用LabelImg或X-AnyLabeling都行导出为YOLO格式的txt文件。2.3 行为规则与检测器的分工坐标信息怎么变成事件检测器输出的是类别、置信度、x中心、y中心、宽高你的规则层需要把这些数值翻译成行为。以摔倒检测为例比较可靠的规则是宽高比。人的检测框在站立时高度明显大于宽度倒地时宽度接近或大于高度。再加上检测框的y中心突然下移就能判定摔倒事件。为了减少偶发误报通常还要做帧间平滑连续三帧以上满足条件才触发。打架检测则用两个人检测框的IoU即交集面积与并集面积的比值当IoU超过阈值且持续时间较长判定为打架。这些规则直接写在后处理脚本里不依赖任何深度学习模型。YOLOv5在这里扮演的角色就是一个高质量的人与物体检测器它把视频逐帧拆解成结构化数据剩下的事件判断完全交给逻辑。这种解耦方式让整个项目的模块边界清晰出了误报你也能快速定位是检测问题还是规则问题。3. 跑通训练全流程环境配置、数据整理、训练命令与参数说明3.1 环境准备与常见坑用conda装YOLOv5依赖先搭环境。YOLOv5对PyTorch版本有一定要求但更重要的是CUDA和torch的匹配。我建议用conda创建独立环境避免和现有的其他项目冲突这一步在毕业设计答辩时也很加分因为你能把环境复现讲清楚。安装命令如下conda create -n yolo5 python3.8 conda activate yolo5 # CUDA 11.8 对应 PyTorch 2.0.1 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt这里有个容易翻车的点pip install -r requirements.txt会安装最新版opencv-python在部分Ubuntu服务器上会和系统自带的cv2冲突导致ImportError。解决方式是在虚拟环境里先卸载系统cv2pip uninstall opencv-python再重新装一次。还有一点PyTorch的安装源一定要指定否则默认装CPU版本训练速度慢到怀疑人生。装完后用python -c import torch; print(torch.cuda.is_available())验证GPU可用输出True再继续。3.2 数据集目录结构与YOLO标注格式YOLOv5要求的数据目录结构是固定的以下是一个标准布局。你自己录的视频切帧后用标注工具导出成txt每个txt文件对应一张jpg文件名必须完全一致。txt的第一行格式是类别id归一化中心x归一化中心y归一化宽归一化高。注意归一化是相对于图片的宽和高不是相对于检测框区域。dataset/ images/ train/ 0001.jpg 0002.jpg val/ 0100.jpg labels/ train/ 0001.txt 0002.txt val/ 0100.txt这里最容易被忽略的是类别从0开始编号。你的data.yaml文件里定义names顺序一旦写错训练出来的模型预测类别就会错乱。比如train: dataset/images/train val: dataset/images/val nc: 4 names: [normal, fall, fight, squat]我自己一般会在写data.yaml之后跑一个脚本校验标注把每个txt第一列的类别id打印出来确认和names顺序一致。如果训练时loss正常下降但验证集的mAP一直很低优先检查这里。3.3 训练命令与超参数的直觉理解训练命令不复杂复杂的是超参数。YOLOv5提供了一系列默认超参数存放在data/hyps/hyp.scratch-low.yaml里。初学者喜欢把所有参数拉满实际效果反而不好。以下是推荐的基础命令python train.py --img 640 --batch 16 --epochs 100 --data dataset/data.yaml --weights yolov5s.pt --cache--img指训练时resize到640x640这个值决定了检测性能的下限。--batch设16在大多数8G显存的显卡上可行如果你的显卡是4G显存降到8。--epochs不是越多越好我观察过很多训练日志异常检测数据往往在60到80个epoch时就过拟合了典型表现是训练loss持续下降但验证集mAP不再上升。--weights用yolov5s.pt作为预训练权重比从头训练收敛快很多。--cache表示把图片缓存进内存能大幅缩短训练时间但内存不足的机器会直接OOM。如果你想微调检测头而不是全部参数可以加--freeze 10把前10层冻结这样可以保护预训练特征不被小数据集破坏。3.4 训练过程的监控指标loss下降之外还要看什么训练开始后命令窗口会打印每一轮的box_loss、cls_loss、obj_loss以及precision、recall、mAP50等指标。很多人只盯着total loss。实际上要分三部分看box_loss是边框回归误差cls_loss是分类误差obj_loss是目标置信度误差。异常检测数据里如果fall、fight这类类别样本少你会看到cls_loss震荡明显因为模型在少数类上学不到稳定特征。缓解的办法一是你给少数类多标注几份扩充样本二是在训练时设置--cls 0.5来降低分类损失惩罚权重让它不要只顾着把正常类拟合得过于完美。训练结束后runs/train/exp/weights/目录下会生成best.pt和last.ptbest.pt是验证集mAP最高的权重这才是你要用的last.pt是最后一个epoch的通常效果略差。4. 推理部署与后处理检测框如何变成报警事件4.1 用best.pt跑视频推理理解YOLOv5的输出结构训练完成后YOLOv5自带detect.py可以做视频推理但如果你要做异常行为规则判断直接跑detect.py是不够的。detect.py输出的是可视化画面你拿不到结构化数据。你需要写一个自定义推理脚本调用模型的forward接口拿原始预测结果。这里有一个关键参数要调conf-thres即置信度阈值和iou-thres即NMS的交并比阈值。公共安全场景里漏报比误报更严重我会把置信度阈值设低到0.25把IoU阈值设到0.45。代码示例如下import torch model torch.hub.load(., custom, pathruns/train/exp/weights/best.pt, sourcelocal) model.conf 0.25 model.iou 0.45 results model(frame) boxes results.xyxy[0].cpu().numpy() for box in boxes: x1, y1, x2, y2, conf, cls_id box w x2 - x1 h y2 - y1 # 宽高比规则检测摔倒 if w h * 1.2 and cls_id 0: print(fall event detected)这段代码里results.xyxy[0]返回的是一个numpy数组每行是x1、y1、x2、y2、置信度、类别id坐标是像素坐标。为什么摔倒判定里建议按宽高比而不是直接用h值因为摄像头视角不同画面中离镜头远的人检测框整体偏小绝对像素阈值完全不可靠宽高比是尺度无关的鲁棒得多。4.2 目标跟踪与ID稳定性没有跟踪的规则检测都是纸老虎仅仅靠单帧检测做规则判断会出现一个很常见的问题人走过去一瞬间检测框抖动宽高比突然变化误触发一次摔倒报警。解决方向是引入目标跟踪让同一ID的检测框轨迹连续。轻量做法是用YOLOv5结合DeepSORT重量做法是直接用ByteTrack。在毕设场景ByteTrack更简单因为它不需要额外的ReID模型。思路是检测器每帧输出检测框ByteTrack用卡尔曼滤波预测下一帧位置再通过IoU匹配把同一目标的框关联起来分配稳定ID。然后你的规则层改为基于ID的状态机连续M帧内同一个ID的宽高比都满足摔倒条件才触发报警。这个改进能让误报率下降一个量级。部署时ID信息是一条曲线你把每个ID在最近100帧里的宽高比存成队列再检测这个队列的均值和方差用均值的突变来判断行为变化。4.3 异常行为判定的三种典型规则方案规则层不需要机器学习但需要精心设计。我把常用的规则整理成一个表格方便你对照自己的场景选择异常类型输入信号判定逻辑推荐阈值摔倒检测框宽高比、中心点y坐标连续3帧宽高比大于1.2且中心y坐标下移超过20%帧数3比例1.2打架两个检测框的IoUIoU大于阈值并持续5帧以上IoU 0.3持续5帧闯入检测框中心是否在预设区域内中心坐标落在禁区多边形内区域按实际画徘徊同一ID在画面内停留时间跟踪ID存活超过预设秒数200帧这些规则写好后要先用正常视频做一遍回归测试确保完全没有误报再添加异常视频验证召回率。很多人在调试时只看异常视频结果答辩现场放一段正常走廊的视频系统疯狂报警场面会很尴尬。记住异常检测系统的核心指标是误报率不是召回率。5. 常见问题和排查避坑这些坑我基本都踩过一遍5.1 训练时loss为NaN模型权重全部爆掉现象训练开始几十个step后loss打印出nan模型无法收敛。原因最常见的是学习率过高或者batch里出现了异常标注数据比如txt标注文件的坐标值超过了1或者为负数导致损失函数计算梯度爆炸。解决先用脚本扫描所有标注txt检查每一行坐标是否在0到1之间0以下或1以上的直接删除对应文件。然后降低初始学习率YOLOv5默认lr0是0.01如果数据集小改成0.001会更稳。5.2 训练完mAP很高实际上检测效果却很差现象验证集的mAP50到了0.95但拿到现场视频测试人物漏检严重。原因你的验证集和训练集来自同一批视频切帧分布几乎一致模型记住了场景特征而不是人物特征。解决重新录制一段完全不同的场景视频单独切帧作为测试集。不做这一条你的模型说服力会大打折扣。我一般还会用--augment打开测试时增强让模型在推理时看到多个尺度下的预测结果对低分辨率监控画面有改善。5.3 树莓派或Jetson上推理速度慢到无法实时现象部署到边缘设备后FPS只有3到5完全达不到实时。原因直接使用了PyTorch的fp32权重设备没有充分利用GPU或者根本没有GPU。解决分两步走。第一步用export.py把模型转成TensorRT引擎命令是python export.py --weights best.pt --include engine --device 0需要本机装有TensorRT。第二步在推理脚本里加载engine文件替代torch模型。如果确实没有TensorRT环境至少转成ONNX再用onnxruntime推理速度也比PyTorch快不少。注意转engine后输入分辨率必须是固定尺寸不能像PyTorch模型那样自由输入任意大小。5.4 数据类别不平衡导致少数类完全学不出来现象fall和fight的召回率接近0normal类的AP很高。原因异常事件在视频里本来就是稀缺的标注样本少模型优先拟合了多数类。解决不要只做简单的样本复制。我用过比较有效的方法是Mosaic增强加复制粘贴。复制粘贴是指把异常目标从原始帧中裁剪出来随机粘贴到正常场景帧上同时修改对应的标注txt坐标。这个方法人为增加了异常样本的多样性比直接复制整个图片要有效得多。5.5 加载模型时出现KeyError或者尺寸不匹配现象用torch.hub.load加载本地weights时报错或者前向推理时提示shape不一致。原因你下载的权重文件不完整或者训练时的输入尺寸和推理时的输入尺寸不一致。解决yolov5s.pt的下载要确认文件大小在14MB以上不完整的pt文件都是几KB。再检查你的train.py命令里--img参数是640detect时也要用640。不同分辨率的输入会造成特征图尺寸不匹配除非模型里使用了自适应锚框否则报错是必然的。5.6 摄像头视频流推理卡顿画面延迟严重现象解码rtsp流时画面延迟超过3秒完全无法用于实时监控。原因视频解码线程和模型推理线程混在了一起前向推理阻塞了解码。解决用双线程模型。一个线程专负责cv2.VideoCapture读取最新帧另一个线程负责模型推理推理线程只处理最新的一帧丢弃积压的旧帧。核心点是不能一边读一边推理否则积压晚点会让你误报率飙升。6. 把规则检测升级成可演示的报警系统事件日志与置信度平滑训练和推理跑通之后一个常见困惑是“被告知系统检测出异常但演示时没有报警输出画面”。这是因为你只做了检测没有做事件记录层。我会在推理脚本里加一个环形缓冲区为每个目标ID维护最近50帧的检测记录。每当ID被分配时创建一个字典来保存它的历史数据包括宽高比序列和中心点坐标序列。规则判断函数的入参是这个缓冲区出参是事件类型和时间戳。当事件触发时把当前帧保存为jpg同时把事件信息写入JSONL日志文件每一行一条事件记录包含时间、摄像机ID、事件类型、置信度、以及触发帧的截图路径。这一层非常轻量但对答辩展示和后续调试都很有用。置信度是另一个值得做平滑的地方。YOLOv5对同一个目标在相邻两帧给出的置信度会有波动如果你直接用0.25阈值做二值判断目标稍微模糊就会丢掉身份IDID频繁跳变会导致跟踪断线。我的习惯是保存每个ID最近10帧的置信度均值只有连续5帧均值超过阈值才认为目标有效。这条经验也适用于摔倒检测连续帧满足条件比单帧满足条件可靠得多。最后再说一个验证技巧准备两段视频一段是彻底正常的场景一段是包含异常事件的场景跑完把报警时间点和截图拿出来逐帧对一遍。如果正常视频零报警异常视频能覆盖大部分事件把这个结果直接写进论文结论。这是我做所有检测类项目都会做的回归测试它能让你在答辩时拿出数据而不是感觉。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →