☰
E_bicycle7雅迪电动车数据集:864张XML标注转YOLOv5训练全流程
2026/10/2 14:50:55 网站建设 项目流程

简介:本资源面向从事机器视觉与目标检测的开发者及学生,聚焦非机动车违规停放场景下的电动车识别任务,提供YOLOv5可直接训练使用的已标注数据。包内为电动车数据集中的第七类——雅迪电动车,共864张实拍图片,配套858个XML标注文件,压缩包约100MB,合计1722个文件,图片与标注一一对应,省去自行采集与标注的成本。该分类属于更大规模非机动车数据集的一部分,同类还涵盖山地、公路、通勤、共享单车,绿源、台铃、小刀、共享电动车,以及淮海、金彭、宗申等三轮车,每类约500至1000张,整体规模达两万余张,便于后续扩展多类别检测。目前已有2330人学习下载,适合用于违规停放识别、电动车检测模型训练与算法验证,可直接接入YOLOv5流程完成数据加载、训练与评估,快速验证检测效果。

1. 从 864 张雅迪电动车说起:这套 E_bicycle7 标注数据到底能干什么

如果你正在做园区、社区或者校园场景的非机动车违规停放识别,大概率绕不开一个现实问题:公开数据集里电动车样本太少,自己拍又凑不齐角度和光照。我手上这份 E_bicycle7 资源,就是专门解决这个卡点的——它是整个非机动车数据集里电动车分类的第七类,全部是雅迪电动车,864 张图片,每张都配了 XML 标注,直接对应 YOLOv5 的训练格式。

说白了,这份资源不是让你从零标注,而是把「数据准备」这一步替你走完了。你拿到手就能直接进 YOLOv5 的训练流程,把精力放在模型调参和部署上。适合两类人:一是刚接触机器视觉识别、想跑通一个完整非机动车违规停放检测流程的新手;二是手头有场景但缺电动车样本、需要快速补充某一类数据的老手。下面我按「数据长什么样 → 怎么转成 YOLO 格式 → 怎么训 → 坑在哪」的顺序拆一遍。

2. 拆开 E_bicycle7 数据包:864 张图与 XML 标注的结构

2.1 图片与标注的对应关系

这份资源的核心是「图片 + XML 标注」成对出现。864 张雅迪电动车图片,命名规则是「雅迪电动车_编号.jpg」,编号从个位数到四位数都有,比如雅迪电动车_41.jpg、雅迪电动车_1011.jpg。对应的标注文件是同名 XML,放在同一目录或者平行的 annotations 目录下,具体看你拿到的压缩包结构。

XML 的格式是 PASCAL VOC 风格,里面记录了图片尺寸、目标类别和边界框坐标。类别名统一是 E_bicycle7,这个命名很关键——它决定了你后面训练时模型输出的类别标签。如果你直接把这份数据混进自己的数据集,类别名冲突或者重复定义会直接导致训练报错。

我一般拿到这种数据包,第一件事不是急着转格式,而是先抽查三到五张图,确认 XML 里的 bndbox 坐标和图片里的电动车位置对得上。这一步花两分钟,能省掉后面几小时的排查。

2.2 数据规模在整体数据集里的位置

摘要里写得很清楚,这份 E_bicycle7 只是电动车大类下的一个子类。整个电动车部分有 8000 张左右,分绿源、台铃、小刀、雅迪、共享电动车等,每类 800 到 1000 张。雅迪这一类给了 864 张,属于正常量级。再往上,自行车 8000 张、三轮车 6000 张,整个非机动车数据集接近 22000 张。

这个规模意味着什么?如果你只做电动车违规停放识别,864 张够你训一个单类检测器,但泛化能力有限。更合理的做法是把这份数据当作「补充样本」,和你自己场景里的电动车图片混在一起训。雅迪这个品牌在现实中保有量高,样本多样性(角度、光照、遮挡)比你自己拍的要好。

提示:不要指望 864 张就能覆盖所有电动车外观。雅迪不同车型差异不小,如果场景里还有其他品牌,建议按比例混入。

2.3 标注质量与重复样本的处理

