基于YOLO v8的GB-AC与GB-DC充电插口检测数据集训练实战
发布时间:2026/10/2 9:31:56 作者:尧图编辑部 阅读量:1,286

简介汽车充电插口识别数据集面向YOLO v8目标检测训练与验证覆盖GB-AC国标交流与GB-DC国标直流两种常见充电插口类型适用于新能源汽车充电桩自动识别、智能引导插枪、车辆充电口定位等场景。包体共2000个文件包括1191张jpg原始图像、1191个txt标注文件以及1个yaml配置文件压缩包大小22.26MB其中txt文件为YOLO格式的边界框标注yaml文件定义了类别名与数据集路径可直接放入YOLOv8项目中使用。数据集由图像与对应标注一一配套免去自行采集和标注的耗时工序用户即可开始训练高精度充电插口检测模型也可根据业务需要扩充类别或调整训练参数。已有272人学习下载资源体积紧凑适合刚接触目标检测的开发者快速上手也适合需要标准训练数据集的车辆视觉项目团队。1. 充电插口识别是什么问题GB-AC与GB-DC为何值得单独做数据集做移动充电机器人或者自动泊车充电项目的人第一道坎往往不是机械臂怎么对准而是视觉系统压根认不出面前这个洞是什么类型。国标充电插口在物理结构上分成 GB-AC 交流慢充和 GB-DC 直流快充两大类插错枪座轻则充不进电重则机械爪直接怼坏接口。这个标题给到的资源——1191 张已标注、可直接喂给 YOLO v8 训练的数据集解决的就是这个「先认出是什么、再谈对得准」的前置环节。适合正在做自动充电引导、充电站运营监测、车位插口状态识别的视觉工程师也适合刚入手自定义数据集训练、想找一份真实工业场景数据练手的人。1191 张不算多但这两类插口的物理差异足够大训练到可用的精度完全够。2. 拿到数据集先别急着开训结构与标注质量决定上限2.1 YOLO v8 的数据集目录结构先对齐再动手YOLO v8ultralytics 框架对数据集的目录约定其实延续了 YOLO 系列的惯例图片和标注文件分离按 train、val可选 test分目录。拿到数据集后第一件事不是开 Notebook而是把目录结构铺开看一遍。标准结构是 images 与 labels 两个根目录下面再分 train 和 val标签文件用同名 txt 一一对应图片。一份合格的 YOLO v8 数据集目录长这样dataset/ ├── images/ │ ├── train/ │ │ ├── img_0001.jpg │ │ └── ... │ └── val/ │ ├── img_0001.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── img_0001.txt │ │ └── ... │ └── val/ │ ├── img_0001.txt │ └── ... └── data.yaml每个 txt 文件里是一行一个目标格式固定为class_id x_center y_center width height坐标全部归一化到 01 之间。比如0 0.512 0.438 0.196 0.223表示一个类别 id 为 0、中心点在图中 51.2%、43.8% 位置、宽占比 19.6%、高占比 22.3% 的框。拿到数据集后先用一条命令确认图片和标签是否一一对应避免后面训练时报 missing label 或者图片没有标签的错find dataset/images -name *.jpg | wc -l find dataset/labels -name *.txt | wc -l数量不一致先别往下走。常见问题是原始数据里混了几张截断图或空标注图导致某一侧多出文件。这个数据集标注得相对规整但我每次接手新数据集都习惯先做这一层检查属于「花五分钟省两小时」的活。2.2 标注分布检查两个类别到底均衡不均衡1191 张图GB-AC 和 GB-DC 两类。下一步是检查类别分布和每个框的尺寸、坐标是否异常。类别不均衡会影响模型对少数类的召回率而坐标异常比如归一化坐标大于 1、宽高为 0会让训练直接产生 NaN loss。用一段短脚本把所有标注文件扫一遍统计类别数量和框质量问题# check_labels.py import os from collections import Counter labels_dir dataset/labels/train class_counter Counter() bad_files [] for file in os.listdir(labels_dir): if not file.endswith(.txt): continue file_path os.path.join(labels_dir, file) with open(file_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: bad_files.append(file) continue cls, cx, cy, w, h int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) # 归一化坐标越界或宽高非正的框直接记下来 if w 0 or h 0 or not (0 cx 1) or not (0 cy 1): bad_files.append(file) continue class_counter[cls] 1 print(类别分布:, dict(class_counter)) print(异常文件:, set(bad_files))运行后看两点一是类别分布比如{0: 822, 1: 748}这种量级二是异常文件列表。如果某一个类占比明显低训练时就要考虑对少数类做针对性增强或者降低正样本阈值。除了坐标格式还要看框的面积分布。充电插口在整张图里的占比很影响训练结果。把每个框的 w*h 算出来画个直方图如果大量框宽高占比只有 0.05 以下即插口在图中属于小目标训练时就要重点调 imgsz 或者切图策略。2.3 GB-AC 与 GB-DC 的视觉差异看什么来定义标注边界模型能不能学会区分两类前提是人类自己有没有把标注边界定清楚。GB-AC 交流插口参考 GB/T 20234.2 的接口形态通常是一个 7 芯圆形排列的腔体整体尺寸相对紧凑枪座外侧带有防呆缺口视觉上偏「内敛」。GB-DC 直流插口参考 GB/T 20234.3是 9 芯布局腔体明显更大更粗壮孔位更粗而且随着快充功率等级不同周围还可能带辅助散热结构或高压警告标识。标注规范里最容易出现分歧的是「框哪里」。我见过四种标法只框内腔、框整个枪座外壳、框到固定螺丝边缘、把周围线缆一起框进去。四种标法都能训出模型但换场景后表现差异巨大。只框内腔的模型在近景表现最好但中远景内腔太模糊容易丢框整个外壳的模型更稳但两个类靠外观轮廓区分时容易混淆。建议默认采用「框住整个枪座外沿」的规范因为检测任务对定位精度要求不那么苛刻但对外观特征的完整度要求很高。模型需要看到外沿厚度、防呆缺口、孔位排列这些上下文信息来做分类决策。如果你手里拿到的标注本来就是这个风格那训练时少踩很多坑。2.4 标注工具的返工成本什么时候值得重新标1191 张数据不是大数目如果发现标注规范不一致比如有的框内腔有的框外壳最好的选择是直接返工而不是将就着训。返工工具我一般用 CVAT 或 LabelImg 之类常见的 YOLO 标注工具导出时选 YOLO 格式就能直接覆盖原 txt。一个人一天能重标 300500 张两天时间换后面的模型稳定性划算。返工时建议同时做一件事把「插枪状态下」的图单独归类。车端插口被枪头插住时视觉上是一个圆柱体捅进枪座这时标注框和空置时的外沿形态不同。这部分图要么标为 same class要么拆出去单独做状态分类混在一起会让检测器困惑。3. 用 YOLO v8 在 1191 张标注数据上跑通训练3.1 环境准备与数据划分把验证集留出来训练前先装 ultralytics 包当前稳定版可以直接通过 pip 安装依赖 PyTorch 和 torchvision。装好后确认 GPU 可用然后做数据划分。1191 张图按 85/15 划分比较合理——大概 1012 张训练、179 张验证。验证集太少会导致最后评估指标的置信区间很大所以下限保底留 150 张。用一段脚本完成按比例划分同时保证同名图片和标签被移入同一侧目录# split_data.py import os, shutil, random random.seed(42) src_images dataset/images/all src_labels dataset/labels/all for split in [train, val]: os.makedirs(fdataset/images/{split}, exist_okTrue) os.makedirs(fdataset/labels/{split}, exist_okTrue) files [f for f in os.listdir(src_images) if f.endswith(.jpg)] random.shuffle(files) val_count int(len(files) * 0.15) for i, img in enumerate(files): split val if i val_count else train label img.replace(.jpg, .txt) shutil.move(os.path.join(src_images, img), fdataset/images/{split}/{img}) shutil.move(os.path.join(src_labels, label), fdataset/labels/{split}/{label})划分要保证 shutil.move 成功执行也就是原始目录里必须有对应的同名 txt否则会抛 FileNotFoundError。random.seed(42) 固定随机种子保证复现结果一致。划分完成后建议再跑一遍 2.2 节的检查脚本确认 train 和 val 的类别分布没有偏移。如果某一类全部流到 train而 val 里该类样本极少后面评估 mAP 就会虚高或虚低。3.2 写 data.yaml 并启动训练关键参数逐个说data.yaml 是 ultralytics 读取数据配置的唯一入口。它必须包含三个关键字段path 指向数据集根目录train 和 val 是相对于 path 的图片目录名nc 是类别数names 是类别名字符串列表。# data.yaml path: /home/ubuntu/dataset # 数据集的绝对路径改成你自己的 train: images/train val: images/val nc: 2 names: [GB-AC, GB-DC]path 用绝对路径最省事省得相对路径问题。nc 必须是 2names 的顺序决定类别 idGB-AC 是 0、GB-DC 是 1。这里顺序其实无所谓只要和 2.2 节脚本里统计 class_counter 时看到的 id 含义一致就行。接着启动训练。我用 COCO 预训练权重做迁移学习通常选 yolov8n.pt 或 yolov8s.pt。1191 张属于小数据集n 或 s 足够m 以上容易过拟合且训练更慢。yolo detect train \ modelyolov8n.pt \ datadata.yaml \ epochs150 \ imgsz640 \ batch16 \ device0 \ workers8 \ patience30 \ lr00.01 \ projectruns/detect \ namegb_charging参数怎么理解、怎么改逐个说清楚modelyolov8n.pt从 COCO 预训练权重起步YOLO v8 的 backbone 能复用通用特征。如果完全从零训练1191 张很难收敛得好深度。epochs150数据集小150 轮足够让 loss 平原化。配合 patience30 做早停loss 连续 30 轮不下降就自动终止省时间。imgsz640默认尺寸。但 2.2 节如果发现插口框宽度占比普遍小于 0.1即图中属于小目标建议升到 800 或 896。代价是显存占用增加和训练时间变长。batch16在 24G 显存的卡上n 模型配 640 输入跑 batch16 很稳。显存小就降到 8梯度积累参数不用动。lr00.01ultralytics 默认初始学习率改小到 0.005 会收敛慢但更稳数据里噪声大时可以试试。这个参数属于「玄学」区间没有标准答案。project 和 name输出目录。训练完的权重默认存到 runs/detect/gb_charging/weights/best.pt。训练日志里重点盯两个输出每个 epoch 的val/box_loss和metrics/mAP50(B)。box_loss 下降说明定位在收敛mAP50 上升说明识别效果在变好。如果 mAP50 在某个值震荡上不去先停一轮实际推理看看别急着加轮次。3.3 训练中断和恢复给意外留条后路训练到一半掉线是常态。ultralytics 支持从断点继续训练不需要重新来一轮yolo detect train resumeTrue modelruns/detect/gb_charging/weights/last.ptresumeTrue 会自动读取同一目录下的训练状态。注意它必须配合 modellast.pt 使用best.pt 是评估最优权重不携带优化器状态无法断点续训。保存 last.pt 这个动作本身就是给训练买的「后悔药」每次跑长训练我都提醒自己别手贱删掉。4. 评估与推理模型到底能不能直接放到现场4.1 两个核心指标怎么读mAP50 与 mAP50-95训练结束终端会打出一张指标表。GB-AC 和 GB-DC 是两个类最终看所有类别的平均结果也就是 mAP。这里最容易读错的是 mAP50 和 mAP50-95 的区别表格对比如下指标计算方式对充电插口任务的意义mAP50IoU 阈值固定 0.5算所有类别的平均 AP只看框「有没有大致框中」对插口识别更实用因为后续有机械对准环节mAP50-95IoU 阈值从 0.5 到 0.95 每 0.05 算一次再取平均对框的精确贴合度更敏感。插口任务里 mAP50-95 偏低不必焦虑这个数据集上mAP50 跑到 0.85 以上就值得进现场小规模实测mAP50-95 在 0.550.7 都正常。如果你发现 mAP50 很高但 mAP50-95 特别低说明框的贴合精度不够检查标注框是否普遍比目标外沿大一圈或小一圈。验证集每张图都会输出预测框和置信度。用官方指标脚本把每类的 precision、recall、mAP 单独看不要只看均值。实际项目里两类识别难度往往不同GB-DC 的接口形态特征更明显通常 AP 高GB-AC 紧凑小巧偏暗环境下容易漏检。4.2 用训练好的权重跑一次批推理训练完直接跑一批验证集图片把预测结果可视化保存这是最直观的验收方式:yolo detect predict \ modelruns/detect/gb_charging/weights/best.pt \ sourcedataset/val \ conf0.25 \ iou0.45 \ saveTrue \ projectruns/predict \ nameval_inferenceconf0.25 是置信度阈值低于 0.25 的框会被丢掉。这个值后期部署时按场景调识别率优先就降到 0.15误检率优先就提到 0.4。iou0.45 是 NMS 的去重阈值两个框重叠超过 45% 时保留置信度高的一个。saveTrue 会在 runs/predict/val_inference 下保存带标注框的结果图。跑完后打开结果图重点看三类样本的错误模式GB-DC 被标成 GB-AC 的交叉误检、完全漏检的图、一个插口出了两个框的重复检测。这三类错误分别对应特征混淆、目标过小和 NMS 参数不当后面避坑章节详细展开。4.3 导出模型从 PyTorch 权重到部署格式训练产物 best.pt 是 PyTorch 权重开发阶段够用。但部署到嵌入式设备或服务端一般导出为 TensorRT 或 ONNX 格式。yolo export modelruns/detect/gb_charging/weights/best.pt formatonnx dynamicTrueexport 时要注意输入尺寸和训练一致。训练用的 imgsz640导出后推理就按 640 输入。如果部署设备性能差可以导出时用 imgsz416但这是模型没见过的输入尺寸精度会掉一截通常不建议在训练后随意改输入分辨率改动前先跑一轮评估。5. GB-AC 和 GB-DC 识别的几个经典翻车现场与排查思路5.1 翻车现场一插口在画面里占比太小验证集 mAP 高但实景全漏现象验证集 mAP50 有 0.85换成现场整机画面后几乎框不出目标或者框出来置信度只有 0.1。原因训练图和现场实景的成像构图差异太大。训练数据里插口占了画面主体框宽占比普遍在 0.2 以上模型没有见过「插口只占画面 5%」的远端视角。解决先量化差距。把现场图抽几张量一下插口 bounding box 的宽占画面比例如果训练集主要在 0.20.4、现场在 0.050.1就得换数据策略。最常见做法是用 SAHI 这类切片推理库把大图切块后再逐个检测再聚合或者重新收集远端视角样本把框占比区间补到 0.050.3 的分布上去。另外把训练 imgsz 从 640 提到 896对小目标也是一种直接补救。5.2 翻车现场二夜间逆光暗部插口直接吞没现象白天测试没问题傍晚或夜间识别率断崖下跌插口区域在画面里一片死黑。原因数据集大概率以白天自然光为主缺少夜间补光环境下的样本。充电插口所在的枪座通常是深色塑料逆光时整个区域灰成一团模型提取不到孔位纹理。解决先做数据增强层面的补丁——开启 HSV 增强和亮度扰动用 YOLO v8 内置的 hsv_h、hsv_s、hsv_v 参数把训练图变暗变偏色模拟夜间。但增强只是治标治本要补夜间样本。带红外或可见光补光重新拍一版标注后加入训练集这个方向没有太多替代方案。5.3 翻车现场三标注框过紧推理时框抖动、两个框重叠现象同一张图连续推理两次框的位置有 35 个像素的抖动有时候一个插口被框了两个重叠框。原因标注框如果只贴着内腔边缘框和目标边界之间没有留误差余量模型学到的特征边界过于敏感特征图稍有波动框就跳。NMS 去重阈值 iou0.45 对高重叠框应该能合并但如果两个框置信度都高且重叠不到 45%就会保留两个。解决标注规范改成「框住整个枪座外沿」让框边缘和目标边缘留足像素推理时把 iou 阈值降到 0.3让 NMS 更大胆地合并重叠框。如果两个框来自同一个目标的概率很高但重叠率低考虑是标注框宽高比不一致导致回看标注修正。5.4 翻车现场四GB-DC 枪头插在车上同一目标算有枪还是没枪现象空置状态的 GB-DC 识别很准但充电中车辆插枪后模型时对时错甚至把枪头识别成另一类。原因数据集标题明确只识别「充电插口」本体标注时可能只覆盖了空置枪座。插枪后外部枪头改变了枪座的轮廓特征和上下文模型没见过这个形态。解决明确业务定义——如果需求是「识别插口类型并引导机械臂插枪」那插枪状态下应该锁定到枪座位置而不是枪头。处理方式是把插枪状态图片单独标注为同一类目标还是框到枪座但这时枪头会占用一部分框面积或者训练一个前置的「插枪状态分类器」做条件分支状态不同走不同检测逻辑。这个坑是数据定义问题模型只是照单全收。5.5 翻车现场五过拟合——验证集 90%新场地跌到 50%现象验证集 mAP50 接近 0.95模型看起来已经「到位了」换一个光线不同的停车场后直接掉到 0.5。原因1191 张图的数据量如果图片采集集中来自少数几个场地模型大概率泛化不足。从训练日志能看出端倪train_loss 持续下降val_loss 在某个 epoch 后不再降甚至反升。另一个信号是 mAP50-95 和 mAP50 差值过大说明模型在训练集上学到了背景纹理等「捷径」。解决过拟合的常规三板斧——加大数据增强尤其是随机的裁剪缩放、光照扰动、提高权重衰减 weight_decay、用更小的模型减少参数量。从 n 换到 s 反而可能过拟合更严重数据量不变时模型越小越好。最有效的还是扩充训练数据的场景多样性哪怕只补 100 张不同场地、不同角度、不同光线的图都比再加 500 张同场景图有用多。这也是这类数据集后续维护的重点方向。6. 把识别精度再往上顶的三件事6.1 两段式思路先粗定位再分类比单模型更稳单模型在做「找出插口 判断类型」两件事时精度上限受制于共享特征。一种常见做法是把任务拆成两段第一段用纯检测把插口找出来不管类型第二段对裁剪出的插口区域做细分类。YOLO v8 的检测头本身能做前一段分类用它的分类头或者单独的 CNN 都行。第一段可以把两个类合并只输出一个类别的框第二段拿到裁剪图后按 GB-AC、GB-DC 做二分类。两段式的代价是推理链路变长收益是分类精度通常能涨 23 个点特别是在近景切图后特征更清楚。6.2 用 SAHI 处理大图小目标一个切片就解决问题现场机位如果架在车位侧上方一幅 4K 画面里充电插口往往只占几十到一百像素。SAHI 的做法是对大图做重叠切片推理每个切片独立过模型再对切块边界的目标做聚合去重。切块尺寸一般取 640×640 或 896×896重合率设 20%。切片后小目标框对应的像素占比被放大模型识别率会显著回升。代价是推理时间成倍增加移动充电机器人这类算力受限的场景要权衡但固定机位服务端推理完全扛得住。6.3 用它自己的误检集做迭代把给它的数据还给它训练结束后把验证集之外的真实场景图跑一遍批量推理凡是置信度低、重复框、交叉误检的结果全部收集起来归为「hard example 集」。有价值的部分单独补标注下次训练时合入。这个「误检集回注」的习惯比反复调参数带来的收益更稳定。我自己做充电插口识别这类工业检测项目的经验是参数靠调参解决的是下限数据迭代解决的是上限前三次数据迭代的 mAP 涨幅通常比任何一次参数调整都大。这个 1191 张的数据集提供了不错的基础但真正让模型在你自己的现场站稳的是你从它出发持续补进去的那些「翻车图」。希望这些思路能帮你把第一版模型顺利跑起来少走几趟我走过的弯路祝顺利。本文还有配套的精品资源点击获取