ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

2800张手机检测YOLO数据集全流程实践:从标注到部署

2800张手机检测YOLO数据集全流程实践:从标注到部署 手头这套“手机检测数据集 | 2800张YOLO目标检测数据集”是我在去年一个内部项目里从零攒起来的。做监控场景的智能识别时经常要判断画面里有没有人违规使用手机一开始试过通用目标检测模型但准确率始终上不去——问题就出在数据手机这玩意儿目标小、外观千奇百怪套壳、反光、半遮挡泛化起来特别麻烦。所以干脆自己收集、清洗、标注了这批数据用YOLO系列模型跑通了训练、验证和部署的整个闭环。成品是2831张图像、接近1.2万个标注框质量可控代码和标注脚本也都顺手整理好了。这篇东西不聊虚的就把我怎么设计类别、怎么标数据、怎么调YOLO参数、怎么避坑的整个过程拆开讲适合刚接触目标检测的初学者也适合想在自定义数据集上做落地验证的算法工程师。1. 数据集的设计思路与场景定位1.1 为什么专门做手机检测数据集手机检测听起来简单做起来全是细节。我最初的需求是在办公室、机房、考场这类半封闭场景里用固定摄像头识别人手是否持有手机。但直接拿COCO这类公开数据集的“cell phone”类别去跑发现误检率特别高——桌子上的鼠标、遥控器、眼镜盒经常被当成手机。原因也直观公开数据集里手机样本占比少且多是手持完整露出的画面真实监控里屏幕朝下、被手遮住一半、灯光反射发花的情况占了绝大多数。所以这批数据集的定位很明确面向“小目标、局部遮挡、复杂背景”的移动设备检测。不是简单把手机照片堆一堆而是按真实监控视角去构造负样本和正样本比例。2800张图里真正完整露出的手机大概只占55%其余都是半遮挡、远距离、躺桌面或握在手里的状态。当时定这个比例就是为了让模型别养成“只能认出完整手机”的惰性。1.2 数据集的类别体系与统计口径我只做了单类别“phone”没有拆“brand”“withScreen”之类的细分。原因很实际标注人员对品牌识别的分歧大而且YOLO模型的类别越多收敛越慢对部署在边缘设备上的模型反而不友好。最终类别就一个但同类别里包含了多种状态状态图像张数标注框数占比手持完整露出921402132.5%手持局部遮挡634287723.2%桌面平放/充电783310225.1%口袋外露半截2238927.2%远距离小目标(小于32px)27012089.7%训练/验证/测试按8:1:1划分划分时特意用脚本保证每个文件夹里的状态比例和整体一致而不是随机瞎切。否则可能验证集里全是完整手机训练集里全是遮挡评估出来的mAP会虚高。1.3 为什么选YOLO而非其他目标检测算法单纯说“想用YOLO”没意思我对比过Faster R-CNN和SSD。Faster R-CNN在遮挡场景精度确实高一点但推理速度只有YOLOv8的1/6在只有CPU的现场试过一遍完全跑不动。SSD对小目标不友好MobileNet骨架经常把远处耳机当手机。YOLO特别是v8之后anchor-free设计让头部结构更简单对小目标的适应能力强不少加上工程生态成熟导出ONNX、TensorRT都有人踩过坑部署时遇到问题也好搜。这款数据集不开源算法代码只提供标注数据和脚本但用YOLOv5s或YOLOv8n跑都能在GTX 1060上7个小时内完成训练门槛够低。2. 数据采集与标注的全过程2.1 采集策略别只拍“漂亮图”采集这2800张图花了两周。第一周在实验室和办公室用手机虽然目标是检测手机但采集设备用相机就行拍了大量单机图发现背景太干净训练后模型到了真实走廊直接傻眼。第二周调整策略加入了几个关键变化视角多样化摄像头高度1.5米、2.5米、3.5米各拍一部分模拟不同安装高度。低角度拍到的手机侧面轮廓和俯拍完全不同必须都要有。光环境覆盖白炽灯、日光、黄昏逆光、屏幕反光四类各拍不少于300张。屏幕亮着和息屏的框体特征差异很大我统计过模型对“亮屏手机”的置信度普遍比“息屏手机”高0.1~0.2所以两类都要有。干扰物混入特意拍了一些只有遥控器、移动电源、计算器的场景放进训练集作为背景负样本。YOLO的训练逻辑是“没标注的位置就是背景”这些图能强制模型学会区分。2.2 标注工具与格式转换标注用labelImg和X-AnyLabeling都试过。labelImg老牌稳定快捷键效率高适合单人标注1600张X-AnyLabeling有自动分割模型可以预标注但手机会因为反光被切碎反而要改更多框。最后主力就用labelImg导出Pascal VOC格式再写脚本转成YOLO的txt格式。转换脚本是这类项目里最容易出乱子的环节。我在这里踩过一个坑labelImg导出的是difficult字段有些难例被标记成difficult1但YOLO训练时会把所有未标注区域都当背景如果直接把难例放进训练集等于告诉模型“这种难例你随便处理”导致那些半遮挡手机反而学不出来。正确做法是把difficult1的样本单独拿出来要么重标要么直接删掉难例或者把难例放进验证集评估鲁棒性不要进训练集。标注框的尺寸我还做了归一化统计发现很多框的宽高比集中在0.4到0.8之间这说明手机横屏拍摄的多、竖屏的少后续数据增强里我补了90°旋转来平衡。以下是标注坐标转换的要点# VOC的xmin,ymin,xmax,ymax - YOLO的x_center,y_center,width,height x_center (xmin xmax) / 2 / img_width y_center (ymin ymax) / 2 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height # 注意所有坐标必须归一化到[0,1]否则训练会直接nan2.3 数据清洗与质量复核标注完成不等于能训练。我教出来的经验是第一遍粗标、第二遍必须复查而且复查要用“独立视角”——就是不要看着原图而是在模型预测的基础上修正。具体操作先用YOLOv5s在这个初始数据集上训一个临时模型让它预测200张验证图再把预测结果框画出来人工看。凡是模型置信度很高但确实标错的都是清洗重点。清洗中发现的最典型问题有两类一是把屏幕反光亮斑标成了手机高光泽背景的锅二是把两只紧挨的手机标成了一个框。前者直接删图或剪掉反光区域后者拆分成两个框。这样跑完一轮标注框的数量从初始的1.2万减少到1.18万看似没变多少但置信度上限干净了不少。3. YOLO模型训练的全流程与参数细节3.1 环境准备与依赖安装训练用YOLOv8n起步后来对比过YOLOv5u两者都能跑。环境配置我写了张简洁的清单组件版本Ubuntu 22.0422.04.3 LTSPython3.10CUDA11.8PyTorch2.1.0ultralytics8.0.220这里特别提醒CUDA版本和PyTorch的编译版本必须匹配装错的话训练时会出现“Torch not compiled with CUDA enabled”的报错。装完先运行一个10张图的小测试确认能掉loss再开始正式训练。装依赖时还有个隐性问题opencv-python和opencv-contrib-python如果同时装会导致图像读取崩溃我的做法是只用opencv-python不要装contrib版。3.2 训练参数的选择逻辑第一次训练我用默认参数跑mAP0.5到了0.89但mAP0.5:0.95只有0.42说明定位和分类的“精”度不够。后来调参的核心集中在img size、batch size、epochs三个变量上。img size640手机属于小目标如果img size设到320很多小于40像素的目标会直接被下采样到10像素以下信息完全丢失。640是精度和显存平衡的选择GTX 1060 6G显存刚好带得动batch16。batch size16显存不够就减小batch同时减学习率。我用默认lr0.01配batch16刚好如果batch降到8记得把lr降到0.005否则容易震荡。epochs200前120轮loss下降明显后80轮主要用来稳定边界框回归。用早停机制patience30防止过拟合。训练配置文件里我改了一个关键超参——scale0.8。这个参数控制随机缩放增强的强度默认是0.5但手机小目标多我放大到0.8让模型多看到不同尺度的目标。flipud垂直翻转关闭了因为真实监控不会倒立着拍手机水平翻转保留因为手机左右朝向不影响语义。3.3 Loss函数的作用与观察方法YOLOv8的loss由三部分组成box_lossCIoU、cls_lossBCE、dfl_lossDistribution Focal Loss。我第一周在训练日志里发现dfl_loss降得特别慢查了下原理——DFL是为了让边界框回归更精准对小目标的定位精度提升很明显但收敛需要更多迭代。所以我采用了两个针对性技巧前50轮冻结backbone只训练head部分。先用大学习率让head快速适应数据50轮后再解冻backbone做微调最终mAP0.5:0.95从0.42升到0.51。设close_mosaic10最后10轮关闭mosaic增强避免过度增强导致小目标被拼接背景混淆。这招是从YOLOv5训练经验里学来的实测验证精度提高2%左右。3.4 训练过程监控与断点续练跑训练的那几天我基本每小时看一眼日志。重点看P精准率和R召回率的趋势而不是光盯loss。有次训练到第60轮时R突然从0.83跌到0.71排查发现是验证集里混入了几张dark模式下屏幕亮起而背景全黑的图模型直接预测不出来排除那张坏图后指标恢复正常。监控时常用两个小scrip一个用torch.cuda.memory_summary()看显存占用一个用plot_results输出曲线图。断点续练是必须掌握的技能。训练到150轮时机器重启如果不续练就得从头跑7个小时全浪费。我用训练中断后最后一个.pt文件继续命令里设resumeTrue即可但要注意必须用原项目目录和配置目录变了会找不到路径报错。4. 模型评估指标与常见问题排查4.1 mAP、混淆矩阵和置信度阈值的选择评估这套手机检测模型不能只看mAP。我用三个指标组合看mAP0.5、mAP0.5:0.95、F1-score。mAP0.5高只代表“大概框对了”实际投产时还需要看置信度阈值选择。我用验证集上的Precision-Recall曲线找到F1最高的阈值是0.45但真实场景中我会调高到0.55因为漏报没检测到手机比误报把遥控器当手机更致命宁愿漏一点也要减少错误报警。混淆矩阵也是必看的。YOLOv8训练完会自动生成confusion_matrix.png我看了以后发现很多“背景被预测成手机”的样本集中在透明手机壳和玻璃桌面反光上。针对这个我在后续数据增强里加了hsv_h0.015、hsv_s0.7、hsv_v0.4这种颜色扰动让模型学会忽略反光差异。4.2 过拟合与数据不均衡的处理手机上万物联动的场景里数据不均衡经常出问题。手机检测数据集里“远距离小目标”只有9.7%的框导致模型对这类目标召回率偏低。我的处理方案有三条过采样小目标图像把远距离图像复制一份放入训练集但复制时随机裁剪放大到中等尺寸避免完全重复造成过拟合。调整anchor仅YOLOv5有效用autoanchor重新计算anchor尺寸因为默认anchor是为COCO数据集的通用目标设计的手机这种小目标需要更小的初始anchor。YOLOv8是无anchor的但尺度scale0.8已经能缓解问题。加入小目标切片SAHI推理时把图像切成4块分别预测再合并这个能显著提升小目标召回率但代价是推理时间翻倍只在离线场景使用。4.3 常见问题速查表我把训练过程中遇到的典型问题和解法整理成了一个表方便有需要的人直接抄作业现象可能原因排查思路Loss出现NaN学习率过大或数据有NaN标注检查标注文件中是否有空值降lr至1/10训练正常但验证mAP为0验证集和训练集类别不一致检查验证集.txt里是否有错误类别id推理结果框偏大标注框边缘“切”太紧了检查标注时是否紧贴目标换自动标注模型重标模型把所有亮斑当手机反光样本不够增加曝光和反光增强或者手动补拍亮屏图小目标漏检严重下采样损失大改用640输入并加SAHI推理不要用3204.4 部署阶段的精度损失控制训练完成后导出ONNX再用TensorRT转换中间如果直接转float16mAP会从0.51掉到0.44。我试过在命令行加--fp16推理速度快了40%但小目标精度掉得太狠。最后选择用混合精度转第一层保持fp32backbone后半段和head用fp16这样mAP只损失1.2%速度却提升了30%。具体做法是用TensorRT的动态范围校准跑100张验证图做校准再转比直接强制fp16稳得多。5. 数据集后续扩展与我的实践体会5.1 数据增强的进阶玩法基础数据增强之外我还试过给手机检测专用的特殊增强手法。最有价值的两个cutout和随机遮挡。Cutout就是把图像中心一块随机挖去逼模型不要只依赖中心特征随机遮挡是专门把手机的一部分用色块盖住模拟人手遮挡场景。两个都做之后测试集上“半遮挡手机”的召回率提升了8%。另外强烈建议训练时加mixup0.1不调太高否则手机和背景糊在一起小目标反而学不到。以前我贪心设到0.3结果mAP掉了4个点这东西就是过犹不及。5.2 这批数据能用来干什么这套数据集除了直接训练手机检测模型还能做几个变体扩展到饮酒检测或行为分析很多场景需要识别手部行为和物体关系手机检测可以作为手部姿态检测的前置模块。用于隐私保护的区域检测在涉密区域检测到手机就报警合法合规的安防场景适用。作为小目标检测的benchmark由于包含9.7%的小目标样本用来验证新模型的小目标性能很顺手。我在实际项目中还发现把手机检测和人员检测两个模型并行跑然后判断二者边框的IoU如果人员和手机框重叠度高就是“手持手机”否则可能是“桌面手机”这个逻辑能过滤不少误报。5.3 关于数据集的一些真心话2800张图对深度学习来说不算多但在目标检测这个细分领域质量胜过数量。我最后没一味追求“更多数据”而是反复清洗、增强、调整分布最终效果比用1万张粗糙数据更好。标注数据这活儿一天标300张就已经快眼花中间还因为连续标注把“手机在手里”的框画偏了不少后来休息好复查才发现。个人最深的体会是目标检测项目真正的门槛不在模型而在数据集的可控度。数据分布、标注质量、增强策略三者任何一个出问题后续调参都是徒劳。这套数据集我也还在持续迭代下一步准备补充更多夜间红外光线下的手机图像解决低照度场景下的漏检问题也考虑把标注格式统一成标准COCO方便更多人上手。如果你也要做类似的数据集项目建议从小规模开始先把标注规范定死再扩数据别一上来就追求数量。希望这篇实践笔记对你有用有什么具体问题欢迎在评论区聊。
返回列表