摘要里提到「极个别重复」,这是真实数据集的常态。重复样本分两种:一种是完全相同的图片被复制了两份,另一种是同一辆车不同角度但高度相似。前者必须去重,后者可以保留但要控制比例。

去重我一般用感知哈希(pHash)快速筛一遍,阈值设 5 到 8 之间。完全重复的直接删,高度相似的保留但打散到不同 fold 里,避免训练集和验证集出现同一辆车的不同角度,导致验证指标虚高。这一步不做,你看到的 mAP 可能是假的。

XML 标注本身也可能有框偏大、框偏小、漏标的情况。864 张里我抽查下来,大部分框是紧贴车身的,少数几张把旁边的柱子或者地面标线也框进去了。这种脏标注在训练时会引入噪声,建议用脚本把宽高比异常(比如宽高比大于 5 或小于 0.2)的框筛出来人工过一遍。

3. 从 XML 到 YOLO 格式:转换脚本与四个边界坑

3.1 为什么必须转成 YOLO 格式

YOLOv5 不认 PASCAL VOC 的 XML,它要的是每张图对应一个 txt 文件,每行格式是「类别索引 中心x 中心y 宽 高」,坐标全部归一化到 0 到 1 之间。这个转换看着简单,但边界情况不少。我见过太多人转完格式直接开训,结果 loss 不降,回头查才发现坐标没归一化或者类别索引从 1 开始。

下面这个脚本是我常用的版本,处理 E_bicycle7 这种单类别数据刚好够用。

import os import xml.etree.ElementTree as ET from PIL import Image # 类别映射:E_bicycle7 对应索引 0 CLASS_MAP = {"E_bicycle7": 0} def convert_annotation(xml_path, img_path, out_dir): tree = ET.parse(xml_path) root = tree.getroot() # 用 PIL 读图片真实尺寸,不信任 XML 里的 size with Image.open(img_path) as im: w, h = im.size lines = [] for obj in root.iter("object"): cls_name = obj.find("name").text.strip() if cls_name not in CLASS_MAP: continue cls_id = CLASS_MAP[cls_name] 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)) xmax = max(0, min(xmax, w)) ymin = max(0, min(ymin, h)) ymax = max(0, min(ymax, h)) # 归一化并转中心点格式 cx = (xmin + xmax) / 2.0 / w cy = (ymin + ymax) / 2.0 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h lines.append(f"{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}") if lines: base = os.path.splitext(os.path.basename(xml_path))[0] with open(os.path.join(out_dir, base + ".txt"), "w") as f: f.write("\n".join(lines))

逻辑说明:脚本先读图片真实宽高,而不是用 XML 里写的 size,因为有些标注工具的 size 字段是错的。然后对每个 object 做边界裁剪,防止 xmin 小于 0 或者 xmax 超过图片宽度。最后归一化并转成中心点加宽高的格式。

参数说明:CLASS_MAP 里 E_bicycle7 映射到 0,如果你后面要混入其他类别,在这里加映射就行,但索引必须从 0 开始连续。归一化保留 6 位小数,够用且不会引入精度损失。

3.2 四个容易翻车的边界情况

第一个坑是坐标越界。XML 里偶尔出现 xmax 大于图片宽度的情况,直接归一化会得到大于 1 的值,YOLOv5 训练时不会报错,但那个框实际是错的。脚本里的 max/min 裁剪就是防这个。

第二个坑是空标注文件。有些图片可能没有目标,XML 里 object 数量为 0。这种图如果生成空 txt,YOLOv5 会把它当负样本,但比例不能太高。我一般统计一下空标注比例,超过 5% 就考虑剔除部分。

第三个坑是类别名大小写和空格。E_bicycle7 如果写成 e_bicycle7 或者带前后空格,CLASS_MAP 匹配不上,转换后 txt 是空的。脚本里用了 strip(),但映射表的 key 必须和 XML 里完全一致。

第四个坑是图片格式。jpg 和 JPG 在 Linux 下是两个不同的文件名,遍历时如果只匹配小写后缀会漏文件。建议用 os.path.splitext 取后缀后统一转小写再判断。

3.3 转换后的目录结构

