
简介面向新能源汽车电池健康管理与机器学习研究者的小型项目代码包配合大规模三元锂离子电池运行数据集帮助快速开展电池状态估计、剩余寿命预测等数据驱动研究。压缩包仅6KB共3个文件包含HTML展示页、gitignore配置文件及inscode入口文件便于了解数据读取与调用流程。已有175人学习下载此资源。数据集由智能汽车安全技术全国重点实验室发布源自300辆运营车辆的真实行驶数据覆盖0-50万公里与0.5-4年周期采样间隔10秒总帧数约8.5亿含SOC、SOH、电压、电流等13个关键字段同时提供100MB样例数据和72GB全量CSV并附标准引用格式可支撑电池健康状态估计、剩余寿命预测、BMS算法优化等研究对电池老化规律挖掘具有重要价值。 做新能源汽车电池相关的视觉检测最难的不是模型选型而是手里没有一套能用的数据。我去年花了大半年时间从产线实地采集、缺陷标注到格式转换最后把整套方案整理成了一个带完整项目代码的新能源汽车电池数据集工程。这篇就把整套流程掰开揉碎讲清楚电池缺陷类别怎么定、标注怎么做才不会被模型带偏、VOC格式怎么转成YOLO能直接跑的格式、YOLOv8训练时踩过的坑以及完整项目代码结构怎么组织。不管你是刚入门工业视觉还是已经在做电池质检但被数据质量折磨得头疼这篇应该都能帮你少走不少弯路。1. 项目起点为什么做一套电池数据集1.1 电池质检场景的真实需求新能源汽车电池从电芯生产到模组封装表面缺陷直接关系到安全性和良品率。产线上一块电池从卷绕、焊接、封装到下线要经过好几道视觉检测工序常见缺陷包括极耳弯折、焊渣飞溅、表面划痕、凹坑、脏污等等。这些缺陷形态差异大、光照干扰多通用目标检测模型直接拿COCO预训练权重硬上效果往往很差。我当时接到的需求很明确给一条电池模组产线做缺陷检测算法验证。但翻遍公开数据集几乎没有针对新能源电池表面缺陷的现成数据。有的数据集是电池X光图像有的是电芯微观结构图跟工业相机拍出来的表面缺陷完全不是一回事。最后决定不纠结了直接自己在产线搭采集环境从零构建一套新能源汽车电池表面缺陷数据集同时把整个流程沉淀成可复用的项目代码。1.2 数据集的项目定位与技术选型这套数据集工程在动手之前我给自己定了几个硬性指标第一缺陷类别要覆盖产线真实出现的类型而不是实验室里理想化的样本第二标注格式要同时兼容VOC和YOLO两种主流格式方便后续换模型时不重新标注第三项目代码要能一条龙跑通从数据预处理到模型训练评估的全部流程。选定方向之后就是技术选型。检测框架我选了YOLOv8理由很直接工业场景部署友好、训练推理速度快、单阶段模型在中小目标缺陷上表现够用。虽然双阶段模型比如Faster R-CNN在某些极端小缺陷上精度略高但产线实时性要求摆在那里YOLOv8的性价比明显更合适。数据格式方面标注阶段用VOC格式XML文件保存因为标注工具支持好、人工检查方便训练阶段再通过脚本转成YOLO格式TXT文件因为在YOLO系列里读取效率更高而且做数据增强时不容易出错。2. 数据采集与标注最耗时但是最值的环节2.1 采集场景设计与缺陷类别定义采集环境我搭了一套简易的暗室采集装置工业面阵相机加环形LED光源分辨率为2048×1536拍摄距离固定。之所以用环形光源而不是条形光源是因为电池表面尤其是焊接区域有金属反光环形光源能有效减少镜面反射带来的不均匀光照。这里有个容易被忽略的细节光源亮度不是越亮越好我实测下来把光源亮度调在最大值的70%左右缺陷对比度最清晰过亮反而会把浅划痕洗白。缺陷类别定义是整个数据集最关键的决策点。我去产线蹲了一周统计了实际生产中最常见、最影响判断的缺陷类型最终确定了5个类别scratch划痕电池外壳表面的线状划伤长短粗细差异大dent凹坑磕碰或压伤导致的凹陷边缘通常有阴影weld_splash焊渣焊接过程中飞溅的金属颗粒形状不规则stain脏污油污或电解液残留呈片状分布burr毛刺极耳切割或冲压产生的金属毛边每类缺陷采集了约2500张图像总共12800张按7:2:1划分训练集、验证集和测试集。这个比例在工业数据集里比较常用因为缺陷样本获取成本高测试集再多就会压缩训练数据量。每张图像中缺陷实例数量不均衡单张最多有十几个小焊渣最少只有一个划痕这种自然的分布反而更贴近真实产线场景。2.2 标注工具选择与质量管控标注工具我对比过LabelImg、Labelme和X-AnyLabeling最后选定了LabelImg。原因很朴素它支持VOC格式的XML直接导出界面简单标注框能自动吸附边缘对工业场景的矩形框标注来说效率最高。Labelme更适合多边形分割标注但缺陷检测用矩形框就已经能满足要求没必要把标注复杂度拉高。标注过程踩了一个大坑初期标注标准不统一有人把浅划痕标了有人漏了有人把脏污的整个区域框进去有人只框了深色核心部分。这直接导致前500张图的标注质量参差不齐。后来我紧急拉了一个标注规范评审会明确了三条规定目标必须完全包含在框内且预留2-3像素边距多个缺陷粘连时分开标注被遮挡超过50%的缺陷不标注。规范定了之后我让团队重新检查了之前标注过的图返工了差不多两轮才稳定下来。标注完成后的质量检查同样不能省。我写了一个简单的标注可视化脚本把每张图的标注框叠加在原始图像上生成预览图人工快速扫一遍就能发现框偏移、漏标、类别标错的问题。这一步看起来笨但确实能拦截大部分低级错误。最终数据集的质量合格率控制在98%以上这为后续训练省了很多调试时间。3. 数据清洗与格式转换喂给模型前的最后一步3.1 VOC与YOLO格式的转换脚本标注完的数据是VOC格式每张图像对应一个XML文件记录着目标类别和边界框坐标左上角x、y、右下角x、y。但YOLO系列训练时用的是归一化的中心点坐标加宽高x_center、y_center、width、height并且全部除以图像宽高做归一化。所以必须先写一个转换脚本把XML转成TXT。转换脚本的核心逻辑不复杂但有几个细节要注意。图像尺寸必须从XML里的width和height字段读取而不是用PIL重新打开图片获取因为标注时的图片尺寸和实际resize后的尺寸如果对不上坐标就会错位。另外类别名称需要映射成数字id这个映射表必须是固定的训练和推理时用同一份。import os import xml.etree.ElementTree as ET from pathlib import Path def voc_to_yolo(xml_path, out_dir, class_names): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue class_id class_names.index(name) bbox obj.find(bndbox) x_min float(bbox.find(xmin).text) y_min float(bbox.find(ymin).text) x_max float(bbox.find(xmax).text) y_max float(bbox.find(ymax).text) x_center (x_min x_max) / 2 / img_w y_center (y_min y_max) / 2 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) out_path Path(out_dir) / (Path(xml_path).stem .txt) with open(out_path, w) as f: f.write(\n.join(lines)) class_names [scratch, dent, weld_splash, stain, burr]这个脚本我用了很久后来还加了一个校验函数检查转换后的TXT中是否有越界坐标比如x_center大于1或者width为0有就说明原始XML有问题直接标记出来人工复核。这一步能提前拦截标注时的坐标手误别小看这个检查我至少抓出来过三十多张标注框坐标反了的问题图。3.2 数据增强与样本平衡处理转换完成之后数据增强是进一步提高模型泛化能力的关键步骤。工业场景能用到的增强策略和自然图像不太一样随机翻转、缩放、亮度对比度调整是安全的但Mosaic增强需要谨慎使用因为电池表面的缺陷比例相对小过强的拼接增强可能让模型学到错误的上下文信息。我的策略是轻度到中度增强。训练时开了YOLOv8自带的Mosaic概率0.8和MixUp概率0.1同时把HSV扰动幅度调低Hue只动0.01、Saturation动0.5、Value动0.3这样既增加了样本多样性又不会把金属表面的颜色特征破坏得太厉害。实测下来同样的模型结构开增强比不开增强在验证集上mAP0.5能高出接近5个百分点。样本不平衡的问题主要出在burr毛刺这个类别上。毛刺通常出现在极耳边缘所占像素很少标注实例数量也不如stain多。我尝试过复制粘贴小目标增强把毛刺实例随机粘贴到其他无缺陷图像上但因为粘贴边缘的过渡不自然模型反而学到了毛刺周围总是有突变边界这种假特征。后来放弃了这个方案改用给burr类别在损失函数中加权的方式在YOLOv8的配置文件里通过对每个类别设置不同的loss权重来缓解效果更稳。4. 模型训练与项目代码架构4.1 基于YOLOv8的训练配置训练部分我直接用了Ultralytics的YOLOv8版本锁定在8.0.x因为这个版本接口稳定我试过之后就把项目依赖固定下来了。训练前先写一个数据集配置文件data.yaml内容很直观path: /path/to/nev_battery_dataset train: images/train val: images/val test: images/test nc: 5 names: [scratch, dent, weld_splash, stain, burr]模型基准我选了yolov8s.pt预训练权重。为什么不是nano也不是mediumnano轻量但精度损失较多在细小的划痕和毛刺上漏检率偏高medium精度更高但推理速度下降明显产线如果未来要并行处理多路相机流可能扛不住。yolov8s在精度和速度之间最均衡。训练命令参数如下yolo detect train \ datadata.yaml \ modelyolov8s.pt \ epochs150 \ batch16 \ imgsz640 \ patience20 \ lr00.01 \ lrf0.01 \ projectruns/detect \ namebattery_defect初始学习率0.01是YOLOv8的默认值对大多数场景是合理的起点。batch size16是在一块RTX 408016GB显存上测试出来的再往上加显存会爆往下减到8则训练速度明显变慢。imgsz640适合我这边图像中缺陷的中等尺寸分布没有盲目调到1280因为更高分辨率虽然对小目标有好处但训练时间几乎翻倍。4.2 项目代码结构讲解整套项目代码我按功能模块拆分成了清晰的目录结构方便后续扩展和维护nev-battery-dataset/ ├── config/ │ └── data.yaml ├── data/ │ ├── raw/ # 原始采集图像 │ ├── annotations/ # VOC格式XML标注 │ ├── labels/ # YOLO格式TXT标注 │ ├── images/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ ├── scripts/ │ ├── voc_to_yolo.py # 格式转换脚本 │ ├── split_dataset.py # 数据集切分脚本 │ ├── check_labels.py # 标注质量检查脚本 │ └── visualize.py # 标注可视化脚本 ├── train.py # 训练入口 ├── predict.py # 推理入口 └── requirements.txtsplit_dataset.py的核心逻辑是用固定随机种子切分数据集保证每次运行结果一致这样实验结果才能复现。我用的是random.shuffle加固定seed42同时记录了每张图所属的划分到csv文件里方便回溯。check_labels.py会扫描所有TXT标注文件检查是否存在未归一化的坐标、类别id越界、空标注文件等异常。train.py其实只是对ultralytics包的薄封装把命令行参数固化成了可读的配置文件方便团队其他人不用看文档也能直接跑。predict.py则包含单张图推理和批量推理两种模式同时输出带标注框的结果图。这段代码的价值不在于逻辑多复杂而在于把整个工作流固化新的实习生拿到项目就能快速上手。5. 实操过程与踩坑记录5.1 训练过程实录第一版模型训练到大概60个epoch时验证集的mAP0.5停在0.82左右上不去了。我看了一下训练日志发现loss曲线在40个epoch后就已经震荡收敛但精度始终差一口气。排查后发现是验证集的图像里有不少低光照样本训练增强里没有加灰度扰动和随机光照噪声导致模型对低光照泛化能力不足。于是我在数据增强策略里加了一条以0.2的概率对图像做随机gamma校正gamma范围设在0.8到1.3之间。重新训练后mAP0.5提升到了0.88。这个教训很典型工业现场的光照条件不可能和采集时完全一致增强策略要考虑真实部署环境。第二个坑是训练到大约120个epoch时模型在训练集上的Loss已经很低但验证集Loss不仅没继续降反而小幅回升——这是过拟合信号。我调整了模型结构从yolov8s换成了yolov8m同时增加了Dropout比例并提前停止了训练。最终模型在测试集上达到了mAP0.5为0.91mAP0.5:0.95为0.68的成绩单张推理时间在3080显卡上约8毫秒满足产线的实时性要求。5.2 常见问题排查与解决整个过程中我记录了不少实际操作中遇到的问题整理成了一张速查表方便大家在复现时快速排查问题现象可能原因解决办法训练Loss一直不降学习率过大或下界过低把lr0从0.01降到0.005检查lr schedule验证集mAP低但训练集高过拟合增加数据增强换更大模型提前停止小目标缺陷漏检严重输入分辨率不够把imgsz从640调到960或在标注时细分小目标类别标注框偏移导致训练震荡标注质量问题跑一遍check_labels.py用visualize.py人工复核某一类样本特别少类别不平衡对该类别做loss加权或采集更多样本最后再分享一个最容易被忽略的细节训练完成后一定要用独立的测试集做最终评估而不是只盯着验证集看。我当时测试集里特意放了一些在完全不同的光照条件下采集的样本结果发现weld_splash类别的误检率比验证集上高了不少。这说明模型对光照变化仍然敏感后来我在数据增强里进一步加入随机光照扰动并在推理管线里加了一步简单的直方图均衡化预处理这个问题才基本压住。这套数据集和代码前前后后迭代了三个版本从最初标注混乱到后来形成一套完整的工作流最大的体会是工业视觉项目的天花板几乎完全取决于数据质量和管理规范模型反而不是瓶颈。如果你也在做类似的电池缺陷检测项目建议从数据采集阶段就想清楚类别定义、标注规范和后续使用场景这套架子搭好了后面所有的训练和部署都会顺畅很多。本文还有配套的精品资源点击获取