简介本资源面向工业质检与目标检测方向的开发者、算法工程师及高校学生提供一套顶盖焊接缺陷检测的YOLO格式数据集可直接用于YOLOv5等目标检测模型的训练与验证省去繁琐的数据整理环节。压缩包共约2000个文件以1999个txt标注文件和1个Python可视化脚本为主整体约400MB按YOLOv5标准目录划分为训练集3646张图像与对应标签、验证集1562张图像与对应标签图像为2448×2048高分辨率RGB图标注框完整每张图含多个目标涵盖漏焊、断焊等5类缺陷并附类别class文本文件。资源还提供show.py可视化脚本随机传入一张图片即可绘制边界框并保存至当前目录无需修改即可运行便于快速核验标注质量。目前已有185人学习下载适合需要快速搭建焊接缺陷检测基线或开展工业视觉实验的读者参考使用。1. 顶盖焊接缺陷检测数据集为什么 5 类缺陷比 20 类更难标顶盖焊接是动力电池、储能模组产线上最要命的一道工序焊缝一旦出现气孔、虚焊、偏焊整颗电芯的密封性和导电性都会出问题。很多团队第一反应是「上 YOLO 训练自己的数据集」但真正卡住进度的往往不是模型而是数据集本身——顶盖焊接缺陷检测这个场景公开数据几乎为零只能自己标。而自己标的时候5 类缺陷的边界比想象中模糊得多气孔和凹坑在低分辨率下几乎一样虚焊和未焊透的灰度差只有几个像素。这份数据集的价值就在这儿它把顶盖焊接最常见的 5 类缺陷做了划分好的训练/验证/测试集配了类别 class 文件和数据可视化脚本省掉从零标注和划分的重复劳动。适合两类人一类是想快速验证 YOLO 在自己产线数据上能不能跑通的算法工程师另一类是手上有一批焊接图像、但不知道怎么组织成 YOLO 可训练格式的现场工程师。下面按「数据集长什么样 → 怎么接进 YOLO 训练 → 可视化脚本怎么用 → 坑在哪」的顺序讲清楚中间会穿插 YOLO 训练自己的数据集时最常翻车的几个点。2. 数据集结构与 class 文件先搞清目录再动手2.1 划分好的数据集目录长什么样一份能直接喂给 YOLO 的数据集目录结构决定了你后面写 data.yaml 时会不会返工。顶盖焊接缺陷检测这类工业数据集常见做法是按 images/labels 双轨存放再按 train/val/test 三份切分。我一般会先确认目录层级因为 YOLOv5、YOLOv8、YOLOv11 对路径的解析规则略有差异尤其是 labels 目录能不能被自动推导出来。典型结构如下weld_defect_dataset/ ├── images/ │ ├── train/ # 训练集图像jpg/png │ ├── val/ # 验证集图像 │ └── test/ # 测试集图像 ├── labels/ │ ├── train/ # 与 images/train 同名的 txt 标注 │ ├── val/ │ └── test/ ├── classes.txt # 类别名一行一个 └── visualize.py # 数据可视化脚本这里有个关键点YOLO 的标注文件是「同名 txt」images/train/001.jpg 对应 labels/train/001.txt。如果图像和标注不同名训练时不会报错但那一张图会被当成无目标背景损失函数里正样本直接消失模型学不到东西。我见过最隐蔽的一次翻车就是标注文件名多了个_label后缀训练 loss 一直降但 mAP 死活上不去。2.2 class 文件与 data.yaml 的对应关系classes.txt 里每一行是一个类别名行号从 0 开始就是类别 id。顶盖焊接 5 类缺陷常见的命名是porosity气孔、virtual_weld虚焊、undercut咬边、offset偏焊、crack裂纹。注意 classes.txt 本身不是 YOLO 训练直接读的文件YOLO 读的是 data.yaml你需要把类别名搬过去。# data.yaml path: /data/weld_defect_dataset # 数据集根目录 train: images/train # 相对 path 的路径 val: images/val test: images/test nc: 5 # 类别数必须和 classes.txt 行数一致 names: # 顺序必须和 classes.txt 完全一致 0: porosity 1: virtual_weld 2: undercut 3: offset 4: crack参数说明nc写错是最常见的低级错误写成 4 或 6 都会让训练在加载标签时抛 index 越界names的顺序如果和标注时用的 id 对不上模型会把气孔学成裂纹混淆矩阵会呈现一种「对称错位」的诡异形态。我一般会写个小脚本核对 classes.txt 行数和 data.yaml 的 nc 是否相等再抽查 3 张图的标注 id 是否落在 [0, nc-1] 区间内。2.3 标注格式YOLO txt 的 5 个字段YOLO 检测的标注是归一化后的class_id cx cy w h全部是 0~1 的相对值。顶盖焊接图像如果是固定工位拍摄分辨率稳定归一化不会有问题但如果是手持或变焦拍摄宽高比不一致归一化后框会变形。常见做法是先把所有图 resize 到统一尺寸再标或者标注时就用原图尺寸算归一化。# 校验标注是否越界或格式错误 import os def check_labels(label_dir, nc5): bad [] for f in os.listdir(label_dir): if not f.endswith(.txt): continue with open(os.path.join(label_dir, f)) as fp: for i, line in enumerate(fp): parts line.strip().split() if len(parts) ! 5: bad.append((f, i, 字段数不为5)) continue cid int(parts[0]) vals list(map(float, parts[1:])) if cid 0 or cid nc: bad.append((f, i, f类别id越界:{cid})) if any(v 0 or v 1 for v in vals): bad.append((f, i, 坐标未归一化或越界)) return bad print(check_labels(labels/train))这段脚本做三件事检查每行是否恰好 5 个字段、类别 id 是否在合法范围、坐标是否落在 0~1。返回空列表说明标注干净。参数nc要和 data.yaml 一致。跑完训练集再跑验证集别只查一份——我遇到过验证集里混进了一张旧版标注训练正常但验证 mAP 波动很大查了半天才发现是 val 的标注没同步更新。3. 用 YOLOv8 在本地跑通顶盖焊接缺陷训练3.1 环境配置与预训练模型选择YOLO 训练自己的数据集环境这块的玄学主要集中在 CUDA 和 PyTorch 版本匹配上。我一般用 conda 建独立环境避免和系统里的其他 torch 版本打架。YOLOv8 用 ultralytics 包安装比早期 YOLOv5 省事很多。conda create -n weld_yolo python3.10 -y conda activate weld_yolo pip install ultralytics8.2.0 pip install opencv-python matplotlib # 验证 GPU 是否可用 python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))如果输出True加显卡型号说明环境通了。预训练模型选择上顶盖焊接缺陷属于小目标密集场景我一般从yolov8s.pt起步——n 版太轻气孔这种小目标召回上不去m/l 版在数据量只有几千张时容易过拟合。如果产线要求实时推理s 版在 V100 上单帧大概几毫秒够用。预训练权重直接用官方发布的不要自己从头训工业缺陷数据量通常撑不起 from scratch。3.2 训练命令与关键参数怎么设一条命令能跑起来但参数设不对结果差很多。下面是我在顶盖焊接数据集上常用的训练命令yolo detect train \ datadata.yaml \ modelyolov8s.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience30 \ mosaic1.0 \ mixup0.1 \ degrees0.0 \ fliplr0.5 \ projectruns/weld \ nameexp_s参数逐个说imgsz640是 YOLOv8 默认顶盖焊接图像如果原图是 2000 像素以上缩到 640 后气孔可能只剩几个像素这时可以提到 960 或 1280但显存占用会翻倍V100 16G 上 1280 配 batch8 比较稳。mosaic1.0是 YOLO 的招牌增强把 4 张图拼一张对小目标友好但顶盖焊接的缺陷位置有工艺规律多在焊缝边缘mosaic 会打乱这种空间先验我一般先开 1.0 跑一轮如果 mAP 不理想再降到 0.5。degrees0.0是因为焊接图像方向固定旋转增强反而引入不存在的姿态。patience30是早停150 epoch 里如果 30 轮验证 mAP 不涨就停省时间。3.3 训练过程看什么loss、mAP 与混淆矩阵训练启动后终端会打印每轮的 box_loss、cls_loss、dfl_loss 和 mAP50、mAP50-95。顶盖焊接这类 5 类缺陷正常收敛曲线是前 10 轮 loss 快速下降mAP50 爬到 0.6 以上30 轮后增速放缓最终 mAP50 落在 0.85~0.95 区间算健康。如果 cls_loss 一直不降八成是类别不平衡——气孔样本可能占了 70%裂纹只有几十个。这时可以在 data.yaml 里加cls_pw或者对少数类做过采样。混淆矩阵是排查类别混淆的利器。YOLO 训练完会在 runs 目录下生成 confusion_matrix.png。顶盖焊接最容易混的是气孔和凹坑如果凹坑也标了类以及虚焊和未焊透。如果矩阵里 porosity 那一行大量落到 virtual_weld 列说明这两类的视觉特征在你的数据里区分度不够要么合并类别要么在标注规范里把边界写死。我一般会导出验证集的预测结果挑出置信度在 0.3~0.5 之间的样本人工复核这批「模棱两可」的样本往往就是类别定义模糊的重灾区。4. 数据可视化脚本标注对不对一眼看出来4.1 可视化脚本要解决什么问题标注完几千张图靠人一张张翻是不现实的。数据可视化脚本的核心作用是把 YOLO txt 里的归一化框还原到图像上让你一眼看出框有没有偏、类别有没有标错、有没有漏标。顶盖焊接缺陷检测里漏标比错标更致命——漏掉的气孔会被模型当成背景训练时反而强化「这里没有缺陷」的错误认知。4.2 用 OpenCV 画框并批量导出下面这段脚本读 images 和 labels把框画到图上并存到 preview 目录。支持按类别上色方便区分 5 类缺陷。import cv2 import os import numpy as np # 5 类缺陷的 BGR 颜色 COLORS { 0: (0, 0, 255), # porosity 红 1: (0, 255, 0), # virtual_weld 绿 2: (255, 0, 0), # undercut 蓝 3: (0, 255, 255), # offset 黄 4: (255, 0, 255), # crack 品红 } NAMES [porosity, virtual_weld, undercut, offset, crack] def draw_one(img_path, label_path, out_path): img cv2.imread(img_path) if img is None: return h, w img.shape[:2] if os.path.exists(label_path): with open(label_path) as f: for line in f: cid, cx, cy, bw, bh line.strip().split() cid int(cid) cx, cy, bw, bh map(float, (cx, cy, bw, bh)) # 归一化坐标还原为像素 x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) color COLORS.get(cid, (255, 255, 255)) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, NAMES[cid], (x1, max(y1 - 5, 12)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) cv2.imwrite(out_path, img) def batch_visualize(img_dir, label_dir, out_dir): os.makedirs(out_dir, exist_okTrue) for f in os.listdir(img_dir): if not f.lower().endswith((.jpg, .png, .jpeg)): continue stem os.path.splitext(f)[0] draw_one( os.path.join(img_dir, f), os.path.join(label_dir, stem .txt), os.path.join(out_dir, f) ) batch_visualize(images/train, labels/train, preview/train)逻辑说明draw_one负责单张图的坐标还原和绘制batch_visualize负责遍历目录。参数上COLORS字典的 key 必须和 class id 对齐NAMES列表顺序也要一致否则画出来的标签名会张冠李戴。坐标还原公式(cx - bw/2) * w是 YOLO 归一化中心点转左上角的标准写法注意bw是宽不是 x2写反了框会跑到图外。4.3 从可视化结果里能看出哪些标注问题跑完脚本重点看三类现象一是框明显偏离缺陷区域说明标注时鼠标点歪了或者坐标算错二是同一张图里同类缺陷框大小差异极大可能是标注员对边界理解不一致三是图像上有明显缺陷但没有任何框这就是漏标。顶盖焊接里气孔往往成簇出现如果可视化后发现只标了其中最大的一个小气孔全漏了那模型学到的就是「只有大气孔才算缺陷」召回率会很难看。我一般会随机抽 50 张可视化图按这三类问题统计比例超过 5% 就退回重标。5. 避坑与排查顶盖焊接数据集训练最容易翻车的 5 个点5.1 现象训练 loss 正常下降但 mAP 始终接近 0原因标注文件的类别 id 和 data.yaml 的 names 顺序错位或者 labels 目录路径没被正确解析YOLO 把标注当成了空文件。顶盖焊接数据集如果是从其他格式如 VOC、COCO转过来的转换脚本里类别映射表写错一位就会全盘错位。解决先跑一遍第 2.3 节的标注校验脚本确认类别 id 范围再用yolo detect train启动时观察日志里train: Scanning ... images, ... backgrounds这行backgrounds 数量应该为 0如果等于图像总数说明标注根本没被读到检查 labels 路径和文件名是否与 images 严格同名。5.2 现象验证集 mAP 比训练集低 20 个点以上原因训练集和验证集的缺陷分布不一致。顶盖焊接数据如果按时间顺序切分早期批次和后期批次的工艺参数可能变了缺陷形态漂移。另一种可能是验证集里混入了训练集图像数据泄漏但这种情况 mAP 会异常高而不是低。解决统计 train 和 val 的类别分布用直方图对比。如果某一类在 val 里占比远高于 train要么重新分层抽样要么在 loss 里给该类加权。我一般用sklearn.model_selection.train_test_split的stratify参数按类别分层切分保证两边分布一致。5.3 现象训练到一半 loss 突然变成 NaN原因学习率过大或 batch 里出现了异常样本如标注框宽高为 0。YOLO 的损失函数里有除宽高的项w0或h0会导致除零。顶盖焊接标注时如果鼠标双击没拖动就松开会生成一个宽高为 0 的框。解决在标注校验脚本里加一条if bw 0 or bh 0: bad.append(...)把所有零面积框清掉。同时把lr0从 0.01 降到 0.001 再试YOLOv8 对学习率比 v5 敏感一些。5.4 现象混淆矩阵里两个类别大量互混原因类别定义本身有重叠。顶盖焊接的虚焊和未焊透在灰度图上都是「焊缝发暗」如果标注规范里没写清判定标准标注员会凭感觉标模型自然学混。解决回到标注规范用金标准样本比如用显微镜或电测确认过的缺陷重新定义边界。如果两类确实无法从图像区分考虑合并成一个「焊接不良」大类或者引入多模态数据如红外热图辅助。别硬训硬训的结果是两类都学不好。5.5 现象推理时小目标气孔大量漏检原因输入分辨率不够。顶盖焊接图像原图可能是 4000×3000缩到 640 后气孔只剩 2~3 个像素YOLO 的 P3 特征图 stride8这个尺度下目标几乎消失。解决把imgsz提到 1280 或 1536同时用切片推理SAHI把大图切成小块分别检测再合并。代价是推理速度下降V100 上 1280 大概比 640 慢 3 倍。如果产线节拍允许这是提升小目标召回最直接的办法。另一个方向是改模型结构在 P2 层加检测头但这就属于 YOLO 改进的范畴了需要改 ultralytics 源码。6. 进阶技巧用切片推理把大气孔和小气孔一起捞回来顶盖焊接缺陷检测的终极矛盾是气孔尺寸跨度大大的几十像素小的只有两三像素单一分辨率下很难兼顾。我现在的习惯是训练用 1280推理用 SAHI 切片把 4000 像素的原图切成 640×640 的块每块重叠 20%分别送进模型最后用 NMS 合并。这样小气孔在切片里被放大到可检测尺度大气孔也不会因为整图缩放而丢失。from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/weld/exp_s/weights/best.pt, confidence_threshold0.25, devicecuda:0 ) result get_sliced_prediction( test_images/001.jpg, model, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2 ) result.export_visuals(export_dirsahi_preview/)参数上overlap设 0.2 是经验值太小会切断裂缝导致框不完整太大则重复计算拖慢速度。confidence_threshold比训练时验证用的阈值低一点因为切片后单块内的目标更清晰可以适当放宽召回。跑完对比一下 SAHI 和整图推理的召回率我这边小气孔召回能从 0.6 提到 0.85 左右代价是单图推理从 8ms 涨到 60ms。产线如果节拍是 200ms 一张完全吃得下。验证切片推理效果别只看 mAP要单独统计小目标面积小于 32×32 像素的召回。我一般会把测试集按缺陷面积分三档小32²、中32²~96²、大96²分别算 AP。如果小目标 AP 提升明显而大目标没掉说明切片策略有效如果大目标 AP 掉了多半是切片边界把大缺陷切断了把 overlap 提到 0.3 再试。这套流程跑下来从数据集拿到手到产线可用的模型大概两三天。真正花时间的不是训练是标注校验和类别边界定义。我踩过最深的坑是早期图省事让标注员凭感觉标虚焊结果模型在验证集上表现很好一上产线就疯狂误报——因为产线的光照和标注时的样件光照不一样虚焊的灰度特征整个漂移了。后来老老实实把产线实际光照下的样本补进训练集又花了一周重标。所以如果你手上也有顶盖焊接的图像先别急着训模型把标注规范和光照一致性这两件事做扎实比调任何超参都管用。希望帮到你。本文还有配套的精品资源点击获取