尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

基于YOLO的焊缝质量检测:131张小样本数据集的训练与避坑指南

发布时间:2026/9/28 1:32:17

资讯中心
01
ARTICLE

基于YOLO的焊缝质量检测:131张小样本数据集的训练与避坑指南

基于YOLO的焊缝质量检测:131张小样本数据集的训练与避坑指南
简介本资源为面向焊接质量检测场景的YOLO系列目标检测数据集适合从事工业视觉缺陷识别、智能制造质检方向的算法工程师与高校研究者使用可解决焊缝图像中「焊接不良」与「焊接良好」两类目标的检测训练与验证需求。压缩包共394个文件包含131张jpg图像、131个txt标签、131个xml标签及1个yaml配置文件整体约7.12MB已按训练与验证需求划分完毕并同时提供YOLO格式与VOC格式两套标注便于直接接入yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流框架。YOLO标签采用归一化中心点与宽高比例可直接用于模型训练与测试。目前已有230人学习下载读者可快速获得一份开箱即用的焊缝缺陷检测数据基础用于模型对比实验、标注格式转换练习与检测流程验证节省自行采集与标注的时间成本。1. 131张焊缝图能训出什么从标题拆开一个可复现的检测任务拿到“yolo算法-焊缝质量检测数据集-131张图像带标签-焊接不良-焊接良好.zip”这个标题第一反应不是兴奋而是先算一笔账131张图二分类焊接良好 / 焊接不良用 YOLO 做检测。这个量级放在 COCO、VOC 那种万级数据集面前连零头都算不上但它恰恰是工业质检现场最常见的起点——产线边上的工业相机一天能拍几千张可真正被标注、被清洗、被拿来做基线验证的往往就是这一两百张“种子图”。这个数据集的价值不在于刷高 mAP而在于让你用最低成本跑通“焊缝缺陷检测”这条链路从标注格式转换、预训练权重加载、小样本增强策略到推理时怎么把漏检率压下来。适合谁适合手上有一批焊缝图但不知道怎么喂给 YOLO 的产线算法工程师也适合想拿一个真实工业二分类场景练手的学生或转行者。131 张不是限制是约束条件约束条件下能跑通后面扩到 1310 张就是复制粘贴的事。2. 焊缝检测任务拆解YOLO 在这里到底学什么2.1 焊接良好与焊接不良在图像上长什么样焊缝质量检测在视觉上不是一个“有没有焊缝”的问题而是“焊缝的纹理、宽度、连续性、边缘过渡是否一致”的问题。焊接良好的区域通常表现为熔宽均匀、鱼鳞纹连续、边缘与母材过渡平滑、灰度梯度变化有规律。焊接不良则可能表现为气孔局部暗斑或亮斑、咬边焊缝边缘出现凹槽状暗线、未焊透焊缝中心出现连续或断续的暗带、焊瘤局部凸起的亮块。这些缺陷在 640×640 的输入尺度下有些只占十几个像素这也是为什么小样本焊缝检测不能无脑套用 COCO 上的那套 anchor 配置。YOLO 做的是“框出缺陷位置 分类”。如果数据集里只有图像级标签整图标注为“焊接不良”那严格来说这是分类任务不是检测任务。但标题写的是“带标签”结合 YOLO 的常见用法我一般会先确认标签是 VOC XML、YOLO TXT 还是 COCO JSON。如果是图像级标签就需要先做一步弱监督到强监督的转换或者退一步用 YOLO 的分类模式YOLOv8-cls先跑基线。这一步判断错了后面所有训练都是白费。2.2 为什么 131 张图仍然值得用 YOLO 而不是分类网络有人会问131 张图做二分类直接上 ResNet 或 EfficientNet 不香吗香但工业现场要的不只是“这张图有没有缺陷”而是“缺陷在哪、有多大、有几处”。分类网络给你一个概率检测网络给你坐标。产线复检工位需要的是后者——知道位置才能引导机械臂打磨或标记。YOLO 在 131 张图上的优势不是精度而是它允许你用预训练权重 冻结骨干 小学习率微调的方式在极少量数据上快速得到一个“能框出大致区域”的模型。这个模型可能 mAP50 只有 0.6 出头但它能跑通数据流能暴露标注问题能让你在扩数据之前就知道这套方案值不值得继续投入。2.3 从压缩包到可训练目录目录结构先定死拿到 zip 之后不要急着解压到桌面就开始写训练脚本。我习惯先把目录结构定死后面所有脚本都围绕这个结构写换数据集时只改路径不改逻辑。常见做法是# 假设解压后原始目录为 raw_weld/ # raw_weld/ # images/ # 131 张 jpg 或 png # labels/ # 对应的标注文件可能是 xml / txt / json # classes.txt # 类别名如果有的话 # 目标结构 mkdir -p datasets/weld/images/train mkdir -p datasets/weld/images/val mkdir -p datasets/weld/labels/train mkdir -p datasets/weld/labels/val # 按 8:2 划分131 张约 105 训练 / 26 验证 # 注意小样本下不要用随机划分要按拍摄批次或焊缝编号划分避免同一焊缝的相邻帧同时进训练和验证这里的关键参数是划分比例和划分依据。131 张图如果随机打乱同一道焊缝的连续拍摄帧可能同时出现在训练集和验证集验证指标会虚高。我一般会先看文件名里有没有批次号或焊缝编号有就按编号分没有就按拍摄时间排序后每隔 5 张抽 1 张进验证集。这个细节在 131 张量级下对最终指标的影响可能超过 10 个百分点。3. 把标注喂给 YOLO格式转换与配置文件落地3.1 VOC XML 转 YOLO TXT 的脚本与四个边界坑焊缝数据集最常见的标注格式是 LabelImg 导出的 VOC XML。YOLO 需要的是归一化后的class_id x_center y_center width height。转换脚本网上一搜一大把但真正跑起来不报错的没几个。下面这个是我改过很多次的版本重点处理了四个边界情况import xml.etree.ElementTree as ET import os from pathlib import Path # 类别映射根据你的 classes.txt 修改 CLASS_MAP {weld_good: 0, weld_bad: 1} def convert_bbox(size, box): 将 VOC 的 xmin,ymin,xmax,ymax 转为 YOLO 的归一化中心点宽高 dw 1.0 / size[0] dh 1.0 / size[1] x (box[0] box[1]) / 2.0 y (box[2] box[3]) / 2.0 w box[1] - box[0] h box[3] - box[2] # 边界裁剪防止标注框超出图像范围导致归一化后为负或大于1 x max(0, min(x, size[0])) y max(0, min(y, size[1])) w max(1, min(w, size[0])) h max(1, min(h, size[1])) return (x * dw, y * dh, w * dw, h * dh) def convert_xml(xml_path, out_txt_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): cls_name obj.find(name).text.strip() if cls_name not in CLASS_MAP: continue # 跳过未定义类别避免训练时 index 越界 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) bb convert_bbox((w, h), (xmin, xmax, ymin, ymax)) lines.append(f{CLASS_MAP[cls_name]} { .join([f{v:.6f} for v in bb])}) if not lines: return False # 空标注文件不生成避免 YOLO 报 warning with open(out_txt_path, w) as f: f.write(\n.join(lines)) return True # 批量转换 raw_img_dir Path(raw_weld/images) raw_xml_dir Path(raw_weld/labels) out_label_dir Path(datasets/weld/labels/train) # 根据划分调整 for xml_file in raw_xml_dir.glob(*.xml): img_name xml_file.stem .jpg if not (raw_img_dir / img_name).exists(): continue # 图像缺失的标注直接跳过 out_path out_label_dir / (xml_file.stem .txt) convert_xml(str(xml_file), str(out_path))逻辑说明convert_bbox里做了边界裁剪因为 LabelImg 标注时可能手抖把框拉到图像外面不裁剪的话归一化后会出现负数或大于 1 的值YOLO 训练时虽然不报错但会引入噪声。CLASS_MAP必须和后面 data.yaml 里的 names 顺序完全一致否则类别会错位。空标注文件不生成因为 YOLO 遇到空 txt 会当作背景图处理但 131 张里如果混入太多空文件正负样本比例会失衡。3.2 data.yaml 里三个不能写错的字段YOLOv8 的 data.yaml 看起来简单但小样本焊缝检测里最容易翻车的就是路径和类别数# datasets/weld/data.yaml path: ./datasets/weld # 数据集根目录建议用相对路径换机器时只改这一行 train: images/train val: images/val nc: 2 names: 0: weld_good 1: weld_badpath字段是 YOLOv8 新增的很多人从 YOLOv5 迁移过来时还在用train: ../train/images这种写法结果报Dataset not found。nc必须等于 names 的长度且 names 的顺序必须和转换脚本里的 CLASS_MAP 完全一致。我见过最冤的一次翻车是转换脚本里weld_good是 0data.yaml 里写成了 1训练 loss 正常下降但推理时所有类别全反了产线把良品判成不良品差点造成批量误杀。3.3 用 YOLOv8 在 131 张图上跑通第一个 baseline环境配置不展开假设你已经装好 ultralytics。第一条训练命令不要调任何超参先跑通yolo detect train \ datadatasets/weld/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch8 \ device0 \ projectruns/weld \ namebaseline参数说明modelyolov8n.pt是最小的预训练权重131 张图用 n 就够了用 l 或 x 只会过拟合得更快。batch8是因为 131 张图如果 batch 设 16一个 epoch 只有 8 个 iterationBN 层统计量更新次数太少容易崩。imgsz640是默认值但如果你的焊缝缺陷在原始图里很小可以试 960 或 1280代价是显存和训练时间。epochs100对小样本来说通常够但要看早停如果 50 轮后 val mAP 不涨就可以停。跑完第一轮后重点看runs/weld/baseline/val_batch0_pred.jpg和confusion_matrix.png。如果混淆矩阵里weld_good和weld_bad互相错得厉害先别调模型回去查标注一致性——131 张图里如果有 10 张标反了指标就永远上不去。4. 小样本焊缝检测的避坑与排查4.1 现象训练 loss 正常下降但验证 mAP 始终为 0原因验证集标注文件路径不对或者验证集 txt 里的类别 id 超出了nc范围。YOLO 在验证时如果找不到对应类别的预测mAP 计算会直接给 0但训练 loss 照常下降因为训练和验证走的是两套数据加载逻辑。解决先手动检查datasets/weld/labels/val/下是否有 txt 文件再随便打开一个 txt 看第一列数字是否小于nc。如果 txt 是空的说明转换脚本在验证集上没生成任何标注回去检查 XML 里的类别名是否和 CLASS_MAP 匹配。4.2 现象模型把所有框都预测成 weld_bad原因131 张图里如果焊接不良的样本占 80% 以上YOLO 的分类损失会被多数类主导模型学到一个“全预测为 bad”的局部最优。这在工业质检里很常见因为产线收集缺陷图的动力比收集良品图大得多。解决两个方向。一是数据层面对weld_good类别做过采样或者用 mosaic、mixup 增强时偏向良品类。二是损失层面在 YOLOv8 的train参数里加cls0.8提高分类损失权重或者用focal_loss替换默认的 BCE。我一般先试过采样因为改损失函数容易引入新的不稳定因素。4.3 现象BN 层崩溃训练几个 epoch 后 loss 变 NaN原因batch 太小比如 4 或 2且没有用预训练权重。BN 层在 batch 维度上计算均值和方差batch 太小统计量噪声大加上焊缝图像本身对比度低梯度容易爆炸。解决第一确保modelyolov8n.pt而不是yolov8n.yaml预训练权重能稳住初始阶段。第二把batch提到 8 或 16如果显存不够就降imgsz到 512。第三加patience20早停BN 崩了之后 loss 会先降后升早停能帮你省下后面几十轮的无效计算。4.4 现象推理时漏检细长型咬边缺陷原因YOLO 的默认 anchor 是基于 COCO 聚类的偏向于常规物体。焊缝咬边往往是细长条宽高比可能到 1:10 甚至更极端默认 anchor 匹配不上。解决在 YOLOv8 里 anchor 是自适应生成的但可以通过imgsz放大输入尺度来缓解。更直接的办法是在训练前用yolo detect train ... rectTrue开启矩形训练减少 padding 对细长目标的形变影响。如果还是漏就需要在标注里把咬边框得稍微宽一点给模型一点容错空间。4.5 现象换了台机器推理结果全变原因训练时用了 GPU推理时用了 CPU或者 OpenCV 版本不一致导致图像解码后的像素值有细微差异。焊缝检测对灰度变化敏感这种差异可能让分类结果翻转。解决固定推理环境。如果产线用 CPU 推理训练完就在 CPU 上跑一遍验证集确认指标和 GPU 上差不超过 2 个百分点。另外推理脚本里读图统一用cv2.imread并指定cv2.IMREAD_COLOR不要混用 PIL。5. 从 131 张到产线可用验证方法与一个提点技巧5.1 用留出法代替随机划分做最终验证131 张图如果按 8:2 随机划分验证集只有 26 张指标波动极大。我习惯在训练完成后额外做一次“留出法”验证从训练集里再抽 20 张从未参与训练的图按焊缝编号抽单独跑推理人工核对每一个预测框。这一步不看 mAP只看漏检和误检的具体案例。如果 20 张里漏检超过 3 张这个模型就不能上产线回去补数据或调阈值。# 用训练好的权重对单张图推理输出带框图像和置信度 yolo detect predict \ modelruns/weld/baseline/weights/best.pt \ sourceholdout_20/ \ conf0.25 \ saveTrue \ projectruns/weld \ nameholdout_checkconf0.25是默认值但焊缝检测里我一般会先看conf0.1时的召回再看conf0.5时的精度根据产线能接受的误杀率来定最终阈值。如果产线复检工位人力充足可以把 conf 调低到 0.15宁可多框几个让工人排除也别漏。5.2 一个提点技巧用背景图做负样本抑制误检131 张图里如果全是焊缝区域的特写模型没见过“没有焊缝的母材区域”推理时遇到整张图都是母材的帧就会乱框。解决办法很简单从产线视频里截 20 张不含焊缝的母材图放到images/train里对应的labels/train放空 txt 文件。YOLO 会把它们当作背景图学习“没有目标时不要输出框”。这个技巧在焊缝检测里效果立竿见影误检率通常能降一半以上。注意空 txt 文件必须存在不能只放图不放标签否则 YOLO 会报Label missing。5.3 我踩过最疼的一次坑早期做焊缝检测时我拿到一批标注好的图看都没看就直接训练mAP50 跑到 0.85兴冲冲拿到产线试结果工人反馈“十张有八张框错位置”。回去一张张看标注才发现标注员把“焊接良好”的焊缝边缘也框进去了模型学到的“焊缝”其实是“母材与焊缝的交界线”。131 张图里这种系统性标注偏差靠指标根本发现不了只能靠人眼一张张过。从那以后我拿到任何焊缝数据集第一件事不是写训练脚本而是随机抽 20 张把标注框画到原图上自己看一遍。这个习惯帮我省下了至少三次返工。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。