
超市安防这些年我一直觉得偷窃行为检测是个“看起来简单做起来要命”的活。你把摄像头装好期待它自动抓出问题结果真正跑起来不是把顾客正常拿货当成偷窃就是把已经发生的行为漏成了筛子。根源往往不在算法而在训练数据。我最近在一个门店安防项目里用了这套超市店铺偷窃行为检测数据集4000张高质量标注图像直接喂给YOLO体系做训练才算是把整个流程跑通。这篇文章就从数据集的构成、标注逻辑、训练调参到落地部署把我实操中验证过的经验完整写出来。这套数据集解决的核心问题很清楚让模型在监控画面里区分“正常购物动作”和“偷窃/可疑行为”而不是把所有伸手进包、弯腰查看的动作都误判成异常。它适合三类人正在做安防告警系统的开发者、连锁零售行业做技术方案选型的人、以及拿异常行为识别当课题方向的学生。下面进入正题。1. 为什么偷窃检测必须用专门的数据集1.1 监控画面里的人工巡检困局超市损耗是零售行业长期存在的运营痛点小到零食、日用品大到高价商品失窃造成的损失累加起来非常可观。传统应对方式是配保安看监控但人眼巡检有天然上限一个保安要同时盯几十路画面注意力分配到每一帧的时间几乎可以忽略偏偏偷窃动作又常常发生在购物车遮挡、货架转角、同伴掩护这些视觉盲区里经常是事后翻录像才发现。深度学习给了另一条可行路线。目标检测模型能7×24小时处理视频流每一帧都能保持同样的注意力还能同时处理多路摄像头不疲劳、不眨眼。但这里有个关键前提模型必须知道你要找的是什么。通用目标检测模型识别“人”“购物车”“背包”没有问题但你让它判断“这个人正在把商品塞进衣服里”它完全没有概念。这就是通用模型和行业专精模型之间的差距也是这类偷窃行为检测数据集存在的根本原因。1.2 为什么首选YOLO框架目标检测框架选择很多我最终固定在YOLO系上落地主要基于三点。第一是速度。哪怕是Jetson这类边缘设备YOLO的小模型也能跑到每秒十几帧到二十几帧满足监控实时分析的需求。两阶段检测器虽然精度上限可能稍高但推理时间经常翻好几倍一旦视频路数上来算力根本吃不消。第二是工程生态。YOLO体系的标注格式、训练代码、模型导出链路非常成熟从拿到数据到部署上线工具链衔接顺畅不需要大量自研胶水代码这对项目交付周期来说是巨大优势。第三是精度与成本平衡。针对“框出人”“框出包”“框出可疑行为”这类任务YOLO的中等模型已经能达到不错的mAP没有必要为了零点几个点的提升牺牲开发效率和推理速度。当然YOLO并非没有局限。它本质上处理的是静态图像单帧输入模型不知道动作正在进行还是已经结束。这个问题需要在应用层用连续帧、跟踪与时序逻辑来弥补具体方案放到第4章详细讲。1.3 偷窃检测的三个公认难点为什么超市偷窃检测比一般的目标检测更棘手我总结了三个难点。第一个是动作幅度小、持续时间短。真正的偷窃动作往往只有零点几秒伸手、塞包、藏衣一气呵成在25帧/秒的视频里可能只有十几帧。模型必须从这些短暂瞬间里抓住有效特征训练数据里就要有大量不完整的“动作中断”画面而不是只挑动作完整的高光和明显样本。第二个是环境干扰强。超市货架密集、人流交错遮挡是常态。同一个动作在货架左侧和右侧拍摄画面差异极大再加上灯光色温变化、玻璃反光、生鲜区雾气等干扰模型学到的特征很容易被环境噪声带偏。第三个是正负样本极度不均衡。监控画面里绝大多数是正常购物偷窃行为可遇不可求。如果数据集随机采样正样本比例可能低到可以忽略模型训练出来只会永远输出“正常”。构建这类数据集必须做有意识的采样策略把稀有行为挑出来还要把“弯腰系鞋带”“翻找钱包”“整理衣服”这类难负例放进去逼模型学到真正的判别特征。这套4000张的数据集在负样本编排上做得比较到位这也是我选它作为项目起点的原因。2. 4000张标注图像里到底有什么2.1 场景划分、分辨率与类别设计这个数据集属于典型配置我按项目习惯做了二次整理。4000张图像主要覆盖超市货架区、收银台、出入口和生鲜区几个关键区域时段包含晨间、下午和晚间光照条件比较多样。图像分辨率统一为1920×1080属于监控标准分辨率细节保留足够。按70%训练、20%验证、10%测试的比例我把它分成训练集2800张、验证集800张、测试集400张。类别设计是这类项目最关键也最容易被忽略的一环。我见过有些项目只用一个“偷窃”类别框所有可疑动作结果模型把正常取货、掏钱包都判成偷窃误报率高到没法用。合理的做法是把动作拆细我的设定是三类人员、购物袋/购物车、存疑行为。进一步把存疑行为细分成“商品藏入衣物”“商品放入未付款容器”“快速反复张望后取货”等具体姿态。类别细一点模型学到的判别特征更准确但也不能无脑细一个类别如果只有几十个样本数据量撑不住模型学了也白学。2.2 高质量标注的执行标准与清洗流程“高质量标注”不是嘴上说说它体现在两个容易量化的指标上。第一是标注框贴合度目标是让边界框紧紧包裹目标不包含大量无关背景。第二是遮挡目标处理的一致性连续帧里同一个被遮挡一半的人不会一会儿框全身一会儿框半身这种一致性直接影响训练时标签噪声的水平。实际操作中我推荐双人独立标注加一致性复核的流程。两个人各自标一遍然后计算同一个目标两个标注框的IoU如果IoU低于0.7就需要人工复核到底是谁标错了。不要觉得这是浪费人力标签错误对模型训练的负面影响是系统性的一个坏标签可能带偏一整片区域的损失计算。清洗环节更不能跳过。我处理任何数据集都会过滤五类不合格样本画面严重模糊、目标被大面积遮挡、光线过暗导致主体不可辨识、重复画面占比过高、目标区域过小。很多数据集宣传片数很大但里面夹杂着大量粗标和低质量图模型的性能上限会被这种噪声拖住。4000张看起来不算特别多但每一张都有效信息完全可以支撑一个小型安防项目启动后续再用现场数据做增量扩充完全够用。2.3 转换成YOLO格式的实操细节拿到原始标注后第一步是转换成YOLO能识别的标签格式。YOLO的标签文件是纯文本每一行代表一个目标class_id x_center y_center width height其中中心点坐标和宽高都是归一化到0到1的小数。如果原始标注来自COCO或VOC格式转换公式如下x_center (xmin xmax) / 2 / image_width y_center (ymin ymax) / 2 / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_height转换完的目录结构建议是这样的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/这里有个很容易踩的坑图片文件和标签文件必须同名、同后缀大小写比如001.jpg对应的标签必须是001.txt不能是001.TXT。我第一次转格式的时候就是因为导出工具把后缀写成了大写训练时报了一堆文件找不到错误花了半天才发现是这个细节。3. 从零开始训练环境、命令、参数一次说清3.1 硬件与软件环境搭建训练这类检测模型硬件门槛没有想象中那么高。我实际用的是单张8G显存显卡跑YOLO小模型足够如果只有4G显存也能跑但batch size要降到8甚至4训练时间会明显变长。软件方面建议Python 3.10以上、PyTorch 2.x、对应版本的CUDA再从开源仓库拉取YOLO训练代码。这里最容易出的问题是CUDA、PyTorch和显卡驱动版本不匹配典型表现是torch.cuda.is_available()返回False。遇到这种情况先别怀疑硬件用nvidia-smi查看驱动支持的CUDA版本再对照PyTorch官方支持矩阵安装对应轮子基本都能解决。环境搭好后先下载一个预训练权重跑一次官方示例数据确认训练流程跑通再换成自己的数据集。这个验证步骤看起来多此一举实际能省下大量排查时间。3.2 data.yaml与训练命令模板数据准备好之后需要写一个data.yaml告诉训练脚本去哪里找数据、有哪些类别。我的写法是path: /home/yourname/supermarket-theft/ train: images/train val: images/val test: images/test nc: 3 names: [person, cart_bag, theft_act]这里nc必须和names列表长度一致names的顺序要和标签文件里的class_id严格对应。顺序一旦写错模型会把“人”当成“偷窃行为”去学损失降不下去验证指标也乱七八糟。训练命令我建议这样写python train.py --data data.yaml --weights yolov8s.pt --epochs 120 --batch-size 16 --img 640 --lr0 0.01我实际跑下来120轮在单张8G显卡上大约四到五小时。使用预训练权重做迁移学习是必须的从零训练不仅收敛慢mAP通常还会低几个点完全没有必要。3.3 几个关键超参数该怎么调训练过程里最值得盯的参数有三个。输入分辨率img 640是默认起点。如果小目标漏检严重可以提高到768但推理速度会下降、显存占用也会上涨需要结合部署设备权衡。我见过有些项目为了冲精度直接设到1280结果边缘设备根本跑不动只能在服务器上跑演示完全没有落地的意义。学习率lr0设0.01配合余弦衰减是比较稳的初始方案。如果损失曲线从头到尾都不降先尝试把学习率调低到0.001而不是盲目加大。反之如果验证loss直接炸掉大概率是学习率偏高或者batch size太小。一个实用的判断标准是观察前20轮的mAP曲线如果完全不涨说明学习率设置有问题。数据增强方面默认的Mosaic增强对提升泛化能力帮助很大相当于每次用四张图拼接成一张新样本。但Mosaic有两个坑大幅随机裁剪可能把关键动作裁丢当场景中存在大量相似背景时拼图会让模型学到错误的背景关联。我习惯把Mosaic概率从1.0降到0.5到0.7尤其是在数据本身比较“珍贵”的时候宁可增强少一点也要保证关键目标不被破坏。3.4 评估指标与部署上线的完整思路训练完先看验证集上的mAP0.5如果能在0.75以上就可以考虑部署应用了。但mAP高不代表误报低安防场景更关键的是Precision和Recall的平衡。我的经验是设置双阈值检测置信度0.25以上先记录但不告警连续若干帧都稳定超过0.6才推向告警模块。这个策略的好处是既不会漏掉可疑动作又能把单帧误报压掉不少。部署时模型可以导出成ONNX再转TensorRT做GPU加速。边缘设备上帧率紧张的话一个实用技巧是限制分析帧率比如每秒抽5帧做检测再配合帧间逻辑既省算力又不影响检出效果。多路摄像头场景下每路视频用一个子线程做解码和推理把结果汇总到队列里由告警模块统一消费吞吐量会比串行处理高出一大截。4. 实战难题与排查方案记录4.1 漏检、误报、迁移问题的落地解法先说漏检。偷窃动作本身短暂且目标小模型漏检频率比较高是常态。我遇到过最典型的情况训练图的标注框都集中在人的整体区域但真正关键的“手部动作”只有几十像素模型根本没注意到。后来调整标注策略把“手部区域”也作为单独目标框输出漏检明显下降。另外提高输入分辨率、做多尺度训练也能改善小目标检出。再说误报。最常见的误报是把顾客正常取货、翻包、整理衣服当偷窃。原因在于YOLO只能看单帧不知道前后文。解决办法很朴素用连续帧投票。具体实现上维护一个长度为5的滑动窗口5帧里有4帧都检出高置信度偷窃行为才确认告警。想做得更精细可在后面接一个时序分类网络。我实测这个策略能把误报率压掉一半以上代价仅仅是增加一点内存开销。迁移问题也很常见。在场景A训练好的模型换到场景B不同门店、不同摄像头角度性能可能大幅下滑。原因是数据分布变了货架颜色、光照亮度、摄像头高度全都不一样。我的做法是“现场微调”去新场地录制两三小时视频抽出500到1000帧做人工标注用原有模型作为预训练权重以0.001的学习率再训练20到30轮。这样通常能把mAP拉回到可用水平成本远低于重新采集几千张图。4.2 一张问题速查表为了平时排障方便我把常见问题整理成了下面这个表格问题现象可能的根因推荐处理方案漏检频发小目标、动作帧短提高输入分辨率、多尺度训练、补充手部/局部动作标注误报刷屏单帧检测无时序上下文连续帧投票、接入时序分类网络换场景效果大跌数据分布变化现场采集少量数据微调20-30轮损失不下降学习率过大或标签顺序错乱降低学习率、检查names顺序和标签ID推理带宽不足模型过大或线程处理串行导出ONNX/TensorRT、限制抽帧率、多线程解码告警延迟太高推理排队多路视频子线程并发告警逻辑与推理解耦这张表我常贴在项目组的共享文档里每次加新设备或者换站点先按表排查省掉大量沟通时间。5. 从静态检测到行为识别还能走多远5.1 跟踪与轨迹判断单帧检测做告警只能说是“入门版”。更进阶一点需要把同一个人的连续帧检测结果关联起来引入目标跟踪比如ByteTrack或DeepSORT。跟踪的价值在于给模型增加时间维度可以回答“这个人是不是一直把手放在包里”这类问题。同时跟踪还能避免同一行为被重复告警同一个track ID在几秒内不必重复推送用户体验会好很多。实现上先跑YOLO检测再把每帧检测框喂给跟踪器得到带ID的轨迹。对每条轨迹统计可疑时长、动作频率、是否接触货架等特征再制定规则。比如一个track ID在1秒内两次触发高置信度的“藏匿”检测系统才推送一次告警。这个逻辑比单纯累加帧数更稳误报率也能进一步下降。5.2 姿态估计与更轻量的时序识别更高阶的方案是姿态估计加行为识别。超市偷窃的本质是“手部动作异常”通过关键点检测得到手腕、手肘、肩颈的位置可以构造“手与包距离”“手与货架距离”这类几何特征判断动作是正常取货、放货还是藏匿。相比直接给整图分类这种结构化表达更抗遮挡可解释性也更好。如果不想上太重的模型轻量化时序方案也值得尝试。先用YOLO做目标裁剪得到目标区域后再过一个小型时序网络比如TSM或带时序卷积的分类器判断片段类别。整个pipeline在边缘盒子上的推理时间能控制在几十毫秒内足以支撑实时告警。这种“检测裁剪时序分类”的模式比直接把整个视频帧序列塞进大模型要便宜得多。5.3 商业落地的合规与硬件考量最后说落地部分这也是我在项目中体会最深的地方。第一是隐私合规超市监控涉及普通顾客的肖像与行为数据系统应当对人脸区域做模糊或脱敏处理告警只输出行为信息不输出能够直接识别到具体个人的影像。任何数据集和模型的使用都必须围绕适用的隐私规则来设计不能拿合规当儿戏。第二是成本控制。并不是所有门店都需要服务器级设备。如果需求只在货架区识别“可疑蹲下、藏匿”这类粗粒度行为一台带NPU的边缘盒子加普通摄像头就够单店成本很低只有要做全店多路并发、高帧率全量分析时才需要考虑独立计算节点。实际部署中我更推荐“AI巡检人工复核”的混合模式让系统把最可疑的画面挑出来人来最后确认在成本、准确率和隐私之间找到平衡点。我自己跑这套数据集的过程中最深的体会是标注一致性比数据总量更影响最终效果连贯帧判定比单帧判断更接近真实需求。如果你准备上手偷窃行为检测建议先用这套4000张高质量标注图像配合YOLO把单店场景完整跑通把“检测—跟踪—告警—人工复核”的闭环搭起来再考虑横向扩容。换到新场景时一定补一点现场数据做微调效果会完全不一样。这套从数据出发的工程思路不只适用于超市换到仓库、园区等其他异常行为识别场景做法同样成立。