简介本资源为面向YOLO系列目标检测算法的工程机械数据集包含自卸卡车、挖掘机、轮式装载机三类目标适合从事施工场景识别、工地安全监控及自动驾驶研究的开发者与算法学习者使用。压缩包共2000个文件以xml标注文件为主同时提供YOLO格式txt与VOC格式xml两套标签分别存放于独立文件夹文件名末尾标注对应类别名称并附带data.yaml配置文件可直接用于yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等模型的训练与验证测试。数据集已按训练验证需求划分完毕图像总量2656张整体约232.47MBYOLO标签采用归一化中心点与宽高比例便于直接读取。目前已有80人学习下载读者可快速获得一套开箱即用的工程机械检测数据省去标注与格式转换环节将精力集中于模型选型、训练调参与效果对比适合作为课程设计、毕业项目或算法验证的实用素材。1. 挖掘机数据集与 YOLO 训练从 2656 张带标签图像到能跑的检测器手头拿到一个 2656 张图像带标签的工程机械数据集类别是自卸卡车、挖掘机、轮式装载机想用 YOLO 训一个能落地的检测器——这件事听起来简单真正动手的人多半会在第一轮就卡住标签格式对不上、类别名带空格、小目标全挤在画面角落、训练到一半 BN 崩溃。这个数据集的价值不在图像数量而在于它把工地场景里最容易混淆的三类重型机械单独拆了出来自卸卡车和轮式装载机在远景下轮廓高度相似挖掘机的机械臂姿态又千变万化正好是检验 YOLO 数据管线和增强策略的试金石。下面按我实际跑这类数据集的顺序从数据体检、格式转换、训练配置到排错把每一步的参数和坑讲清楚新手能照着复现熟手能直接对参数边界。2. 拿到 2656 张带标签图像先做什么数据体检与类别分布2.1 用脚本统计类别数、框数和图像尺寸不要急着写 data.yaml 就开始训练。先花十分钟做数据体检后面能省几小时排错。把解压后的目录结构看清楚常见的是 images/ 和 labels/ 平行存放也可能所有文件混在一起。下面这个脚本统计每类框数、每张图的目标数分布和图像尺寸范围。import os import glob from collections import Counter from PIL import Image img_dir dataset/images lbl_dir dataset/labels class_names [dump_truck, excavator, wheel_loader] class_counter Counter() per_image_counts [] sizes [] for img_path in glob.glob(os.path.join(img_dir, *.jpg)): stem os.path.splitext(os.path.basename(img_path))[0] lbl_path os.path.join(lbl_dir, stem .txt) if not os.path.exists(lbl_path): print(f缺失标签: {stem}) continue with Image.open(img_path) as im: sizes.append(im.size) with open(lbl_path) as f: lines [l.strip() for l in f if l.strip()] per_image_counts.append(len(lines)) for line in lines: cls_id int(line.split()[0]) class_counter[cls_id] 1 print(类别框数:, {class_names[k]: v for k, v in class_counter.items()}) print(每图目标数 min/mean/max:, min(per_image_counts), sum(per_image_counts) / len(per_image_counts), max(per_image_counts)) print(图像尺寸集合:, set(sizes))逻辑说明脚本按图像文件名去找同名 .txt 标签统计每个类别的框数量、每张图的目标数以及图像分辨率。参数上class_names 的顺序必须和标签里的类别 id 严格对应如果数据集用的是 0/1/2 但你不确定哪个 id 对应哪类先看标签文件里 id 的分布再对照图像确认。体检结果重点关注三件事类别是否严重不均衡比如挖掘机 3000 框、轮式装载机只有 400 框、每张图目标数是否过少平均低于 2 说明大量空背景图、图像尺寸是否统一。这三项直接决定后面增强策略和 anchor 设置。2.2 判断标签格式并处理类别名映射YOLO 用的是归一化中心点格式class_id cx cy w h全部是 0 到 1 之间的小数。如果你拿到的是 VOC 的 XML 或 COCO 的 JSON需要先转换。判断方法很简单打开一个 .txt 看第一列是不是整数、后四列是不是小数。# 检查标签格式是否规范 def check_label_format(lbl_path): with open(lbl_path) as f: for i, line in enumerate(f): parts line.strip().split() if len(parts) ! 5: return f第{i}行字段数{len(parts)}应为5 cls_id int(parts[0]) coords [float(x) for x in parts[1:]] if any(c 0 or c 1 for c in coords): return f第{i}行坐标越界: {coords} return 格式正常如果坐标出现大于 1 的值说明标签是绝对像素坐标需要除以图像宽高做归一化。这一步翻车的代价很大YOLO 不会报错只会把框画到画面外训练 loss 居高不下但你看不出来。类别名映射是另一个隐蔽坑。数据集里可能写的是中文「自卸卡车」或者带空格的「dump truck」而 YOLO 的 data.yaml 里 names 列表是按索引对应的名字本身不参与计算但如果你用中文名且编码不是 UTF-8读 yaml 时会直接抛异常。我一般统一改成英文下划线命名和 class_names 列表保持一致。提示体检阶段就把类别 id 到名称的映射写死在一个 json 里训练、推理、可视化三个环节共用避免中途对不上。3. 把数据集接进 YOLOv8 训练目录结构、data.yaml 与增强参数3.1 目录结构与 data.yaml 的正确写法YOLOv8 对目录结构有约定最省事的做法是 train/val 各自带 images 和 labels 子目录。2656 张图按 8:2 划分验证集留 500 张左右足够反映真实分布。划分时注意同一段视频抽帧的图不能跨 train/val否则验证指标虚高。dataset/ ├── train/ │ ├── images/ # 约 2125 张 │ └── labels/ ├── val/ │ ├── images/ # 约 531 张 │ └── labels/ └── data.yamldata.yaml 的写法path: /abs/path/to/dataset train: train/images val: val/images nc: 3 names: 0: dump_truck 1: excavator 2: wheel_loaderpath 用绝对路径相对路径在不同工作目录下启动训练时经常找不到文件。nc 必须等于 names 的长度多一个少一个都会在加载时崩。names 的索引顺序必须和标签里的 class_id 完全一致这是最容易出错的地方——如果标签里 0 是挖掘机而你写成 dump_truck模型学出来的类别全是错的但 loss 曲线看起来很正常。3.2 针对工程机械场景的增强参数怎么调默认增强对工地场景不够用。自卸卡车和轮式装载机在远景下都是「方块加轮子」需要靠颜色和纹理区分所以 HSV 增强要开挖掘机机械臂姿态多需要较大的旋转和缩放范围工地图像常有逆光和阴影亮度对比度扰动要保留。from ultralytics import YOLO model YOLO(yolov8s.pt) model.train( datadataset/data.yaml, epochs150, imgsz640, batch16, workers4, device0, hsv_h0.015, # 色调扰动区分涂装颜色 hsv_s0.7, # 饱和度扰动应对逆光 hsv_v0.4, # 亮度扰动应对阴影 degrees15.0, # 旋转角度覆盖机械臂姿态 translate0.1, scale0.5, # 缩放范围覆盖远近景 fliplr0.5, mosaic1.0, # 四图拼接提升小目标 mixup0.1, patience30, # 30轮无提升则早停 cacheTrue # 图像缓存到内存加速训练 )参数说明imgsz640 是速度和精度的平衡点如果小目标多可以提到 960但显存占用翻倍。batch16 在 8G 显存下跑 yolov8s 比较稳爆显存就降到 8。mosaic1.0 对小目标提升明显但最后 10 轮建议关掉让模型在真实分布上收敛。patience30 配合 150 epochs实际往往在 100 轮左右就早停了。注意cacheTrue 会把所有图像解码后存内存2656 张 640 尺寸大约占 3-4G 内存内存不够就设 cacheFalse 或 cachedisk。3.3 训练启动与关键日志怎么看启动训练后重点盯三个指标box_loss、cls_loss 和 mAP50。box_loss 在前 10 轮快速下降是正常的如果 20 轮后还在 0.5 以上多半是标签格式有问题。cls_loss 如果一直不降检查类别 id 映射。mAP50 在 50 轮后应该能看到明显爬升。yolo detect train datadataset/data.yaml modelyolov8s.pt epochs150 imgsz640 batch16命令行和 Python 脚本等价命令行适合快速试跑脚本适合固化参数。训练产物在 runs/detect/train/ 下weights/best.pt 是验证集上最好的权重last.pt 是最后一轮。别直接用 last.pt 做推理除非你确认没有过拟合。4. 训练过程避坑从 BN 崩溃到类别混淆的排查记录4.1 BN 崩溃loss 突然变 nan现象训练到三四十轮loss 突然变成 nan之后所有轮次都是 nan。原因batch 太小导致 BatchNorm 统计量不稳定或者学习率过高让梯度爆炸。解决把 batch 从 8 提到 16或者改用 yolov8s 以上的模型参数量大一些 BN 更稳同时把初始学习率从 0.01 降到 0.005。如果显存实在不够用model.train(..., ampFalse)关掉混合精度能缓解但不根治。4.2 自卸卡车和轮式装载机互相误检现象验证集上这两类的混淆矩阵交叉很高mAP 卡在 0.6 上不去。原因远景下两类车轮廓相似且数据集中可能存在标注不一致——同一辆车在不同图里被标成不同类。解决先抽样 50 张验证集误检图人工核对标注确认不是标注问题后在增强里加大 scale 和 degrees让模型学到更多视角差异同时把这两类的样本按 1:1 重采样避免某一类主导。4.3 小目标挖掘机漏检严重现象画面远处的挖掘机几乎全漏mAP 只有 0.3。原因640 输入下远处挖掘机可能只有 20x20 像素特征图上下采样后信息丢失。解决把 imgsz 提到 960或者用 yolov8m/l 这类更大模型增强上把 mosaic 保持 1.0并加 copy_paste0.3 把小目标复制粘贴到其他图上增加出现频率。4.4 验证集指标虚高但实际推理效果差现象mAP50 到 0.85但拿工地实拍视频跑漏检和误检都很多。原因train/val 划分时同一段视频的帧被分到了两边验证集和训练集高度相似。解决按视频源或时间段划分确保验证集的场景和训练集不重叠。这个坑最隐蔽指标好看但模型没泛化能力。4.5 标签文件里有空行或多余空格现象训练启动时报IndexError: list index out of range或者某些图的目标数统计为 0 但明明有框。原因标签文件里有空行、行尾有空格、或者用逗号分隔。解决训练前跑一遍清洗脚本去掉空行、统一用空格分隔、确保每行 5 个字段。import glob, os for lbl in glob.glob(dataset/**/labels/*.txt, recursiveTrue): with open(lbl) as f: lines [l.strip() for l in f if l.strip()] cleaned [] for line in lines: parts line.replace(,, ).split() if len(parts) 5: cleaned.append( .join(parts)) with open(lbl, w) as f: f.write(\n.join(cleaned))5. 用验证集反查标注质量与推理部署的一个实用技巧训练完拿到 best.pt 只是开始真正决定落地效果的是标注质量。我习惯用模型在验证集上的预测结果反查标注把预测框和真实框画在同一张图上差异大的图单独拎出来人工复核。这一步能揪出标注漏标、框不准、类别标错三类问题比单纯看 mAP 有用得多。from ultralytics import YOLO import cv2 model YOLO(runs/detect/train/weights/best.pt) results model.predict(dataset/val/images, conf0.25, iou0.5, saveTrue) # 对每张图把预测框和 GT 框叠加对比 for r in results: img cv2.imread(r.path) # 画预测框红色 for box in r.boxes: x1, y1, x2, y2 map(int, box.xyxy[0]) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) # 画 GT 框绿色从同名 label 文件读 stem os.path.splitext(os.path.basename(r.path))[0] lbl fdataset/val/labels/{stem}.txt h, w img.shape[:2] if os.path.exists(lbl): with open(lbl) as f: for line in f: c, cx, cy, bw, bh map(float, line.split()) x1 int((cx - bw/2) * w); y1 int((cy - bh/2) * h) x2 int((cx bw/2) * w); y2 int((cy bh/2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(fcompare/{stem}.jpg, img)参数说明conf0.25 是推理置信度阈值反查标注时可以调低到 0.1 让更多预测出来方便发现漏标。iou0.5 是 NMS 阈值密集场景可以提到 0.6 减少误抑制。对比图里红框是预测、绿框是标注红绿重合说明标注准只有绿框说明漏检可能是标注了但模型没学到只有红框说明误检或漏标。这个技巧的另一个用途是确定部署时的置信度阈值。把验证集按 conf 从 0.1 到 0.5 扫一遍画 precision-recall 曲线选 F1 最高的点作为部署阈值。工地场景通常宁可误检不可漏检阈值可以比 F1 最优点再低 0.05。我自己的习惯是每次训完新模型先跑这个对比脚本看 20 张比看任何指标都直观。标注质量差的数据集再好的模型也救不回来而反查是发现标注问题最快的方式。希望帮到你。本文还有配套的精品资源点击获取