简介本资源为面向YOLO系列目标检测算法的工程机械数据集包含自卸卡车、挖掘机、轮式装载机三类目标适合从事施工场景识别、工地安全监控或车辆检测的开发者与研究者使用。压缩包共2000个文件以VOC格式的xml标注文件为主同时提供YOLO格式的txt标签两种标注分别存放于独立文件夹文件名末尾标注对应类别名称便于按类别检索与核对。资源已按训练与验证需求划分完毕并附带data.yaml配置文件可直接适配YOLOv5、YOLOv7、YOLOv8、YOLOv9、YOLOv10及YOLO11等主流版本省去格式转换与目录整理的重复工作。YOLO标签采用归一化中心点与宽高表示坐标范围0到1符合标准训练输入要求。压缩包整体约232MB内含2656张图像及对应标签目前已有82人学习下载适合快速搭建工程机械检测基线模型并开展迁移学习实验。1. 从一份 2656 张的挖掘机数据集说起YOLO 工程机械检测到底难在哪工地上同时出现挖掘机、自卸卡车、轮式装载机这三种设备外形差异大、作业姿态多变但真正做过工程机械检测的人都知道难的不是把它们分开而是让模型在尘土、逆光、遮挡和远距离小目标下依然稳定。这份 2656 张图像带标签的挖掘机数据集覆盖了挖掘机、自卸卡车、轮式装载机三类目标正好是一个典型的「少类别、强场景、高姿态变化」检测任务。它适合谁适合想入门 YOLO 目标检测但不想从 COCO 那种通用数据集起步的工程师也适合做智慧工地、土方量统计、设备调度、安全监控的从业者。你拿到的不是一份玩具数据而是一个能直接跑通训练、验证、推理全流程的真实场景数据集。接下来的内容我会按「数据怎么查、标签怎么转、YOLO 怎么训、参数怎么调、坑在哪」这条线把整个落地路径拆开讲清楚。2. 拿到数据集先别急着训2656 张图像的标签体检与格式转换2.1 先搞清楚标签格式YOLO txt、VOC xml 还是 COCO json工程机械数据集最常见的标签格式有三种YOLO 的归一化 txt、Pascal VOC 的 xml、COCO 的 json。你拿到的这份数据集从命名习惯看大概率是 YOLO txt 或 VOC xml。别急着写训练脚本先花十分钟做一次标签体检否则后面训练 loss 不降、mAP 为 0 的时候你会怀疑人生。先看目录结构。常见做法是 images 和 labels 两个文件夹并列labels 里每个 txt 对应一张图每行是class_id x_center y_center width height全部归一化到 0~1。如果是 VOC则是 Annotations 里一堆 xmlJPEGImages 里一堆 jpg。用下面这段脚本快速统计类别分布和标签完整性import os from collections import Counter from pathlib import Path # 改成你的实际路径 label_dir Path(labels) img_dir Path(images) class_counter Counter() missing_label [] empty_label [] bad_line [] for img_path in img_dir.glob(*.jpg): label_path label_dir / (img_path.stem .txt) if not label_path.exists(): missing_label.append(img_path.name) continue lines label_path.read_text().strip().splitlines() if len(lines) 0: empty_label.append(img_path.name) continue for line in lines: parts line.split() if len(parts) ! 5: bad_line.append((label_path.name, line)) continue cls_id int(parts[0]) class_counter[cls_id] 1 # 检查归一化坐标是否越界 coords list(map(float, parts[1:])) if any(c 0 or c 1 for c in coords): bad_line.append((label_path.name, line)) print(类别分布:, class_counter) print(缺标签图片数:, len(missing_label)) print(空标签图片数:, len(empty_label)) print(异常行数:, len(bad_line))这段脚本做了四件事统计每个类别的框数量、找出没有对应标签的图片、找出空标签文件、检查坐标是否越界。类别分布直接决定你后面要不要用加权采样或 focal loss缺标签和空标签图片如果太多要么补标要么剔除坐标越界说明标注工具导出时出了问题必须修。参数说明label_dir和img_dir按你的实际目录改如果你的图片是 png 或 jpeg把 glob 的后缀换掉。跑完如果发现某一类只有几十个框那这个类基本训不出来需要考虑合并类别或补充数据。2.2 把 VOC 转成 YOLO 格式转换脚本与四个边界坑如果体检发现是 VOC xml就得转成 YOLO txt。转换逻辑不复杂但边界坑很多。下面这个脚本我用了很多次直接抄import xml.etree.ElementTree as ET from pathlib import Path from PIL import Image voc_dir Path(Annotations) img_dir Path(JPEGImages) out_dir Path(labels_yolo) out_dir.mkdir(exist_okTrue) # 类别名到 id 的映射按你的数据集改 classes [excavator, dump_truck, wheel_loader] class_to_id {name: i for i, name in enumerate(classes)} for xml_path in voc_dir.glob(*.xml): tree ET.parse(xml_path) root tree.getroot() img_name root.find(filename).text img_path img_dir / img_name if not img_path.exists(): print(图片缺失:, img_name) continue w, h Image.open(img_path).size lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in class_to_id: continue bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 边界裁剪防止越界 xmin max(0, min(xmin, w - 1)) ymin max(0, min(ymin, h - 1)) xmax max(0, min(xmax, w - 1)) ymax max(0, min(ymax, h - 1)) if xmax xmin or ymax ymin: continue x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{class_to_id[cls_name]} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) if lines: (out_dir / (xml_path.stem .txt)).write_text(\n.join(lines))四个边界坑第一xmin/xmax 可能超出图片尺寸必须裁剪第二有些标注框宽高为 0 或负数直接跳过第三类别名大小写和空格不一致比如 Excavator 和 excavator 要先 strip 再统一映射第四图片文件名和 xml 里的 filename 不一致要以实际图片为准。转换完再跑一遍 2.1 的体检脚本确认类别分布和坐标都正常。2.3 划分训练集、验证集、测试集别让同一场景的图同时出现在两边2656 张图不算多划分比例常见是 7:2:1 或 8:1:1。但工程机械数据有个特点同一段视频抽帧出来的图片高度相似。如果你随机划分训练集和验证集里会出现几乎一样的图验证 mAP 虚高上线就翻车。正确做法是按场景或按视频源划分同一场景的图只进一个集合。import random from pathlib import Path import shutil random.seed(42) img_dir Path(images) label_dir Path(labels) out_root Path(dataset) for split in [train, val, test]: (out_root / images / split).mkdir(parentsTrue, exist_okTrue) (out_root / labels / split).mkdir(parentsTrue, exist_okTrue) all_imgs sorted(img_dir.glob(*.jpg)) random.shuffle(all_imgs) n len(all_imgs) n_train int(n * 0.8) n_val int(n * 0.1) splits { train: all_imgs[:n_train], val: all_imgs[n_train:n_train n_val], test: all_imgs[n_train n_val:] } for split, imgs in splits.items(): for img_path in imgs: shutil.copy(img_path, out_root / images / split / img_path.name) label_path label_dir / (img_path.stem .txt) if label_path.exists(): shutil.copy(label_path, out_root / labels / split / label_path.name)如果你的图片文件名里带了场景编号或日期按编号分组再划分比纯随机靠谱得多。跑完检查三个集合的类别分布是否接近如果某一类只在训练集出现验证集就测不出这个类。3. YOLO 训练挖掘机检测模型从 data.yaml 到第一个 baseline3.1 写对 data.yaml三个类别名和路径的常见错误YOLO 系列训练都靠一个 yaml 文件描述数据路径和类别。以 YOLOv8 为例结构如下path: /home/user/dataset train: images/train val: images/val test: images/test names: 0: excavator 1: dump_truck 2: wheel_loader三个常见错误第一path用了相对路径训练时工作目录一变就找不到第二train和val写成了绝对路径但path又拼了一次导致路径重复第三names的 id 和标签里的 class_id 对不上比如标签里 0 是挖掘机names 里 0 写成了卡车训练 loss 正常但预测全错。写完 yaml 后用一行命令验证路径python -c from ultralytics import YOLO; modelYOLO(yolov8n.pt); model.train(datadata.yaml, epochs1, imgsz640, batch4)先跑 1 个 epoch看能不能正常读图、正常反传。如果报 No labels found八成是路径或文件名对不上。3.2 从 yolov8n 开始第一个 baseline 的训练命令与参数含义别一上来就上大模型。2656 张图yolov8n 或 yolov8s 足够跑出可用的 baseline。命令如下yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience20 \ device0 \ projectruns/excavator \ namebaseline参数逐个说imgsz640是输入分辨率工程机械目标通常较大640 够用如果小目标多可以上 1280但显存翻倍。batch16看显存调8G 显存跑 640 大概能到 16。lr00.01是初始学习率YOLOv8 默认 0.01数据量小可以降到 0.005。lrf0.01是最终学习率系数控制余弦退火终点。patience20是早停耐心值20 个 epoch 没提升就停。device0指定第一块 GPU。训练过程中重点看三个指标box_loss是否稳定下降、mAP50是否上升、cls_loss是否震荡。如果 box_loss 不降先检查标签格式如果 mAP50 卡在很低的值检查类别映射和验证集划分。3.3 数据增强怎么开Mosaic、MixUp 和 HSV 在工程机械场景的取舍YOLO 默认开 Mosaic 和 HSV 增强。Mosaic 把四张图拼成一张对小数据集很有效能提升 batch 内的多样性。但工程机械场景有个问题Mosaic 拼出来的图里挖掘机可能被截断成半截模型学到不完整的目标特征。我的经验是前 80 个 epoch 开 Mosaic最后 20 个 epoch 关掉让模型在完整图上收敛。HSV 增强调饱和度、明度、色调对尘土和逆光场景有帮助。但如果你的数据本身色调单一HSV 幅度别开太大否则模型把颜色当噪声。MixUp 在工程机械上要慎用两张图叠加后目标边界模糊小目标容易消失。常见做法是 Mosaic1.0、MixUp0.0、HSV 默认先跑一版看效果再针对性调。yolo detect train \ datadata.yaml \ modelyolov8s.pt \ epochs120 \ imgsz640 \ batch12 \ mosaic1.0 \ mixup0.0 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ close_mosaic20 \ device0close_mosaic20表示最后 20 个 epoch 关闭 Mosaic这是 YOLOv8 的一个实用参数很多人不知道。跑完对比 baseline看 mAP50 和 mAP50-95 的变化如果 mAP50 涨了但 mAP50-95 没动说明框的位置还不够准可以调框回归的 loss 权重。4. 训练完别只看 mAP挖掘机检测的排查与避坑清单4.1 现象mAP50 很高但实际推理漏检严重原因验证集和训练集场景太像模型过拟合到特定背景。或者验证集里目标尺寸分布和实际部署场景不一致。解决按场景重新划分验证集加入不同光照、不同距离的图推理时降低置信度阈值到 0.25 试试看漏检是否减少如果降低阈值后误检暴增说明模型区分能力不够需要补难例。4.2 现象自卸卡车和轮式装载机互相误检原因这两类设备在远距离或部分遮挡时外形相似尤其是车斗和铲斗的轮廓。解决检查标签里这两类的框是否有标错在 data.yaml 里确认类别 id 没串训练时对这两类加更高的分类 loss 权重或者用更大的模型yolov8m提升特征区分度。如果数据里轮式装载机样本太少考虑合并成「工程车辆」一类先跑通再细分。4.3 现象训练 loss 正常但推理时框全偏了原因标签坐标归一化时用了错误的宽高比如把 xml 里的宽高当成了 xmax/ymax。或者图片在训练时被 resize 但标签没同步。解决用 2.1 的体检脚本检查坐标是否在 0~1 之间随机抽几张图用脚本把标签框画到图上肉眼确认框的位置对不对。import cv2 from pathlib import Path img_path Path(images/train/001.jpg) label_path Path(labels/train/001.txt) img cv2.imread(str(img_path)) h, w img.shape[:2] for line in label_path.read_text().strip().splitlines(): cls, xc, yc, bw, bh map(float, line.split()) x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(check.jpg, img)跑完打开 check.jpg框如果偏了就是标签问题不是模型问题。4.4 现象显存溢出batch 降到 4 还是炸原因imgsz 设太大或者模型选太大或者 dataloader 的 workers 太多导致内存泄漏。解决先把 imgsz 降到 640模型换 yolov8nworkers 设 4如果还炸用batch2加梯度累积模拟大 batch检查是否有图片尺寸异常大比如 4000x3000 的图先统一 resize 到长边 1280 再训。4.5 现象训练到一半 mAP 突然掉下去原因学习率太大导致震荡或者数据里有脏标签在某个 epoch 被采样到。解决看 loss 曲线如果 cls_loss 突然飙升大概率是脏标签用 2.1 的脚本再扫一遍标签重点看坐标越界和类别 id 异常的把 lr0 降到 0.005加 warmup epochs。5. 把 2656 张用到极致小数据集的进阶技巧与验证习惯2656 张图在目标检测里属于小数据集想榨出更高精度有几个技巧我反复用过。第一用预训练权重做迁移学习yolov8n.pt 或 yolov8s.pt 都是在 COCO 上训过的直接拿来微调比从头训快得多mAP 也高。第二用 K-fold 交叉验证代替单次划分把 2656 张分成 5 折每折都做一次验证取平均 mAP这样对模型真实能力的估计更稳。第三对难例做针对性增强比如把漏检的图挑出来单独复制几份加不同增强再训一轮。验证习惯上我一般会做两件事一是用测试集跑一次yolo detect val看混淆矩阵确认没有类别系统性混淆二是用yolo detect predict跑一批实际场景图肉眼数漏检和误检。混淆矩阵里如果挖掘机和背景的混淆很高说明背景太杂需要加负样本。下面这个命令导出混淆矩阵和 PR 曲线yolo detect val \ modelruns/excavator/baseline/weights/best.pt \ datadata.yaml \ splittest \ plotsTrue \ save_jsonTrueplotsTrue会在 runs 目录下生成混淆矩阵、PR 曲线、F1 曲线。重点看混淆矩阵的对角线如果某一类召回明显低回去补这类样本。save_jsonTrue导出 COCO 格式的预测结果方便和其他模型对比。最后一个习惯每次改参数或改数据只改一个变量记录 mAP50 和 mAP50-95。我见过太多人一次改五个参数结果涨了不知道哪个起作用跌了不知道哪个背锅。小数据集训练玄学多但可控的实验记录能让你少走很多弯路。希望帮到你。本文还有配套的精品资源点击获取