YOLOv5 要求的数据集结构是 images 和 labels 平行,train 和 val 分开。转换完我一般整理成下面这样:

dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/

划分比例按 8:2 或者 9:1,864 张的话验证集留 80 到 100 张就够。注意 images 和 labels 下的文件名必须一一对应,只是后缀不同。划分时用随机种子固定,保证每次跑的结果可复现。

4. 用这份数据训 YOLOv5:环境、配置与训练参数

4.1 环境配置的最小闭环

YOLOv5 的环境不算复杂,但版本对不上会出各种玄学问题。我一般用 conda 建一个干净环境,Python 3.8 到 3.10 都行,PyTorch 选 1.12 以上。CUDA 版本跟着显卡驱动走,不用追最新。

conda create -n yolo5 python=3.9 -y conda activate yolo5 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt

逻辑说明:先建环境再装 PyTorch,最后装 YOLOv5 的依赖。requirements.txt 里包含了 numpy、opencv、matplotlib 这些,版本已经锁好,不要手动升级。

参数说明:cu118 对应 CUDA 11.8,如果你的驱动只支持到 11.6,换成 cu116。装完用python -c "import torch; print(torch.cuda.is_available())"验证,返回 True 才算通。

4.2 数据配置文件怎么写

YOLOv5 用 yaml 文件描述数据集路径和类别。针对 E_bicycle7 单类数据,新建一个data/e_bicycle7.yaml:

path: ../dataset train: images/train val: images/val nc: 1 names: ["E_bicycle7"]

逻辑说明:path 是数据集根目录,train 和 val 是相对路径。nc 是类别数,单类就是 1。names 列表里的顺序必须和转换脚本里的 CLASS_MAP 索引一致,否则模型学到的类别会错位。

参数说明:如果你后面要混入自行车或三轮车数据,nc 改成对应数量,names 按索引顺序排列。改完记得检查转换脚本里的映射表同步更新。

4.3 训练命令与关键超参数

单类数据用 YOLOv5s 就够,模型小、训练快。命令如下:

python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/e_bicycle7.yaml \ --weights yolov5s.pt \ --project runs/train \ --name e_bicycle7_exp

逻辑说明:img 640 是输入分辨率,864 张图用 640 够用,想提精度可以上 1280 但显存翻倍。batch 16 是 8G 显存下的稳妥值,显存大可以加到 32。epochs 100 对单类数据通常够收敛,看 loss 曲线如果还在降可以加到 150。

参数说明:weights 用预训练的 yolov5s.pt,不要从零训,小数据集从零训基本学不出东西。project 和 name 控制输出目录,跑完在 runs/train/e_bicycle7_exp 下看结果。

训练过程中重点看三个指标:box_loss 是否稳定下降、mAP@0.5 是否在 30 个 epoch 后开始爬升、验证集的 precision 和 recall 是否差距过大。如果 recall 明显低于 precision,说明漏检多,可能是标注框偏小或者数据里小目标太多。

4.4 训练完怎么验证模型真的能用

训练结束不代表模型能用。我一般做两步验证:先用val.py跑一遍验证集,看 mAP 和混淆矩阵;再找几张训练集里没有的电动车图片做推理,肉眼确认框的位置和置信度。

python val.py --data data/e_bicycle7.yaml --weights runs/train/e_bicycle7_exp/weights/best.pt --img 640

逻辑说明:val.py 会输出每类的 AP 和整体 mAP,同时生成混淆矩阵和 PR 曲线。重点看 E_bicycle7 这一类的 AP,如果低于 0.5,说明数据或训练有问题。

参数说明:--img 必须和训练时一致,否则推理尺度不匹配会导致精度下降。--weights 指向 best.pt,不要用 last.pt,last 可能过拟合。

5. 避坑与排查:这份数据用起来最容易踩的五个问题

5.1 训练 loss 不降,mAP 一直是 0

现象:开训后 box_loss 在 0.5 附近震荡,mAP 始终为 0,模型不收敛。

原因:最常见的是类别索引不匹配。转换脚本里 E_bicycle7 映射到 0,但 yaml 里 names 写成了别的顺序,或者 nc 写成了 2。另一个可能是 txt 文件里坐标没归一化,值大于 1。

