我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

FCOS+HRNetV2P货架空置检测实战:从训练到部署全解析

FCOS+HRNetV2P货架空置检测实战:从训练到部署全解析 上个月我们团队刚把一套货架空置检测算法从实验原型搬到了某个连锁超市的监控端实测稳定跑了两周缺货漏报率压到了可以接受的水平。这套方案的检测核心就是标题里写的 FCOS_HRNetV2P 模型——用 HRNetV2P 做骨干网络提特征FCOS 做无锚框检测头。今天这篇就当一次踩坑总结从数据准备、模型选型、训练调参到部署落地把完整链路拆开讲清楚给同样在做零售巡检方向的同行一点参考。这类需求在零售行业越来越常见货架缺货、空置如果不能及时被发现直接影响销售额和客户体验。人工巡店成本高、频率低而且不同门店的执行标准还不一样靠人盯基本盯不过来。用视觉算法自动检测空置区域是货架巡检数字化的核心环节。1. 为什么超市货架空置检测需要专门设计1.1 超市场景下的检测难点与需求货架空置检测表面上就是一个目标检测任务真正做了才发现场景里的坑比想象中多得多。首先是目标形态极其不规则一瓶饮料被拿走留下的空档可能是又窄又长的竖条一箱方便面被搬走半排空出来的是一个整块区域有些货架层板是倾斜的商品被拿走后还会露出层板上的标价条视觉上干扰特别大。其次是光照环境非常复杂。超市里通常混合了日光灯、冷柜灯、自然光和广告牌灯光不同货架区域色温不一致同一货架在一天内各个时段的光照变化也很大。尤其那些带塑料封层的货架反光强的时候会产生明显的白色光斑这种光斑在视觉上和空置区域非常像传统图像处理很容易被带偏。还有一个常被忽略的问题是干扰物体的遮挡。顾客的手臂、购物车、促销标语牌、价格标签、未拆封的整箱货品堆头都会遮挡货架的实际陈列状态。算法如果不够鲁棒很容易把顾客的手部区域或者影子误检成空置。从业务需求角度看这个检测任务真正关注的信息有两个哪里缺货、缺了多少。输出结果要精细到货架的层、排位置才能让补货人员快速定位。这就要求检测模型不能只输出一个粗糙的框还要保证高召回率——漏报的空置比误报的危害更大因为误报最多浪费一个补货员跑冤枉路漏报则是直接损失销售机会。1.2 传统人工巡店与规则算法的局限很多团队刚接触这个需求时第一反应是用传统视觉方案做比如背景差分、颜色阈值、边缘检测。我们早期也试过这些路线效果不理想。背景差分依赖静态背景建模货架上的商品频繁被拿放背景本身一直在变差分法很快失效。颜色阈值就更不稳定白色商品放在浅色货架背景上时颜色分割几乎是无效的反过来深色商品被拿走后露出的深色背景区域也很难单独靠颜色识别出来。人工巡店的局限则更明显。一个中等规模的超市SKU动辄上万货架排面数量巨大一名巡店员每天巡完所有货架要花几个小时而且注意力很难全程保持。很多缺货区域在被发现之前可能已经空置了几个小时。所以在这个场景下引入深度学习目标检测模型是必然选择——它学的是“空置区域”的高层语义特征而不是简单的颜色和边缘信息。这里的核心需求总结起来就是三点高召回率尤其是细长型空置区域抗光照和遮挡干扰推理速度要能支撑高频巡检。这三点直接决定了模型选型的走向。2. FCOS与HRNetV2P技术组合的选型逻辑2.1 FCOS核心原理anchor-free与center-nessFCOS是2019年提出的全卷积单阶段目标检测器和当时主流的anchor-based方法相比最大的特点就是去掉了锚框。YOLOv3、Faster R-CNN那一代方法都需要预先设计一组不同宽高比、不同尺度的锚框然后在训练时计算锚框和真实框之间的匹配关系。问题在于锚框的超参数设计非常依赖经验而且对目标形状的分布很敏感。货架空置区域的形状分布跨度极大可能是2:1的横条也可能是1:5的竖条还可能是接近1:1的方坑。如果预设的anchor比例没有覆盖到某些极端长宽比检测效果就会打折。FCOS直接让特征图上每个位置回归到目标边界四边的距离彻底绕开了anchor匹配的麻烦。具体来说对于特征图上的每个位置如果它映射回原图后落在某个真实框内就是正样本回归目标就是该位置到真实框四条边的距离l、t、r、b。如果落在多个框内就选面积最小的那个框作为回归目标。不过FCOS这种设计有个已知问题由于没有anchor的筛选机制会产生大量偏离目标中心点的低质量预测框。论文里的解决方案是增加一个并行分支预测中心度center-ness。这个分支计算当前位置到目标中心的归一化距离训练目标是中心位置为1、边缘为0的连续值。推理时用center-ness分数乘上分类置信度作为最终得分就能有效地把那些偏离中心的框压下去。2.2 HRNetV2P骨干网络高分辨率特征保留的意义骨干网络的选择也很关键。很多经典检测模型用的是ResNet这类先下采样再上采样的网络特征图经过多次降采样后小目标的细节信息会丢失不少。货架空置检测恰恰需要细腻的边缘和纹理信息——很多空置区域是细长的缝隙周围商品的纹理和标签直接决定了缝隙的边界在哪里。HRNet的核心思路和ResNet不一样它从头到尾始终保持一个高分辨率分支同时并行连接多个低分辨率分支各个分辨率的分支之间反复交换信息保证高分辨率分支能获得充分的语义信息低分辨率分支也能保留空间细节。HRNetV2P是专门为检测和分割设计的一个变体它把不同分辨率分支的输出分别作为特征金字塔的不同层供后续检测头使用。在实际表现上HRNetV2P对细长目标和小目标的特征表达能力明显优于同尺寸的ResNet系列。我们曾经做过单独替换backbone的对比实验在相同的FCOS检测头下HRNetV2P-48在验证集上mAP比ResNet-50高出不少尤其在小目标类别上的提升幅度更大。这个结果基本符合预期因为货架上的空置缝隙在整幅监控画面里往往只占很小的像素比例高分辨率特征正好能抓住这些细节。2.3 两者结合如何适配货架空置检测FCOS加上HRNetV2P的组合放在货架空置检测这个场景里有三个直接优势。第一HRNetV2P输出的多尺度特征金字塔底层高分辨率特征适合检测细长小空位高层语义特征适合检测大块缺货区域天然适配空置区域多尺度差异大的特点。第二FCOS的center-ness机制对不规则的货架空置区域有很好的抑制作用因为大多数空置区域的形状虽然不是规则矩形但中心区域确实是空置状态最明显的部分用中心权重来筛选预测框和业务直觉是吻合的。第三整套模型是单阶段的推理速度快部署到监控端设备上能做到实时或准实时。当时我们还对比过其他方案比如YOLOv5加自定义anchor、Faster R-CNN加FPN。YOLOv5的速度确实快但在细长空置区域的召回率上始终差一口气反复调整anchor也无济于事Faster R-CNN精度不错但单阶段少了两阶段部署和优化成本都更高。最终选择了FCOS_HRNetV2P这个组合是精度、速度和工程复杂度的综合平衡。3. 数据准备与标注决定算法上限的关键环节3.1 数据采集策略与场景覆盖在训练阶段投入最大的往往不是调参而是数据。模型对空置区域的理解程度完全取决于训练数据里见过多少种空置形态。数据采集策略上我们踩了不少坑后才总结出一套比较完整的方法。最关键的教训是不要只采一个门店的图片。我们第一版模型在A门店测试效果很好换到B门店后mAP直接掉了好几个点。原因很简单不同门店的货架材质、颜色、灯光布置、货架间距全都不一样。后来重新采集了五家不同定位的门店数据覆盖了不同品牌货架、不同层板颜色、不同照明环境模型的泛化能力才上来。采集方式上我们用的是固定在货架通道上方的监控摄像头俯仰角大概30度左右视野以一层货架为主。每5秒取一帧不同时段连续采集保证样本覆盖早晨、中午、傍晚、夜间补光灯开启等各个光照条件。建议采集总量不少于8000到10000张图实际标注下来大概能产生3到5万个空置区域实例。还有一个容易忽视的点货架空置状态是动态变化的有些空置只持续几分钟就被补货了。所以我们在采集数据时会刻意在补货前、补货中、补货后三个时间窗口分别采样确保模型见过不同阶段的空置形态。3.2 空置区域标注方案与工具选择标注方案直接影响训练效果。我们最初用单类别“空置”做标注全部空置区域都框成一个矩形。跑了一轮后发现一个问题有些框很大很完整是半排商品被搬空的状态有些框又细又长只是单瓶商品留下的缝隙。这两类数据混在一起模型的检测精度被拉低了。后来改成了双类别标注方案一类是“完全空置”整个槽位都没有商品另一类是“部分空置”商品明显不足但还有残留。这两个类别在业务上也有区分价值完全空置需要紧急补货部分空置可以按计划周期补。训练完成后再根据置信度和框的长宽比合成业务规则决定优先级。标注质量方面核心要求是框要贴边不能把旁边相邻的商品包进去。尤其是细长缝隙稍微标宽一些就会引入大量背景噪声。我们团队内部制定了一个标准框和实际空置边缘的距离不得超过像素宽度的5%。占位和边界有争议的样本标注负责人会逐张复核。标注工具我们用的是某开源图像标注工具配合自定义的标签预设速度能快不少。3.3 数据增强策略与避坑数据增强在零售场景里尤其重要因为光照差异是跨门店泛化最大的敌人。我们用的增强管线包括亮度扰动亮度调整范围设在正负30%左右模拟不同时段灯光差异。对比度和饱和度扰动超市里LED广告牌的光线会让货架区域出现各种偏色饱和度和对比度扰动有助于模型抗色偏。随机缩放和裁剪尺度扰动范围设在0.4到1.6倍增强模型对不同相机安装高度和视角的适应性。轻微旋转和平移旋转角度控制在正负10度以内模拟相机安装的微小偏差。随机遮挡模拟顾客身体、手臂等物体对货架的遮挡。需要注意货架图片不适合做水平翻转的数据增强。虽然货架本身左右对称但超市灯光方向往往固定从一侧打过来水平翻转会让阴影方向反转反而引入分布偏差。我们做过对比实验加了水平翻转后验证集mAP反而略微下降后来就把这个增强去掉了。还有一个细节不要把增强强度拉得过大货架空置检测的目标是真实场景复现不是苛刻的数据竞赛过度增强会让模型对真实分布的敏感度下降。4. 模型训练全流程与关键参数调优4.1 环境搭建与训练配置训练框架我们基于PyTorch和MMDetection来实现这个组合的好处是FCOS和HRNetV2P的backbone都有现成配置不用从零写。训练环境用的是单机8卡GPU服务器模型并行和数据并行都试过货架空置检测的输入图尺寸不算太大单卡显存占用也就在8到12GB左右8卡并行训练一轮大约需要30到40分钟。具体的训练超参数我把一套实测效果不错的配置放在下面供参考参数配置值说明输入尺寸短边 800长边 1333覆盖大空置区域和细长缝隙骨干网络HRNetV2P-W48通道宽度适中速度与精度平衡预训练权重ImageNet分类预训练加快收敛速度优化器SGDmomentum 0.9weight decay 1e-4初始学习率1e-3配合500步warmup批量大小8每卡1张总batch 8配合8卡训练轮数24个epoch验证集mAP通常在20轮后趋于平稳学习率衰减第16和第22轮衰减10倍多尺度训练本身已经有一定正则效果输入尺寸的选择上我们没有直接用常见的1333x800而是根据实际货架画面比例做了调整。货架通道的监控画面通常是比较高的竖构图空置区域在画面中占的比例参差不齐短边800、长边1333这个经验值兼顾了细节和显存开销实测效果比纯正方形输入高一些。4.2 损失函数与训练监控FCOS_HRNetV2P的损失函数分为三部分。分类损失用的是focal loss处理正负样本极度不平衡的问题——货架画面上绝大多数区域不是空置负样本数量远大于正样本。focal loss通过调制系数把简单负样本的损失权重降下来让模型把注意力集中在少数空置区域上。回归损失我们用的是GIoU loss相比传统的smooth L1GIoU能更直接地优化预测框和真实框的IoU对空置区域这种形状不规则的框效果更好。center-ness分支则用BCE loss。训练过程中需要重点监控三个曲线的变化总loss下降趋势、分类loss和回归loss的分离程度、验证集mAP的爬升曲线。如果分类loss下降明显但回归loss迟迟不动通常是回归目标的归一化出了问题检查一下真实框标注是否有大量异常值。反过来如果回归正常但分类loss波动大多半是正负样本采样策略的问题可以尝试调整focal loss的alpha和gamma参数。默认配置下alpha为0.25、gamma为2.0货架场景下gamma调到2.5会有轻微提升因为空置区域和背景的区分难度比通用检测场景更高。4.3 性能评估指标解读目标检测通用的评估指标是mAP但货架空置检测这个业务场景mAP只能作为一个参考维度真正落地的指标是业务方关心的精确率、召回率以及“定位精度”。我们内部主要关注三个指标全类别mAP0.5:0.95空置类别的召回率IoU≥0.5置信度阈值取0.5以及误报率每百帧图的平均误检框数。最终模型在验证集上的成绩大概是mAP0.5:0.95为0.48左右完全空置类别的召回率接近92%部分空置类别召回率在85%上下。这个成绩单看数字不是最顶尖的但在零售真实场景的复杂光照和遮挡条件下已经足够支撑业务运行。这里要提醒一个常见误区AI团队容易只盯mAP忽略了业务对定位精度的要求。货架空置检测的定位精度影响很大——同一个空置区域检测框是精确框在空置缝隙上还是把旁边商品也包了进去直接决定了补货人员能否快速找到位置。所以我们在验证集评估之外还会人工抽检一部分预测结果确认框的边缘贴合度是否满足业务要求。5. 部署推理与工程落地5.1 模型转换与加速优化模型训练完之后就是部署推理优化。PyTorch模型直接跑推理会产生较大的框架开销我们首先把模型导出为ONNX格式再转换为TensorRT的FP16引擎。FP16精度对精度的影响非常小在我们的验证集上mAP几乎没有明显下降但推理速度提升了将近两倍。TensorRT的转换过程中有几个注意事项。一是FCOS的center-ness分支和回归分支的输出需要在后处理中合并计算导出ONNX时最好把这些操作一并封装到图里否则在TensorRT端还得用DLL插件实现。二是HRNetV2P的多分辨率融合结构在TensorRT下会有一些算子融合上的兼容问题实测下来用TensorRT 8.x版本配合对应的PyTorch版本能顺利构建引擎太新的版本反而可能遇到兼容性问题。三是动态输入尺寸问题我们在部署端固定了输入尺寸避免动态shape带来的额外开销。转换后单张1080p图片在边缘盒子上推理耗时大约在30毫秒左右已经能满足实时巡检的需求。如果部署的相机更多建议用多路流并发推理TensorRT的上下文池可以复用显存占用不会成倍增长。5.2 端到端推理流程设计完整的推理流程不是简单地把图丢给模型而是围绕业务规则做了几层封装。采集端摄像头以固定帧率抓拍先做预处理包括去畸变、裁剪ROI区域、颜色校正。货架画面中存在大量非检测目标区域我们会在首次部署时手动标注一次货架的区域多边形之后只在这个区域内做检测能大幅降低误报率。预处理之后进入检测推理得到空置区域的所有候选框。后处理阶段先做NMS去重再用业务规则过滤置信度低于0.4的框去掉宽高比大于4比1或小于1比4的极端细长框重点人工复核因为这种形态有可能是货架缝隙而非真实空置。最后把检测结果映射回货架编号和层排编号生成格式化的补货任务单。这套流程在边缘设备上运行产生的任务单通过消息队列推送到后端管理系统。5.3 实际部署架构与监控部署架构上我们采用了边缘计算加云端管理的模式。每个门店部署一台边缘盒子盒子负责实时推理和结果上报云端负责模型更新和任务管理。这样做的核心考量是带宽成本和稳定性门店监控视频流数据量很大全部上传到云端会占用大量带宽而且断网时巡检任务就中断了。边缘盒子本地跑推理云端只接收轻量的结果数据即使网络断了也能在本地缓存结果恢复后自动补传。模型更新方面云端训练好的新模型会通过静默方式下发到边缘盒子采用双模型热切换机制新模型先在少量测试画面上跑一轮确认无误再切换。远程侧每台设备都配置了推理时间、GPU温度、内存占用、检测结果数量等指标接入监控告警系统。一旦检测数量异常波动或推理耗时异常上升就能及时远程排查。6. 常见问题与排查技巧实录6.1 误检与漏检典型案例实际运行中我们遇到过不少疑难案例这里挑三个典型的分享。第一个是高光反射误检。超市货架上的塑料封层和层板标签在强光下会产生白色耀斑视觉上和空置区域的白色背景非常相似模型经常把耀斑识别成空置。排查后发现训练数据里高光样本太少后来的对策是在数据采集时有意识地覆盖了正午和补光灯全开的时段并给增强管线加入了随机高光光斑模拟误检率立刻下降。第二个案例是白色商品在浅色货架背景下的漏检。当一瓶白色洗衣液被拿走后留下的空置缝隙和旁边白色商品的边界很难区分模型输出置信度偏低导致漏报。这个问题的根本原因是场景语义区分不足单靠视觉特征很难彻底解决。我们的处理方案是结合货架排面的固定槽位信息用先验知识辅助判断——每个槽位如果有黑色背板那么背板区域的颜色突变就是强信号如果槽位也是浅色的则用边缘纹理做二次校验。第三个案例是部分遮挡误检。顾客的手臂横在货架前时模型可能把手臂下的阴影区域误判为空置。这个不能完全靠模型解决需要在业务规则上做约束边缘盒子只在店内人流量较低的时段发起巡检推理或者结合门店的人流量传感器做联动有人群经过时不输出判定结果。6.2 训练不收敛问题排查训练过程中遇到的最典型问题是loss上升为NaN。我们第一次遇到时检查后发现是数据标注里混进了几个面积为零的异常框导致回归loss计算时出现除零。解决方法是数据预处理阶段加一个合法框过滤逻辑剔除面积小于某阈值或坐标越界的框。另一个常见问题是总loss下降到一定程度后不再变化但验证集mAP持续在低水平徘徊。排查思路是先确认是欠拟合还是过拟合训练loss低但验证loss高是过拟合需要加数据增强或dropout训练和验证loss同时停滞则可能是学习率过低或模型容量不足。货架空置检测场景中我们遇到的是后一种把骨干网络从HRNetV2P-W18换到W48后指标立刻有明显提升。此外anchor-free模型对正样本定义很敏感。FCOS中只有落在真实框内部的特征点才算正样本如果空置区域标注得过于窄长落在内部的点就特别少正样本数量不足会导致训练不稳定。我们试过降低正样本匹配的阈值效果不明显后来发现更有效的做法是增加多尺度训练时的高分辨率分支权重让更多细长空置区域的特征点参与回归训练稳定度显著改善。6.3 实测中的独家避坑技巧代码和配置层面的经验说完了再说几个只在实跑中才能遇到的坑。第一边缘盒子的CPU型号和指令集对推理速度影响极大TensorRT的算子会根据硬件平台生成不同实现同一模型在不同型号盒子上推理耗时可能差一倍。所以部署前先确认目标设备的GPU架构导出引擎时用对应的平台参数不要直接用同一份engine包到处拷贝。第二货架空置检测模型的一个隐藏业务场景是“空置序列模式”。连续多个相邻槽位同时空置往往意味着不是简单的单瓶缺货而是整个品类供货出了问题。我们在后处理里增加了一个简单逻辑如果检测到三个及以上的相邻空置框就把它们合并成大范围缺货警报。这个逻辑虽然简单但业务方非常认可因为它直接推动了供应链的补货优先级调整。第三验证集划分要多预留一个门店作为最终盲测集。很多团队随机划分训练集和验证集同一个门店的不同时段图片会同时出现在两边导致验证指标虚高。我们后期特意留出两家从未参与训练的门店做盲测真实泛化性能才看得清楚。再分享一个经验货架保养补货的时间窗口。每次大规模补货动作前货架状态最“干净”是采集高质量正样本的好时机——这时候检测出的空置区域大多是真实的标注工作高效。补货进行中则能拍到各种中间状态适合增加模型对“半空置”形态的鲁棒性。合理规划采集时段能让数据质量事半功倍。每次遇到检测效果问题我第一反应永远是去翻数据而不是动网络结构这个优先级顺序省了我们大量时间。
返回列表