简介:该数据集面向焊接件表面缺陷检测任务,专供训练目标检测模型使用,适合算法工程师、科研人员及智能制造质检项目开发者,省去自行采集与标注的重复工作。数据同时提供Pascal VOC与YOLO两种主流标注格式,覆盖10类常见缺陷,例如皱褶(crease)、月牙间隙(crescent_gap)、夹杂(inclusion)、油斑(oil_spot)、压坑(rolled_pit)、焊缝线(welding_line)等,类别定义清晰,可直接接入YOLO、Faster R-CNN、SSD等主流深度学习框架训练。资源包共2000个文件,以XML标注文件为主体,并配有使用说明TXT,包体总大小约256.38MB,结构简洁,解压后即可按目录划分训练集与验证集。对应2292张现场图片的标注内容,读者可获得一份格式规整、类别均衡的训练样本,既能用于缺陷检测模型迭代,也可作为研究VOC与YOLO标注转换、数据增强及小样本学习的实验素材。当前已有913人学习/浏览,适合作为焊接质检场景的基准数据集使用,帮助快速验证模型效果并缩短项目落地周期。
1. 拿“焊接件表面缺陷检测数据集”训YOLO:2292张图够不够用
焊接件表面缺陷检测数据集这类以 VOC+YOLO 双格式打包的资源,在工业质检项目里几乎是人手一份的起步配置。图片在前、标签在后,XML 和 txt 两套标注同时给齐,省掉了最费人的标注环节;2292 张、10 个类别,听着不大,但配合迁移学习和增强手段,足够把一条 YOLOv8 训练流程完整跑通,也能让现场采集数据的时间没那么紧张。适合两类人:一是准备做焊接质检、想先看看 10 类缺陷真实形态的工程师;二是刚接触 YOLO 训练、需要一份能快速验证“数据→训练→评估”闭环的样本。后面这些内容,就围绕这份数据怎么落地展开。
2. 从 7z 到双格式目录:先把数据包拆开、看清结构再动手
拿到.7z压缩包,第一件事不是急着解压训练,而是先测试压缩包完整性、解压、然后把目录结构摸清楚。7z 格式在数据集分发场景里很常见,因为对标注这类文本文件的压缩率比 zip 高不少,一个带着几百张 JPEG 和上千个 XML/txt 的包,压完能小三分之一左右。Linux 下常见做法是用p7zip工具组,Windows 下用 7-Zip 或者能识别 7z 的压缩软件。无论用哪个,建议先t测试一遍再解压,省得解到一半才发现包是坏的。
7z t 焊接件表面缺陷检测数据集VOC+YOLO格式2292张10类别.7z 7z x 焊接件表面缺陷检测数据集VOC+YOLO格式2292张10类别.7z -o./welding_defect -y这里t是 test 模式,只校验 CRC 不做解压,输出里出现Everything is Ok再继续;x是解压命令,-o./welding_defect指定输出目录,注意-o后面不能有空格;-y表示所有覆盖询问默认同意,适合脚本里批量操作。如果是在 Windows 上双击解压,建议在 7-Zip 的“文件→校验”里跑一次 CRC 校验,原理一样,都是为了排除“下载截断”这种最冤的原因。
解压完,先用tree -L 2看一眼顶层结构。带 VOC 和 YOLO 双格式的数据集,常见做法是下面两种布局之一:要么是JPEGImages + Annotations + ImageSets/Main的经典 VOC 结构,YOLO 的labels作为平级目录单独存在;要么作者已经把图片按train/val分好,图片在images/,标签在labels/。这两种都见过,不提前看清就写训练脚本,后面路径十有八九要返工。
2.1 VOC 与 YOLO 目录结构对照
| 目录/文件 | 内容 | 在训练里的用途 |
|---|---|---|
JPEGImages/ | 2292 张原始图片,jpg 或 png | 模型实际读取的输入 |
Annotations/ | 每张图对应的 XML,VOC 格式 | 转 YOLO 格式的原始依据 |
ImageSets/Main/ | 划分好的 train.txt / val.txt | 如果不做自定义划分,可直接引用 |
labels/或yolo_labels/ | 每张图对应的 txt,归一化坐标 | YOLO 训练直接依赖的标注 |
classes.txt或labels.txt | 类别名清单 | 写 data.yaml 时对齐类别顺序用 |
注意JPEGImages的文件名和Annotations、labels里的文件名必须严格一一对应。文件名对不上是这类数据集最常见的“暗伤”,后面校验脚本会专门处理。
2.2 VOC 的 XML 和 YOLO 的 txt:同一张图的两套表达
VOC 格式的 XML 长这样,一个<object>代表一个目标框,bndbox里存的是像素坐标:
<annotation> <folder>JPEGImages</folder> <filename>weld_00123.jpg</filename> <size> <width>1280</width> <height>960</height> <depth>3</depth> </size> <object> <name>porosity</name> <bndbox> <xmin>320</xmin> <ymin>240</ymin> <xmax>410</xmax> <ymax>330</ymax> </bndbox> </object> </annotation>而 YOLO 的 txt 格式是归一化的中心点坐标,每行五个数:类别编号 中心点x 中心点y 宽 高。无论是 0~1 的小数,四列坐标都相对图片宽高做了归一化,类别编号从 0 开始,顺序必须和训练用的data.yaml里names列表严格一致。两类格式转换时最容易出错的就是类别编号对不上,后面避坑章会专门展开一条。
双格式并存的价值在于:VOC 适合用 labelImg 二次查看和修正,YOLO 格式则能直接被 YOLOv5/v8 的训练管线读取。想验证转出来的 YOLO 标注画在图上是否正确,可以用 OpenCV 把框画回原图,肉眼看几张就能发现坐标归一化有没有做错。
2.3 双格式一致性校验:图片、XML、txt 三方点名
解压之后第一道工序,是用脚本核对三件事:有没有只带图不带标注的;有没有标注文件对应不上图的;YOLO 的 txt 里类别编号有没有超出类别总数。常见的做法是写一个二十行的 Python 脚本跑一遍,秒级出结果。
from pathlib import Path base = Path("./welding_defect") img_dir = base / "JPEGImages" voc_dir = base / "Annotations" yolo_dir = base / "labels" missing_voc = [] missing_yolo = [] bad_class_id = set() for img_path in sorted(img_dir.glob("*.jpg")): stem = img_path.stem if not (voc_dir / f"{stem}.xml").exists(): missing_voc.append(stem) txt_path = yolo_dir / f"{stem}.txt" if not txt_path.exists(): missing_yolo.append(stem) else: for line in txt_path.read_text().strip().splitlines(): class_id = int(line.split()[0]) if class_id >= 10: bad_class_id.add((stem, class_id)) print("缺 VOC XML:", len(missing_voc)) print("缺 YOLO txt:", len(missing_yolo)) print("超范围类别编号:", bad_class_id)这段脚本把图片主文件名当作关联键,检查同名的 XML 和 txt 是否存在,并且顺带扫描 txt 里每行的第一个字段,看类别编号是否超出 0~9 的范围。跑完输出三个数字,任何一个不为 0,都说明数据集内部有脏数据,需要先决定是补标注还是剔除样本,而不是把脏数据直接喂给训练管线。对于工业缺陷检测来说,一个类别错位的样本带来的负面影响远大于缺一张图。
3. 把数据整理成 YOLOv8 可直接训练的样子:划分、yaml 与类别统计
确认数据完整后,下一步是把目录整理成 ultralytics 默认接受的 YOLO 风格布局:images/train、images/val、labels/train、labels/val。很多双格式数据集自带ImageSets/Main的划分文件,可以直接沿用;但更稳的做法是自己重新划分一遍,原因是数据集的原始划分未必考虑同一工件多图泄漏的问题——比如同一个焊接件的多张照片可能同时出现在训练集和验证集里,导致验证分数虚高。
3.1 数据划分脚本:固定随机种子,按 8:1:1 切分
这里按 8:1:1 划分训练、验证、测试三份,测试集先留出来,训练完做最终评估用。关键的细节是随机种子要固定,否则每次运行划分结果不同,实验无法复现。
import random from pathlib import Path import shutil random.seed(42) image_dir = Path("./welding_defect/JPEGImages") label_dir = Path("./welding_defect/labels") all_images = sorted(image_dir.glob("*.jpg")) random.shuffle(all_images) n = len(all_images) train_cut = int(n * 0.8) val_cut = int(n * 0.9) splits = { "train": all_images[:train_cut], "val": all_images[train_cut:val_cut], "test": all_images[val_cut:], } for split, images in splits.items(): (Path("./dataset/images") / split).mkdir(parents=True, exist_ok=True) (Path("./dataset/labels") / split).mkdir(parents=True, exist_ok=True) for img in images: stem = img.stem shutil.copy(img, Path("./dataset/images") / split / img.name) src_label = label_dir / f"{stem}.txt" if src_label.exists(): shutil.copy(src_label, Path("./dataset/labels") / split / f"{stem}.txt")这段脚本先把图片路径列表随机打乱,按数量切成三段,再把图片和对应的标签文件复制到 YOLO 风格的目录里。shutil.copy而不是move,这样原始数据保持不动,后面想重新划分还有后悔药。注意所有划分都在内存里基于文件列表完成,不依赖 XML 内容,速度快且逻辑简单。
3.2 写 data.yaml:相对路径是跨机器跑通的关键
YOLOv8 训练时的数据配置是一份 YAML 文件,里面最关键的就是路径、类别数和类别名列表。
path: ./dataset train: images/train val: images/val test: images/test nc: 10 names: 0: porosity 1: crack 2: slag_inclusion 3: lack_of_fusion 4: lack_of_penetration 5: undercut 6: weld_spatter 7: blowhole 8: over_weld 9: burn_throughpath字段建议写相对路径,而不是绝对路径。原因很现实:这个项目可能在本地调通后要拷到训练服务器上跑批量实验,绝对路径换台机器就崩,相对路径只要目录层级保持一致就能直接跑。names的顺序必须和 txt 标注里的类别编号一一对应,第一行的0对应porosity,如果数据集的classes.txt顺序和这里不一样,必须调整——不要依赖自己“肉眼记住”的顺序,每次训练前先看一遍标签文件。
3.3 类别分布统计:先看清楚数据长什么样再谈训练
训练前花两分钟统计一下各类别的目标框数量,能避免训练到一半才发现某类只有二十几个框。工业缺陷数据天然存在长尾分布,气孔可能占了一半样本,裂纹只有几十个,不统计就不知道这个不均衡有多严重。
from collections import Counter from pathlib import Path label_root = Path("./dataset/labels/train") class_counter = Counter() box_area_sum = 0.0 box_count = 0 for txt_path in label_root.glob("*.txt"): for line in txt_path.read_text().strip().splitlines(): parts = line.split() class_id = int(parts[0]) w, h = float(parts[3]), float(parts[4]) class_counter[class_id] += 1 box_area_sum += w * h box_count += 1 print("各类别框数量:", dict(sorted(class_counter.items()))) print("平均框面积占比:", box_area_sum / box_count)这段脚本遍历训练集所有 txt,统计每个类别的目标框数量和平均框面积占比。平均框面积占比这个数字很关键:如果小于 0.02,说明大部分缺陷目标在 640×640 输入下只有几十个像素,跑默认配置大概率漏检,需要考虑大尺寸训练或切片推理。类别分布不用做成图表,打印出来就已经足够指导下一步——数据增强策略和训练轮数都要根据它来定。
4. 用这份数据训练 YOLOv8:环境、命令与评估指标怎么盯
数据准备完毕,进入训练环节。当前 YOLO 系列迭代到 v8/v11,ultralytics 封装了训练、验证、导出的完整流程,命令行基本上一句话能跑通。这里以 YOLOv8 为例,因为生态最成熟、部署资料多,遇到问题搜起来最方便。
4.1 环境搭建:conda 隔离,避免污染其他项目
建议用 conda 新建独立环境,Python 版本选 3.9 或 3.10,避免和系统 Python 打架。GPU 不是硬性要求,纯 CPU 也能训,只是 2292 张图跑 200 轮可能需要几小时到一天——这在工业项目里完全可接受,因为本来就不是高频迭代的场景。
conda create -n yolo python=3.9 -y conda activate yolo pip install ultralyticsultralytics 装完会自动带上 PyTorch 的 CPU 版本。如果有 NVIDIA 显卡,建议安装 CUDA 版 PyTorch,训练提速明显,命令里pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121一行就能替换,其他依赖不变。装好后可以跑yolo predict model=yolov8n.pt source=test.jpg验证环境没问题。
4.2 训练命令:预训练权重比从零开始更靠谱
训练命令的核心是数据配置、模型选择、超参数三块。这里选用yolov8n.pt作为起点,而不是更大的 s/m 系列,原因后面细说。
yolo detect train \ data=./dataset/data.yaml \ model=yolov8n.pt \ epoch=200 \ imgsz=640 \ batch=16 \ patience=30 \ workers=4 \ seed=42参数说明:model=yolov8n.pt表示加载 COCO 预训练权重然后微调,这是小数据集上最稳妥的做法;epochs=200配合patience=30早停,如果验证集指标连续 30 轮不提升就自动终止,不用死等;imgsz=640是 YOLOv8 默认输入尺寸,先跑通再考虑放大;batch=16在显存不够时降到 8;seed=42固定随机种子,保证每次实验可比。关于为什么不选yolov8x:2292 张图的规模,大模型的参数量远超数据量能支撑的学习能力,很容易训到过拟合,n 或 s 级别的模型在这个数据量上更容易收敛。
4.3 训练过程看什么:loss 曲线、PR 曲线和混淆矩阵
训练启动后,终端会实时打印每个 epoch 的 box_loss、cls_loss、dfl_loss 以及验证集的 mAP50 和 mAP50-95。这三个 loss 里,box_loss关注边界框回归精度,cls_loss关注分类正确性,dfl_loss是 YOLOv8 新引入的分布焦点损失,直接影响框的边界锐度。正常趋势是三者一起下降并趋于平缓;如果cls_loss降得很慢而box_loss正常,大概率是某些类别的样本太少,模型学不到判别特征。
训练结束后,runs/detect/train/目录下会生成results.png、confusion_matrix.png、PR_curve.png等文件。重点看两个:一是PR_curve.png,如果曲线右上角有显著的“塌肩”,说明存在难例类别拉低了整体精度;二是confusion_matrix.png,对角线亮、其余位置暗是理想状态,某一列特别亮说明该类别被系统性误判成了另一类。比如裂纹常被误判为夹渣,这在视觉上本来就难分,需要回到数据层面补样本或者合并类别。
4.4 评估指标:mAP50 和 mAP50-95 的差别
验证集评估默认输出两个核心指标,理解它们的差异比记住数字更重要。mAP50是 IoU 阈值固定在 0.5 时的平均精度,衡量“框个大概位置能不能命中”;mAP50-95是 IoU 从 0.5 到 0.95 每隔 0.05 计算一次再取平均,对框位置的精确度要求高得多。工业焊接质检场景中,缺陷框稍微偏一点往往不影响判断,所以mAP50比mAP50-95更有参考意义。建议训练时以mAP50为主要优化目标,不要盲目追求高分。如果mAP50明显高于mAP50-95,说明框定位精度有待提升,可以考虑增大输入尺寸或使用更深的模型。评估命令用一行就能跑完,测试前记得把model路径换成训练产物,指向权重文件,再指定split=test用之前留出的测试集:
yolo detect val model=runs/detect/train/weights/best.pt data=./dataset/data.yaml split=test5. 焊接件缺陷数据训练的高频坑:现象、原因与解决办法
数据量不大、类别分布不均、缺陷目标尺寸小,这几个特征决定了训练过程不会一帆风顺。下面五条都是这类项目里真正值得记忆的踩坑记录。
5.1 7z 解压报错“密码正确但文件损坏”:先查编码,再查完整性
现象:压缩包是从网盘或群文件下载的,解压时反复输入正确密码,软件提示密码错误或文件头损坏,怎么试都不行。
原因:最常见的是文件名编码问题。7z 在 Windows 下默认使用 ANSI 编码存储文件名,而很多压缩包制作时用的是 UTF-8,解压端编码不匹配就会报错。另一个原因是下载过程中文件被截断,CRC 校验不通过。
解决:先用7z t测试包完整性,排除损坏可能。如果测试通过,把压缩包拷贝到 Linux 环境下用 p7zip 解压,或者用支持编码切换的软件调整文件名字符集后重试。实际操作中,Linux 下解压这类包成功率最高,这算是跨平台处理 7z 文件的实用经验。
5.2 VOC 转 YOLO 时类别编号错位:不要数 index,要按名字映射
现象:用网上脚本把 XML 转成 YOLO txt 后,训练时某些类别的 AP 始终为 0,画出来一看,气孔的框全标成了裂纹。
原因:转换脚本里用names.index(name)这种方式直接取类别索引,而 XML 里类别名顺序和data.yaml的names列表顺序不一致。
解决:先看数据集自带的classes.txt,写出显式的字符串到编号映射字典,转换时用名字查表,而不是靠 index 计算。转换完一定要抽样画框回图验证,不要只看数字。这一步多花十分钟,能省下后面几天排查结果异常的时间。
5.3 loss 一路下降但 mAP 上不去:数据量小导致的过拟合
现象:训练到 100 轮时 loss 还在降,验证集 mAP50 却停滞在 0.3 左右,甚至开始波动。
原因:模型在训练集上“背”下了大量背景纹理,没有真正学到缺陷的泛化特征。小数据集上这种现象非常典型,尤其是焊接件表面反光、飞溅、氧化皮等背景噪声大时。
解决:换小模型强制正则化;开启更强的数据增强;把训练集复制几份做重复采样;如果条件允许,用冻结 backbone 的方式先训头部再解冻微调。最直接有效的两个手段是:把模型从 m 降级到 n,以及在data.yaml里增加背景样本或难负样本。
5.4 气孔、裂纹小目标漏检严重:默认 640 输入对它们太不友好
现象:大尺寸缺陷如未焊透检测效果尚可,气孔和细小裂纹几乎全漏,即便调低置信度阈值也只是换来一堆误检。
原因:焊接气孔直径往往只有几毫米到十几毫米,在 640×640 的输入下可能只占几十个像素;YOLO 系列对小目标的召回能力本来就不如大目标。
解决:把imgsz提到 1280,训练和推理保持同一尺寸;开启 mosaic 增强让模型多见到小尺寸目标;推理阶段用切片推理让目标在输入中占据更大比例。工业现场如果能控制相机距离,优先保证缺陷在画面里所占像素数足够大,比任何算法技巧都有效。
5.5 验证集 mAP 高,现场误检多:数据域差异
现象:测试集 mAP50 达到 0.85,部署到产线后,对着真实工件误检框一堆,正常焊缝被频繁框成缺陷。
原因:数据集里的图片是实验室或特定机位拍的,现场有车间光照、工件姿态、表面油污等干扰因素,模型没见过这些。
解决:下现场采一个小时真实图片,挑出能代表现场情况的几十张加入训练集;如果新样本来不及标注,用现有模型打伪标签,人工复核修正后再回灌数据。任何公共数据集都只是起点,现场数据回灌这一步没办法省。
6. 把 2292 张图的利用率拉满:迁移学习、增强与种子集策略
6.1 优先微调 COCO 预训练权重,别从头训
焊接缺陷和 COCO 的日常物体在视觉特征上差距很大,但不代表预训练权重没有价值。COCO 预训练模型已经学会了边缘、纹理、局部形状这类底层特征,这些对于气孔和裂纹同样适用。用yolov8n.pt而不是随机权重初始化,收敛速度快一倍以上,最终精度通常也更高。如果验证集 mAP 上不去,可以尝试冻结 backbone 只训练 head 部分——在 ultralytics 里设置freeze=10即可,然后解冻全模型微调,这在小数据集上有明显正则化效果。
6.2 增强参数按缺陷类型调:气孔补亮度扰动,裂纹补几何变换
YOLOv8 的augment配置默认开启 Mosaic、HSV 扰动、随机翻转等。焊接件表面反光强烈,增加亮度对比度扰动能让模型更适应现场光照变化;裂纹这类细长目标,degrees旋转增强要保守设置,因为实际缺陷的方向具有物理意义,过度旋转可能偏离真实分布。数据增强的本质是模拟真实变化,不是把样本变成抽象画。
6.3 用伪标签把现场数据变成增量:这是这类数据集真正的价值
2292 张双格式标注数据最大的价值是作为种子集。用它训练出的模型,对现场采集的新图片做预测,然后人工快速审核修正伪标签,比从零标数据效率提高数倍。审核后的样本进入训练集,迭代几轮后,模型的现场表现会有明显提升。这么做的前提是伪标签质量可控,建议只保留置信度高于 0.8 且框面积适中的人工修正结果。
回头看这些项目,最大的教训是拿到数据集后先别急着跑训练,把结构验证、类别统计、格式检查这几步做扎实,才是真正节省时间的做法。这批数据对焊接质检方向的验证工作足够用,希望这些经验能帮你少走一段弯路。
本文还有配套的精品资源,点击获取