资讯详情

YOLOv8实战:623张仓库工人图像训练安全检测模型

📅 2026/10/4 4:20:14 | 华诺云谱 👁 阅读
YOLOv8实战:623张仓库工人图像训练安全检测模型
简介仓库工人作业场景的目标检测数据集适合物流仓储安全监控相关项目面向使用YOLO系列算法进行模型训练的开发者与研究人员解决数据采集和标注耗时的问题。压缩包共包含1870个文件其中623张jpg原图与623个txt标注文件、623个xml标注文件一一对应并附带1个yaml配置文件包体约30.25MB结构清晰按训练集与验证集划分无需自行整理。txt标注采用YOLO格式每行记录类别索引与归一化后的中心点坐标、宽度、高度坐标值均在01之间可直接用于yolov5、yolov7、yolov8、yolov9、yolov10及yolo11等版本训练这种归一化坐标不受图像缩放影响可保证标注位置准确。xml标注兼容VOC格式便于与已有工具链衔接两种格式分别存放可按需选用。目前已有43人学习使用数据集整体轻量适合实时检测、行为识别等安全类应用开发减少标注成本加快模型迭代。1. 仓库工人数据集配YOLO623张带标签图像能做什么仓库监控里最常被问的问题不是“模型准不准”而是“夜班能不能认出没穿反光背心的人”。yolo算法在工业视觉里落地最多的场景之一就是用仓库工人数据集训练安全检测模型。这套命名为“掌舵安全”的warehouse数据集623张图像带标签每张都有人工画好的框和类别足以跑通一版能用的YOLO检测器。适合两类人刚用yolov8训练自己的数据集、想把标注变成模型的初学者以及要快速验证仓库安全方案的工程师。如果你手上正好有这个压缩包第一步不是解压直接训练而是先搞清楚标签长什么样数据是你另找的这套流程同样适用。2. 拆解warehouse数据集623张带标签图像到底意味着什么解压warehouse-skj9z.zip之后我一般先不看图而是先打开一个标签文件。YOLO系数据集最典型的结构就是images和labels两个目录每张jpg对应一个同名txt。这一步能看出很多问题类别有没有错位、坐标有没有越界、框是不是贴合目标。2.1 仓库安全场景的检测对象与标签体系仓库工人安全检测在工业项目里已经相当标准化。检测对象通常分三类人、防护装备、移动设备。以我见过的同类“掌舵安全”数据集来说最常见的是四个类别person、safety_helmet、safety_vest、forklift。有的项目还会把“未戴安全帽的人”单独拆成一类避免模型只认帽子不认人。命名看起来小事实际影响names数组的顺序后续训练、推理、可视化全跟它绑定。类别数量多寡和业务直接挂钩。如果你只检测“有没有人违规进入叉车作业区”一个person类就够了如果你要管“工人是否佩戴安全帽和反光背心”就得把防护装备拆细。仓库场景的难点在于遮挡和尺度变化工人可能站在货架后面只露半个身子远处的安全帽在640分辨率下只有十几个像素。标注框的质量在这时比数量更关键——框是否包住整个目标还是只框了一半会直接体现到map50上。拿到数据集后第一件事是写个脚本统计每个类别的框数量。别急着训练。类别分布不均会让模型偏向多数类后面调起来很费劲。统计完你才能判断623张图里每个类别大概有多少实例小目标占比多少需不需要针对性增强。2.2 YOLO标签格式解析txt、类别id和归一化坐标YOLO的标签是纯文本每行对应一个目标格式固定为五列class_id x_center y_center width height。class_id从0开始对应你names列表里的位置四个坐标全部归一化到0到1x_center和y_center是目标中心点相对图像宽高的比例width和height是目标框宽高相对图像宽高的比例。很多人在这里踩坑拿左上角坐标直接当成x_center训练出来的框全是偏的。如果你从coco预训练权重起步还要留意coco80这套类别索引怎么读。coco80里的类别列表第0类是person不是第1类。许多人在写names时习惯从1开始数结果类别错位训练时loss很低推理时标注全乱。读法很简单names数组下标就是类别id下标和类别一一对应别从1数。我一般会跑下面这个脚本检查标签的完整性和分布from pathlib import Path import numpy as np label_dir Path(labels) cls_count {} box_sizes [] for txt in label_dir.glob(*.txt): for line in txt.read_text().strip().splitlines(): parts line.split() if len(parts) ! 5: print(f格式异常: {txt.name} - {line}) continue cls int(parts[0]) x_center float(parts[1]) y_center float(parts[2]) w float(parts[3]) h float(parts[4]) cls_count[cls] cls_count.get(cls, 0) 1 box_sizes.append((w, h)) # 越界检查YOLO坐标应在(0,1]范围内 if not (0 x_center 1 and 0 y_center 1 and 0 w 1 and 0 h 1): print(f越界: {txt.name} - {line}) print(类别分布:, cls_count) box_sizes np.array(box_sizes) print(框宽高均值:, box_sizes.mean(axis0)) print(框宽高最大:, box_sizes.max(axis0))这个脚本会输出三个关键信息类别分布是否失衡、框尺寸均值提示目标大小、越界标签的文件名。越界标签是后续loss变成nan的头号原因必须提前清掉。框尺寸均值如果普遍小于0.05说明小目标居多训练时imgsz不能设太低。2.3 623张图够不够数据量、类别分布与增强补偿623张图像带标签在目标检测数据集里算小规模。够不够用取决于几个变量类别数、每个类别的实例数、场景覆盖度和部署环境的差异。仓库货架区、通道、装卸区看起来都是“仓库”但光照、角度、货架颜色完全不一样模型很容易过拟合到某一种背景。我对这个规模数据集的判断是能训练能出demo但直接上线风险偏高。要想达到能用的水平至少满足三个条件之一一是使用coco预训练权重做迁移学习而不是随机初始化二是做足数据增强让有限的图像模拟出更多光照和角度变化三是验证集尽量贴近真实部署场景指标才有参考价值。三者缺一个后面都会在夜班测试里翻车。迁移学习的必要性不用多说yolov8n.pt这种几十MB的权重文件已经学会了通用的边缘、纹理和物体概念。从它起步623张图能学到的是“仓库里的工人长什么样”而不是从零学“什么是边缘”。数据增强会在第4章展开这里先给一个判断表数据集规模场景单一程度建议做法预期效果623张场景单一高迁移学习基础增强可行过拟合风险中623张场景多样中迁移学习强增强有实用价值623张夜间/逆光占比低低必须补数据或重度增强谨慎上线验证集划分按8:2比较常见。如果每个类别实例数少于50建议把验证集比例降到10%把更多样本留给训练同时用k-fold交叉验证来评估。623张图的底线是宁可少训练一点也要保证验证集里有没见过的货架角度和人物姿态否则map50就是自欺欺人。3. 用YOLOv8训练自己的数据集从目录搭建到训练命令数据检查完下一步就是把数据集组织成ultralytics能直接读的结构。YOLOv8训练自己的数据集最关键的三个文件数据集目录、data.yaml、训练命令。很多人卡在目录结构上其实规则很简单images和labels平级train和val子目录严格对应。3.1 目录结构images与labels的摆放规则常见做法是这样一个树形结构warehouse-skj9z/ ├── images/ │ ├── train/ │ ├── val/ ├── labels/ │ ├── train/ │ ├── val/ └── data.yamlimages/train里有训练jpglabels/train里是相同文件名的txt。文件名必须一致否则ultralytics会报“No labels found”。如果压缩包里的原始结构是扁平的需要先按比例切分。下面这个脚本按8:2划分并且保证每张图和它的标签一起移动mkdir -p images/train images/val labels/train labels/valimport random from pathlib import Path import shutil random.seed(42) img_dir Path(images) label_dir Path(labels) val_ratio 0.2 imgs sorted(img_dir.glob(*.jpg)) sorted(img_dir.glob(*.png)) random.shuffle(imgs) val_count int(len(imgs) * val_ratio) for i, img in enumerate(imgs): sub val if i val_count else train label label_dir / (img.stem .txt) shutil.move(str(img), str(img_dir / sub / img.name)) if label.exists(): shutil.move(str(label), str(label_dir / sub / label.name))这个脚本先取20%作为验证集其余进训练集。seed固定为42保证每次切分结果一样方便复现。注意两点一是只移动存在的标签缺失标签的图直接删掉二是检查是否有jpg对应txt脚本里label存在才移动不存在的会被留在原目录训练时会报错。我习惯在切分后再跑一遍第2章的统计脚本确认train和val的类别分布大致接近避免某个类别全部落在验证集里。3.2 data.yaml与训练启动参数batch、imgsz、epochs怎么设data.yaml是训练入口路径和类别名必须和标签对得上path: /home/user/warehouse-skj9z train: images/train val: images/val names: 0: person 1: safety_helmet 2: safety_vest 3: forkliftpath可以写绝对路径也可以写数据集根目录相对路径。train和val写的是相对于path的子目录。names的顺序必须和标签里的class_id完全一致。如果第2章统计发现类别只有三四个names就写三四个别多写空类别。多写空类别会让模型的输出维度变多训练时效率变低。训练命令用ultralytics的标准入口yolo detect train \ modelyolov8n.pt \ datawarehouse-skj9z/data.yaml \ epochs100 \ imgsz640 \ batch16 \ patience15 \ device0参数含义model指定预训练权重yolov8n.pt是nano版数据集小就用它起步epochs设100配合patience15做早停连续15个epoch验证集不涨就停imgsz640是YOLO的默认输入尺寸batch16取决于显存RTX 3060这种12GB卡能跑8GB卡建议降到8。device0指定第一张GPU没有GPU就devicecpu但训练会慢很多。这里要单独说yolo损失函数因为训练日志里你会看到三组lossbox_loss、cls_loss和dfl_loss。box_loss管预测框和真实框的回归误差cls_loss管分类对不对dfl_loss是YOLOv8用来优化框边缘分布的一项。三者的加权和就是总loss。如果box_loss降不下去先怀疑标签框质量cls_loss震荡先怀疑类别不平衡dfl_loss异常往往是标签坐标越界。3.3 训练日志与验证loss曲线、map50和混淆矩阵训练结束后results.csv里每一行是一个epoch的指标我一般直接看加权总loss趋势以及val/box_loss有没有在patience之前停止下降。如果训练后map50在0.7以下先别急着调模型回到第2章检查标签。验证和推理各一条命令yolo detect val \ modelruns/detect/train/weights/best.pt \ datawarehouse-skj9z/data.yaml yolo detect predict \ modelruns/detect/train/weights/best.pt \ sourcetest_images/ \ conf0.25 \ saveTrueval命令会输出mAP50、mAP50-95、precision、recall同时生成混淆矩阵png。mAP50是IoU阈值0.5下的平均精度适合快速判断“框有没有蒙对”mAP50-95更严格反映框的贴合度。仓库安全检测场景mAP50达到0.85以上、mAP50-95达到0.6以上算基本可用。predict命令跑一遍真实截图看可视化结果往往比指标更直观——指标是黑匣子画出来的框才是你能跟业务方解释的东西。4. 仓库安全检测调优夜间逆光、遮挡和小目标的三个硬骨头623张图训练出来的基线模型往往在白天货架区表现不错一到夜间监控、逆光窗户、叉车遮挡就掉链子。这一章讲三个最常见的调优方向。4.1 数据增强参数mosaic、mixup与HSV扰动怎么配YOLOv8的数据增强在ultralytics里是默认开启的但默认参数针对coco这种大数据集仓库场景要自己压一遍。最关键的三个mosaic、mixup、hsv。mosaic把四张图拼成一张训练强迫模型学习不同背景下的目标mixup把两张图叠加适合数据量少时增加多样性hsv扰动模拟不同光照对夜间仓库尤其重要。命令行直接覆盖这些参数yolo detect train \ modelyolov8n.pt \ datawarehouse-skj9z/data.yaml \ epochs100 \ imgsz640 \ batch16 \ mosaic1.0 \ mixup0.2 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.5参数说明mosaic1.0表示每张训练图都参与mosaic拼接数据集小时建议保持1.0mixup0.2表示20%的概率做叠加hsv_h是色调扰动幅度0.015不算大hsv_s和hsv_v分别调饱和度和明度v0.5能让模型适应暗光。如果你发现夜间验证集recall偏低把hsv_v再往上提到0.6或0.7。注意mosaic在最后10个epoch会由ultralytics自动关闭保证模型看到真实完整的图像这是正常行为。数据增强不是越多越好。mixup开太高会让目标框重叠严重小目标更难看hsv扰动过大颜色失真反而把安全帽和反光背心的颜色语义带偏。我在小数据集上通常按mosaic1.0、mixup0.2起步过拟合明显再加而不是一开始就全拉满。4.2 imgsz与模型输入让模型看得清远处的小目标仓库监控里最远的摄像头可能覆盖整条货架通道工人和叉车在画面里占很小面积。安全帽这种目标在1080p原图里可能有几十像素缩到640后只剩十几个像素特征几乎消失。YOLOv8虽然是anchor-free设计但输入分辨率直接决定小目标能保留多少像素。把imgsz从640提到960是提升小目标recall最直接的手段yolo detect train \ modelyolov8n.pt \ datawarehouse-skj9z/data.yaml \ epochs100 \ imgsz960 \ batch8imgsz960时显存占用明显上涨batch要相应降下来12GB显卡跑nano版batch8比较稳。代价是训练变慢、推理变慢。如果线上机器只跑640那训练时也别用960否则部署时输入尺寸不一致精度会打折扣。另一种常见做法是保持640训练但用TTA测试时增强做验证评估不过TTA不适合实时推理只能用来评估上限。很多教程让你改anchor大小但YOLOv8已经让模型自己学习anchor的分布手动改容易帮倒忙。真正影响小目标的是imgsz、数据增强里的mosaic拼图方式和损失权重。如果你确实想调可以把小目标类别的box_loss权重稍微放大但这是最后手段优先把imgsz和训练数据搞定。4.3 模型选型n/s/m/l四档在仓库场景怎么挑YOLOv8的n/s/m/l四档差别在参数量和推理速度。仓库安全检测是典型的多路视频流场景通常同时看十几路摄像头模型体积直接决定单卡能带几路。四档特性对比如下模型参数量级640推理速度参考适用场景yolov8n约3M最快多路实时、边缘盒子yolov8s约11M快单路或多路均衡yolov8m约25M中等单路高清、精度优先yolov8l约43M慢离线分析、高精度需求我的选择习惯是先用nano跑通全流程验证数据没问题再换s做正式训练。nano训练快适合试错s在精度和速度之间最均衡623张图的数据量也喂得动s。m和l在这个数据规模下容易过拟合除非你打算做精细的离线分析否则不建议从m起步。如果训练资源有限还有个折中用yolov8m.pt的权重作为初始化但冻结前10层只训练后面的检测头。这样既能利用大模型的特征提取能力又不会因为数据少把底层搞崩。ultralytics的freeze参数就干这个事我一般在小数据集上freeze10配合yolov8m.pt使用。5. 训练仓库工人数据集的5个典型踩坑与排查记录这一章全是血泪经验。每条按现象、原因、解决三步写你可以直接对照排查。5.1 标签越界导致loss直接变成nan现象训练跑到第几个epochloss突然变成nantrain继续跑但val全是0输出框乱飞。原因标签文件里有坐标大于1或小于0的值或者width和height写成0。YOLO坐标必须归一化很多标注工具导出时加了偏移比如把x_center写成了以左上角为原点的像素值。解决训练前一定跑第2章的越界检查脚本把所有不在(0,1]范围的标签行打印出来。要么删掉这行要么用图像真实宽高重新归一化。我习惯把这条脚本加进训练流程的第一步任何新数据集都先过一遍。5.2 类别不平衡安全帽样本远多于反光背心现象val的混淆矩阵里safety_vest那一行recall很低precision却很高说明模型几乎不召回这个类别。原因数据集里安全帽出现频次可能是反光背心的好几倍模型把大多数参数都用来学多数类少数类被忽略。解决三个手段配合使用。一是在训练命令里给少数类加权ultralytics支持class weights参数二是对反光背心样本做复制增强把那几张图多复制几份放进训练集三是推理时对少数类用更低的conf阈值。注意改阈值要压验证集否则误报会增多。5.3 训练集和验证集图像泄漏指标虚高现象map50在验证集上0.95但部署到新摄像头视频上recall掉到0.5差距大得离谱。原因划分数据集时用了random.shuffle同一工人不同帧的图像被同时分进train和val。模型在训练时已经见过这个人的姿态和背景验证集测的是“背答案”。解决如果原始数据来自视频序列按视频片段或按人物身份划分而不是按单张随机分。脚本里可以把文件名前缀作为分组key保证同一个人的所有帧进同一侧。没有序列信息时至少检查验证集图像与训练集的相似度去掉过于接近的帧。5.4 空仓库背景误报成工人难负样本处理现象验证集map50不错但对着空货架通道的实时视频模型隔几秒就框出一个“人”置信度还有0.3到0.4。原因数据集中没有或者极少“空场景”负样本。模型没见过没有人的仓库就把货架阴影、叉车轮廓当成人。解决收集一批完全没有工人的仓库背景图单独放一个目录标签文件为空0字节txt。把这些负样本按一定比例混进训练集用mosaic让模型学会区分“人形阴影”和“真人”。空txt标签在YOLO里合法表示这张图没有目标训练时会作为负样本参与loss计算。5.5 导出TensorRT后精度下降现象pt模型在验证集上map50是0.85导出成engine后降到0.8看起来不多但特定类别比如远处安全帽直接漏检。原因导出时用了INT8量化或者onnx导出时opset版本和TensorRT不匹配某些层被降精度或替换实现。YOLOv8的DFL层在导出时经常出问题。解决先用FP16精度导出别一上来就INT8。FP16在T4上的精度损失很小速度也够快。如果FP16仍掉点检查onnx导出时opset是否在12以上以及有没有把dynamic batch打开。我一般先pt转onnx再用trtexec转engine每一步都保存一份中间文件方便对比是哪一步引入的差异。6. 部署到仓库监控的落地习惯TensorRT推理与路数估算6.1 pt转onnx转engine的两条命令训练完的best.pt要部署到仓库监控常见做法是转到TensorRT engine。两条命令搞定yolo export modelbest.pt formatonnx opset12 trtexec --onnxbest.onnx --saveEnginebest.engine --fp16先转onnx是为了排错如果onnx都导出失败问题大概率在模型结构或opset如果onnx能跑而engine精度差问题在TensorRT的优化策略。trtexec加上--fp16能显著提速T4这类卡对FP16支持很好。6.2 T4上1080p25帧率的路数估算方法大家常问T4上用TensorRT跑yolo 640分辨率检测能支持多少路1080p25我的估算方法从来不算峰值算力而是直接压测单路延迟。以yolov8sFP16T4为例单帧GPU推理时间大约在3到5毫秒加上预处理、后处理和视频解码单路完整pipeline约10到15毫秒。按25帧算单路要求40毫秒内处理一帧所以单卡理论能带3到4路留出20%余量后取2到3路更可靠。具体到你的项目不要拿别人的数字当结论。同一张卡、同一个模型分辨率、batch大小、后处理逻辑都会改变结果。我一般先单路跑十分钟看GPU util和延迟再逐步加路数直到GPU util超过90%且延迟还跟得上那个数就是实际承载上限。6.3 我的部署检查清单和一条血泪习惯部署前我习惯过一遍清单输入分辨率必须和训练时一致推理时conf和nms阈值和压测时一致单路延迟的P95维持在40ms以内空仓库背景连续跑一小时没有误报夜班录像抽两小时验证召回。最后一条血泪经验永远保留训练时的best.pt和data.yaml副本不要顺手删掉。模型上线后要补数据、要调阈值、要追溯某个框为什么漏检全都得回到训练环境里复现。我有一次为了省磁盘删了data.yaml三个月后要复训光重建类别映射就折腾了一晚上。数据、权重、配置这三样是这类项目的后悔药留着不占多少空间丢了就是黑匣子。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