解决:随便打开一个生成的 txt,确认每行第一个数字是 0,后面四个数都在 0 到 1 之间。再检查 yaml 的 nc 和 names 是否和转换脚本一致。改完重新生成 labels 再训。

5.2 验证集 mAP 很高,实际推理全是误检

现象:val.py 跑出来 mAP@0.5 有 0.8,但拿真实场景图片推理,背景里的广告牌、垃圾桶都被框成电动车。

原因:训练集和验证集划分时没有打散,同一辆车的不同角度同时出现在 train 和 val 里,导致验证指标虚高。另外 864 张里如果背景单一,模型学到的是背景特征而不是电动车特征。

解决:重新划分数据集,用图片的感知哈希做分组,同一组只进 train 或 val。训练时加数据增强,YOLOv5 默认开了 mosaic 和 HSV 增强,确认没被关掉。如果背景太单一,混入一些负样本图片。

5.3 XML 解析报错,提示 not well-formed

现象:转换脚本跑到某张图时抛异常,提示 XML 格式错误。

原因:标注文件在保存时被截断,或者里面有非法字符。这种情况在批量标注的数据里不罕见。

解决:用 try/except 包住 ET.parse,遇到解析失败的记录文件名,跳过并记录。跑完统计跳过了多少张,如果超过 10 张,建议找标注方重新导出。

5.4 显存不够,batch 降到 4 还是 OOM

现象:训练启动后报 CUDA out of memory,降 batch 也没用。

原因:YOLOv5 默认会开多尺度训练和 mosaic,显存占用比预期高。另外如果 img 设了 1280,显存需求是 640 的四倍左右。

解决:先把 img 降到 640,batch 设 8。如果还不够,在 train.py 里加--nosave减少中间权重保存,或者用--workers 2降低数据加载进程数。实在不行换 yolov5n,模型更小。

5.5 推理时框的位置偏移,明显偏左或偏上

现象:模型能检出电动车,但框整体往左上偏移,和车身对不齐。

原因:转换时用了 XML 里的 size 字段而不是图片真实尺寸,两者不一致导致归一化基准错了。或者推理时的预处理 resize 和训练时不一致。

解决:确认转换脚本用的是 PIL 读出的真实宽高。推理时用 YOLOv5 自带的 detect.py,不要自己写预处理,它的 letterbox 逻辑和训练时是对齐的。

6. 把 E_bicycle7 用出更高价值:混类训练与部署前验证

单类数据训出来的模型,放到真实场景里往往不够用。我的习惯是把 E_bicycle7 当作电动车类的种子数据,和自行车、三轮车数据按比例混合,训一个多类检测器。这样模型学到的特征空间更大,对电动车本身的泛化反而更好。

混合时注意类别平衡。假设你手头有自行车 8000 张、三轮车 6000 张、电动车只有这 864 张,直接混进去电动车会被淹没。我一般对多的类别做下采样,每个类别控制在 2000 到 3000 张,电动车不够就用这 864 张加上自己补拍的。类别索引重新排,E_bicycle7 可以映射到电动车大类下的一个子索引,也可以直接归到「电动车」这个大类里。

部署前我强制走一遍的验证流程是这样的:从验证集里挑 20 张,再从真实场景拍 20 张,混在一起跑推理,统计误检和漏检。真实场景那 20 张是关键,验证集指标再高,真实场景翻车就是翻车。这一步我吃过亏,有一次验证集 mAP 0.85,实际部署到园区门口,晚上光线暗的时候漏检率超过一半。后来补了夜间样本重新训才解决。

还有一个技巧是导出 ONNX 之后用 onnxruntime 跑一遍,对比 PyTorch 和 ONNX 的输出差异。如果差异大,说明有算子不被支持或者导出时的 opset 不对。YOLOv5 导出命令是python export.py --weights best.pt --include onnx --opset 12,opset 12 兼容性最好。

从那以后我每次拿到新数据集,都强制先跑一遍「转换 → 抽查 → 小规模训 10 个 epoch → 真实场景验证」这个闭环,确认没问题再上全量训练。这套流程帮我省下了不少返工时间。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询