ARTICLE DETAIL

资讯详情

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

YOLO火车轨道手推车数据集:双格式标签与训练避坑指南

YOLO火车轨道手推车数据集:双格式标签与训练避坑指南 简介面向YOLO系列目标检测任务的火车、轨道与手推车识别数据集适合算法学习者、模型训练者以及工业视觉场景开发者直接使用。压缩包约236MB共2000个文件提供VOC格式xml与YOLO格式txt两套标签标签按类别单独组织便于切换训练框架。数据集已完成训练集、验证集与测试集划分并附带data.yaml配置可无缝接入yolov5、v7、v8、v9、v10、yolo11等主流算法省去数据准备与格式转换时间。YOLO格式标签中每行包含目标类别索引、归一化的中心点坐标及宽高比例信息完整可直接用于模型训练、验证测试和迁移学习。结合火车、轨道、手推车三类目标的标注适合轨道运输与施工现场相关检测研究。目前已有100人学习适合需要快速获取带标注数据来调试模型或验证算法效果的开发者。1. YOLO 火车轨道手推车数据集3793 张带标签图像从解压到训练先看清三件事提到 YOLO最烦的从来不是网络结构而是数据集的可用性。这套火车、轨道、手推车数据集讲究在“直接用”3793 张图像两部分标签都齐——YOLO 格式的 txt 和 VOC 格式的 xml 分文件夹存着训练集、验证集已经拆好还放了份 data.yaml 配置YOLOv5/v7/v8/v9/v10/yolo11 都能吃下。对上要快速验证检测管线、对下要做轨道交通货运场景预研的人来说它最大的价值是同时省掉标图、转格式两道最磨人的工序。但“带标签”不等于开箱就能练出好模型。标签文件里坐标参照系、类别索引、图片尺寸三者一旦对不上训练时会换成另一种方式冒出来loss 不降、mAP 个位数、验证集看着挺好现场却漏检。下面我就把这套资源从目录结构、双标签格式、训练命令到常见报错完整拆一遍新手照步骤能跑通熟手也能直接拿去当检查清单用。2. 数据集结构与双标注格式txt 和 xml 两种标签怎么对应到同一张图2.1 解压后目录应该长什么样数据集解压后核心文件按功能分成了四块图像文件、YOLO 格式标签文件夹、VOC 格式标签文件夹和一份 data.yaml。常见目录结构如下如果压缩包内结构略有出入按文件后缀来找就不会认错dataset/ ├── images/ # 训练与验证图像通常按 train/val 子目录分好 │ ├── train/ │ └── val/ ├── labels/ # YOLO 格式 txt 标签每个 txt 与图像同名 │ ├── train/ │ └── val/ ├── voc_labels/ # VOC 格式 xml 标签文件名与图像同名 │ ├── train/ │ └── val/ └── data.yaml # 训练时的数据集配置入口我一般拿到压缩包先看 data.yaml它描述的路径、类别数、类名比任何说明文件都贴近训练逻辑。压缩包里的图像文件名类似img_0866_807.jpg对应标签就是img_0866_807.txt和img_0866_807.xml靠同名关系绑定。文件名末尾的数字后缀有的来自原始抓帧序号有的可能是类别编号不建议靠文件名推测标注内容一切以标签里的实际数值为准。2.2 YOLO txt 标注的五个字段中心点、宽高与归一化坐标YOLO 格式每个 txt 文件里一行一个目标五个数值依次是class x_center y_center width height第三个数开始容易看走眼x_center和y_center是归一化后的目标框中心点坐标width和height是归一化后的框宽高归一化的基准是图像本身的宽和高。一张 640×480 的图框左上角像素坐标为 (160,120)右下角为 (320,240)对应 txt 里的这一行就是0 0.375 0.375 0.25 0.25换算过程为x_center (160320)/2/640 0.375y_center (120240)/2/480 0.375width (320-160)/640 0.25height (240-120)/480 0.25。这套换算关系后面检查脚本天天要用只记格式不记参照系的话转出来的框位置一定是飘的。YOLO 为什么坚持归一化而不是直接存像素坐标因为训练时图像会被 Resize 到固定尺寸还伴随 Mosaic 等数据增强图像实际尺寸随时在变。用归一化坐标增强模块只需要按比例线性映射不需要为每种增强重算坐标基准。反过来也提醒一点如果你打算把 VOC 转成 YOLO千万别先把图像缩放一遍再读 xml 尺寸那样会把两个基准全部弄乱。2.3 VOC xml 标注像素坐标系、类别名与它的“后悔药”价值VOC 格式的 xml 保存的是像素坐标和类别名称一个目标一个object节点annotation size width640/width height480/height depth3/depth /size object namehand_truck/name bndbox xmin160/xmin ymin120/ymin xmax320/xmax ymax240/ymax /bndbox /object /annotationxml 里类别是字符串txt 里是索引因此从 xml 生成 yolo 标签时必须先建立「类别名 → 索引」的映射表。索引顺序没有全局统一标准完全取决于 data.yaml 里names列表的排列。如果压缩包内没有附带类别文件最稳的做法是扫描全部 xml提取出现过的name去重后按序编号再确认与 data.yaml 的names顺序严格一致。同时保留 xml 格式的价值不只是兼容旧 pipelinetxt 一旦被误改、误删或者编码损坏xml 是完整的原始标注证据可以用脚本重新生成 txt相当于给标注上了层后悔药。做多人协作标注的项目我通常会把 VOC 版本作为唯一事实源txt 只当作训练时的派生产物。2.4 data.yaml 是入口类别数才是标签检核的基准data.yaml 的内容通常长这样具体类名与顺序以压缩包内实际文件为准不要不核对就照抄train: ./images/train val: ./images/val nc: 3 names: [train, rail, hand_truck]第一次训练前要检查两点。第一train/val路径在你的机器上能否正确解析相对路径会在命令行工作目录变化时失效第二nc必须和names长度一致同时必须大于所有标签文件里出现过的最大类别索引。因为数据集已经划分好划分比例不用你操心真正要动手的是在打开训练命令之前把标签的合法性检查一遍。提示修改 data.yaml 前先备份一份原文件后面排查路径问题时可以快速对照是数据集本身的问题还是你改配置改出来的问题。类别名对应错位的后果往往滞后训练过程不报错loss 也下降但预测时索引 0 实际指向的是names里的第一个名字如果 txt 里索引 0 的语义在 xml 里根本不是这个类模型学到的就是错位语义。这也是双格式数据集的一个隐藏优势——用 xml 去反查 txt 的类别语义可以快速验证映射表有没有建对。3. 训练前先做一次标注体检坐标越界、类别超范围与可视化抽查3.1 为什么要先检查而不是直接训练边界框坐标越界、类别索引超出nc、宽高为 0 这些错误通常不会阻止训练启动而是转化成损失曲线不收敛、mAP 稳定在零点几这类难定位的玄学问题。我处理新数据集的习惯是先扫描一遍全部 txt 字段而不是急着敲训练命令。检查点主要落在五个方面每行字段数量是否为 5、类别索引是否落在 [0, nc-1]、中心点坐标是否在 [0,1] 区间、宽高是否为正、中心点加减半宽高之后是否仍在图像范围内。另一个常被忽略的点是空标签文件。YOLO 允许一张图没有标注但一张空标签意味着该样本没有任何监督信息如果空文件占比过高训练时这部分图像只会贡献背景误差。扫描脚本里顺手统计空文件数量低于 1% 基本不用管高到 5% 以上就要回到原始 xml 确认是不是漏转了文件。3.2 批量检查 YOLO txt 标注的 Python 脚本import os from collections import Counter labels_dir labels/train # 改成实际标签目录 nc 3 # 与 data.yaml 的 nc 保持一致 err_count 0 empty_count 0 class_counter Counter() with open(issue_report.txt, w, encodingutf-8) as out: for root, _, files in os.walk(labels_dir): for name in files: if not name.endswith(.txt): continue path os.path.join(root, name) with open(path, encodingutf-8) as f: lines f.readlines() if len(lines) 0: empty_count 1 out.write(f{path} 空标签\n) for ln, line in enumerate(lines, 1): parts line.strip().split() # 每个目标必须正好 5 个字段 if len(parts) ! 5: out.write(f{path}:{ln} 字段数{len(parts)}\n) err_count 1 continue cls, xc, yc, w, h parts cls, xc, yc, w, h int(cls), float(xc), float(yc), float(w), float(h) # 类别索引必须小于 nc同时不能是负数 if cls 0 or cls nc: out.write(f{path}:{ln} 类别越界 {cls}\n) err_count 1 # 归一化坐标必须落在 [0,1] if not (0 xc 1 and 0 yc 1): out.write(f{path}:{ln} 中心点越界 xc{xc} yc{yc}\n) err_count 1 if not (0 w 1 and 0 h 1): out.write(f{path}:{ln} 宽高非法 w{w} h{h}\n) err_count 1 # 中心点加减半宽高不能超出图像范围 if xc - w / 2 0 or xc w / 2 1 or yc - h / 2 0 or yc h / 2 1: out.write(f{path}:{ln} 框超出图像边界\n) err_count 1 class_counter[cls] 1 print(问题数量:, err_count) print(空标签数量:, empty_count) print(类别分布:, sorted(class_counter.items()))逻辑说明脚本按行读取每个 txt把五个字段解包后逐个做数值范围校验。类别越界和中心点越界是硬错误代表标签本身已损坏优先处理框整体超出图像范围一般不阻止训练但会引入错误监督同样要定位。参数说明labels_dir改成labels/val就能检查验证集nc必须以你 data.yaml 里的实际值为准脚本不会自动推断。3.3 越界以后怎么办过滤还是裁剪issue_report.txt里如果出现“框超出图像边界”先看数量占比。只有零星几个说明标注源头的误差不大直接过滤掉这些目标即可。如果成片出现基本可以断定是某批 xml 的size字段与实际图像尺寸不一致导致转换时计算基准错了。这时候不要靠裁剪坐标去“修补”标签因为基准错的情况下裁剪出来的框仍然是偏的正确做法是拿原图真实尺寸重新生成整份标签。如果只是单条目标越界且你确实想保留它裁剪逻辑可以这样写def clamp_yolo_line(xc, yc, w, h): x1 max(0.0, xc - w / 2) y1 max(0.0, yc - h / 2) x2 min(1.0, xc w / 2) y2 min(1.0, yc h / 2) if x2 x1 or y2 y1: return None # 裁剪后面积趋近 0直接剔除 return (round((x1 x2) / 2, 6), round((y1 y2) / 2, 6), round(x2 - x1, 6), round(y2 - y1, 6))逻辑说明先把归一化坐标还原成左右、上下边界用min/max夹到 [0,1] 区间再重新换算回中心点和宽高。参数说明函数返回None时表示该目标被压没了调用方应跳过这行返回的四个浮点数保留了 6 位小数足够满足 YOLO 训练精度。3.4 把归一化坐标画回图像上做人工抽查数值检查只能发现边界问题无法确认框是否真的框在目标上尤其是类别名容易张冠李戴。可视化抽查我一般每个类别抽 10~20 张用 OpenCV 把检测框画出来import cv2 def draw_yolo(img_path, txt_path, class_names, out_path): img cv2.imread(img_path) h, w img.shape[:2] with open(txt_path) as f: for line in f: cls, xc, yc, bw, bh map(float, line.strip().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.putText(img, class_names[int(cls)], (x1, max(y1 - 5, 0)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite(out_path, img)逻辑说明归一化中心点先换算回像素坐标x1 (xc - bw/2) * w是框左边界y1同理绘制时类别文本放在框左上角偏上的位置。参数说明class_names必须按 data.yaml 的names顺序传入否则画出来的标签名是错位的抽查阶段发现大量“框在但类别名不对”的情况优先怀疑类别映射表不是图像。3.5 类别分布统计与少数类倾向检查脚本最后输出的类别分布是判断训练配置要不要调整的重要参考。像轨道这种长条形目标在图像里可能框数量不少但实际覆盖面积占比很小手推车如果样本量明显偏少默认权重下训练会出现漏检倾向。常见做法是先把各类别框数拉平看比例当最小类别框数不足最大类别十分之一时训练时可以考虑加大少数类的cls_loss权重或者对少数类做简单的离线增强——水平翻转、随机亮度变化就够了。不过第一次训练以跑通为主不用一上来就调权重知道分布比例就行。此外抽查时还要留意半标注现象即图像里明显有目标但标签漏了。半标注是数据增强和损失权重都救不回来的它会让模型把漏标目标当背景学。抽 5% 的图人工过一遍如果漏标率高这份资源的可用性就要打个折扣需要自己补标后再进训练。4. 从解压到跑通训练data.yaml 改路径用 YOLOv8 命令快速验证4.1 解压与目录整理mkdir -p ~/datasets/railway unzip YOLO算法-火车-轨道-手推车数据集-3793张图像带标签-火车-轨道-手推车.zip -d ~/datasets/railway/ cd ~/datasets/railway # 确认图像、标签、yaml 三个部分都在 find . -maxdepth 2 -type d | sort解压时留意路径里的中文。YOLO 工具链对中文路径的支持参差不齐尤其 Windows 下容易出现编码报错解压时直接放进纯英文目录后续能少踩一堆坑。如果 zip 解压后文件名乱码多半是压缩包内部使用 GBK 编码而解压工具默认用 UTF-8 解码换支持编码选择的工具重解一次即可。4.2 修改 data.yaml 的 train/val 路径打开 data.yaml把train和val改成绝对路径train: /home/you/datasets/railway/images/train val: /home/you/datasets/railway/images/val nc: 3 names: [train, rail, hand_truck]写绝对路径是为了避免命令行工作目录切换后出现「No labels found」。names的顺序就是 txt 里类别索引的对应表这里如果与实际标签不一致训练能跑但指标会非常怪异属于最难排查的那类问题。提示改路径前先备份原始 data.yaml排查问题时可以直接 diff 两份配置确认不是你改坏了。4.3 安装并执行 YOLOv8 训练pip install ultralytics yolo taskdetect modetrain \ modelyolov8n.pt \ data/home/you/datasets/railway/data.yaml \ epochs100 imgsz640 batch16 device0参数说明epochs第一次跑可以设短一点50 起步目标是验证数据链路通不通imgsz训练时会把图像 Resize 到这个尺寸标签是归一化坐标所以不受影响batch受显存约束8G 显存跑 16 容易 OOM先降到 8 更稳device0指定第一张 GPU没有 GPU 就改成devicecpu只是速度慢很多。yolov8n.pt是最小的主干模型适合验证链路如果数据集难度不大n 模型收敛速度最快后续再换 s/m/l 逐步提升精度。4.4 训练日志该怎么看训练一旦启动重点盯住下表的几个指标指标含义我观察什么train/box_loss边界框回归损失前 20 个 epoch 快速下降为正常持续震荡不降则回查标签train/cls_loss分类分支损失对应 YOLO 损失函数里的类别分量类别错位时它会先异常val/mAP50IoU0.5 时的平均精度对长条形目标比 mAP50-95 更直观val/mAP50-95IoU 0.5~0.95 的积分平均指标更严格数值通常比 mAP50 低不少新手先不用纠结推理速度和 mAP 的取舍完整跑完一次训练看到 val 指标正常出来才算数据集在这台机器上真正“跑通”。另外注意 ultralytics 默认开了早停patience控制连续多少个 epoch 验证指标不提升就停止训练。训练到 30 个 epoch 就停了但 mAP 很高这不是 bug是验证集上已经收敛。4.5 同一份数据切到 YOLOv5 或 YOLOv10这份数据集的核心价值在于双格式标签和 data.yaml 可以跨版本复用。切到 YOLOv5 时命令变为python train.py --data data.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100切到 YOLOv10 或 yolo11 时通常还是用 ultralytics 包只是把model换成对应的权重文件名。yolo txt 格式是所有 YOLO 版本通用的底层存储结构数据文件本身不需要改动。需要提醒的是不同版本的数据增强策略不完全一致v5 和 v8 在相同数据上跑出来的指标不能直接横向比但这不影响数据文件的复用。第一次迁移时固定imgsz、batch和随机种子才能判断指标差异是版本引起的还是数据引起的。5. 训练数据集避坑与常见问题排查五条「现象→原因→解决」记录这一章是数据加载与训练阶段的踩坑记录按「先现象、再原因、后解决」的顺序写方便对应自己的报错直接跳读。5.1 「No labels found」训练启动即退出现象YOLOv8 启动训练后打印No labels found in ...然后直接结束。原因yolo 默认会把images路径中的目录名替换成labels去寻找标签。如果解压后的标签目录不叫labels或images和labels不在同级就会找不到。另一种常见情况是 txt 后缀被系统隐藏显示成.txt.txt或标签文件是 0 字节。解决先把标签目录统一调整为labels并保持与images同级再执行ls -la看是否有隐藏字符最后用前面章节的扫描脚本统计空文件数量。这三步做完基本能定位问题。5.2 loss 直接 NaN 或数值爆炸现象第一个 epoch 的train/cls_loss直接是nan或者 loss 数值大到离谱。原因标签里混入了非数值内容比如某个 txt 中有一行是说明文字或者坐标出现极端值如 1e10 这种明显异常数据也可能是类别索引为 -1超出 YOLO 类别张量的合法范围。解决拿第 3 章的体检脚本全量扫一遍重点看字段数不等于 5 的行基本都是混入脏数据的文件。找到后对比同名 xml把正确的标注重新写回。这种情况手动修不如从 xml 重新生成 txt 干净。5.3 txt 与 xml 类别顺序不一致现象训练全程无报错但验证集里某一类的 AP 极低输出预测框发现框位置是对的标签名却整体错位。原因txt 里的类别索引是按某个顺序生成的而 data.yaml 的names列表顺序与它不一致。索引被整体平移比如原索引 0 是火车names 里索引 0 写了轨道模型学的就是把火车当轨道。解决写脚本交叉核对扫描所有 txt 中出现过的类别编号再和 xml 里name的集合做映射比对。两者能对齐修正 data.yaml 的names顺序对不齐直接用 xml 重新生成 txt。记住先核对再训练比训练后看指标猜原因要快得多。5.4 框画在目标上但 mAP 始终很低现象可视化抽查时框都在目标周围边界也基本贴合但训练多个 epoch 后 mAP 仍上不去。原因很可能是部分图像的尺寸与 xml 的size字段不一致。比如原图被压缩过但 xml 里还保留旧尺寸。归一化坐标是以 xml 尺寸为基准算的实际图像变小后框的位置就跟着漂移和画面内容错开。解决批量读取每张图像的真实宽高和同名 xml 的size做一致性比对如果确实被批量压缩过用图像真实尺寸重新生成整份标签。这里的教训是不要只看框形状是否正常要看框相对图像内容的位置是否准确。5.5 验证集 mAP 很高现场测试却漏检严重现象自带的验证集 mAP 有 70% 以上但拿现场拍的十几张图去测火车、手推车漏检明显。原因划分好的验证集和训练集来自同一拍摄批次光照、角度、环境高度同源。验证集指标只能证明模型在这个数据分布内有效不代表换到现场光照和遮挡条件下依然有效这不一定是数据集的问题而是验证结论有边界。解决从现场收集十到二十张图片组成一个很小的外部验证集用训练好的模型跑一遍推理以这组数据的结果判断能否部署而不是只看自带的 val 指标。这是我在多个数据集上反复验证过的经验前四条坑能靠脚本避开这一条只能靠对场景的清醒认识。6. 进阶验证技巧固定随机种子重训两次判断是训练问题还是数据问题6.1 用同一份数据跑两次看稳定性拿到数据集并且训练跑通一轮之后先别急着调参。我建议做一个低成本但信息量很大的验证固定随机种子把同一份数据用完全相同的超参数训练两次。Ultralytics 里直接加seed42即可yolo taskdetect modetrain \ modelyolov8n.pt \ data.../data.yaml \ epochs50 imgsz640 batch8 device0 \ seed42逻辑说明YOLO 训练涉及数据增强随机性、权重初始化随机性、shuffle 随机性不固定种子的话前后两次结果天然有波动。固定种子后如果两次训练出来的 mAP 相差 1~2 个百分点说明数据集的一致性够好后续调参可以放心如果两次相差超过 5 个百分点说明数据里存在影响收敛的噪声——这种噪声往往在标注层面比如边界框不齐、类别边缘模糊、少数类样本太少。此时的首要任务不是调学习率而是回头再看一眼第 3 章的检查报告。再做细一点同一个训练好的权重上跑yolo val打印出每个类别的 AP。三个类别里最容易出问题的是轨道这类长条形目标长宽比极端默认 anchor 和 imgsz 对它并不友好。如果只有这一个类 AP 明显掉队可以针对性地把imgsz提到 1280 重训或者单独给这个类做裁剪增强而不是整体换模型。这类验证的意义在于把“模型效果差”归因到正确的位置。很多时候问题不在 YOLO 结构也不在训练轮数而在数据本身的一致性。3793 张图像属于中等规模数据集适合做算法验证和预研但要部署到真实场景建议补充现场样本做一轮 fine-tune。从那以后我拿到任何新数据集第一步都是先跑标注体检脚本再做一次双种子稳定训练全部通过才进入正式的调参循环。这套顺序帮我少走了不少冤枉路希望帮到你。本文还有配套的精品资源点击获取
返回列表