ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv7的焊缝好坏检测:从数据标注到TensorRT部署

基于YOLOv7的焊缝好坏检测:从数据标注到TensorRT部署 简介面向焊缝质量检测与工业视觉应用场景的 YOLOv7 资源包适合开发者、研究人员及自动化质检学习者快速搭建缺陷识别模型也可作为高校相关课程或企业质检项目的入门参考。资源包含已训练好的检测权重以及 PR 曲线、loss 曲线等训练评估记录方便了解模型收敛与检测性能同时附带用 LabelImg 标注好的钢材焊缝数据集jpg 原图与 xml、txt 两套标签分别存放在独立文件夹既能直接用于推理也能衔接 YOLOv7 继续训练和二次开发。压缩包共 3403 个文件以 1134 张 jpg 图片、1134 个 xml 标注、1135 个 txt 标签为主整体约 284.41MB目录组织清晰便于按数据、权重和训练记录分模块查阅。已有 1336 人学习下载。拿到包后可以快速复现焊缝好坏判定效果也可基于现有标签扩充数据减少从零采集与标注的时间成本。1. YOLOv7做焊缝好坏检测为什么比传统视觉靠谱焊缝质量检测在制造业里一直是硬需求但传统方案绕不开两座山一是特征要靠人去设计光源一变、板材反光一强阈值就失灵二是缺陷样本难以穷举气孔、夹渣、未焊透、裂纹各有各的形态靠固定规则去卡漏检率压不下来。YOLOv7之所以在这类场景里成为首选核心在于它把“找缺陷”变成了端到端的回归问题输入图像直接输出目标框和类别不需要单独做分割、特征提取或多阶段流水线。加上YOLOv7在COCO上的推理速度和mAP平衡做得相当好对产线上常见的工业相机和工控机来说TensorRT加速后能做到实时检测。但很多人在这个标题下真正卡住的不是模型本身而是两件事权重文件从哪来、训练数据怎么凑。公开的COCO权重在焊缝检测上几乎不可用因为COCO里根本没有“焊缝缺陷”这个类别而标注好的焊缝数据集又散落在各论文的补充材料和企业内部很难直接下载到能用的版本。所以我一般建议的落地路径是先用开源标注工具把自采样本整理成YOLO格式再用迁移学习从预训练权重起步最后针对误检做针对性的数据增强和阈值调优。这套流程里每一环都有具体的参数和坑值得逐个拆开讲清楚。2. 焊缝数据集的采集与标注YOLO格式的坑得从这里开始规避2.1 焊缝缺陷类别到底该建几类焊缝检测的数据集标注方案直接影响模型能学到什么。常见做法是建立多类别体系而不是简单地打“好”和“坏”两个标签。我在实际项目中建议至少分以下几类类别英文标签形态特征难易程度气孔blowhole圆形或椭圆形暗斑内部灰黑较易夹渣slag_inclusion不规则块状亮区边界模糊中等未焊透lack_of_fusion细长暗缝沿坡口延伸困难裂纹crack线条状有分支困难咬边undercut焊趾处凹陷边缘锐利中等合格焊缝good_weld表面均匀无异常凹陷突起较易如果只建“好/坏”两类模型虽然也能跑但坏样本内部差异太大损失函数难以收敛到合适特征。且产线上巡检后需要人工复核“坏”的具体类型分类缺失会让复核成本飙升。把类别细化到5到6类既不影响训练速度又能让后续的工艺改进有数据支撑。2.2 标注工具的选择CVAT还是labelImg标注工具的选择我一般分两种场景。样本量小、当场标注验证的用labelImg就够了它轻量、无需部署、导出YOLO格式就是一个文件夹的事样本量大、需要多人协作或外包标注的上CVAT它支持在线协同、自动标注预标注导入、轨迹标注还能直接导出YOLO格式。以labelImg为例标注时最关键的一个参数是classes.txt的定义顺序。YOLO格式的标注文件里每个目标对应一行文本类别ID 归一化的中心点x 归一化的中心点y 归一化的宽度w 归一化的高度h。类别ID是整数索引从0开始对应classes.txt里的行号。我见过不少项目翻车就是因为classes.txt里把“good_weld”放第一行训练配置里却把索引写错导致模型把合格焊缝当成背景。# 在labelImg中保存YOLO格式前先确保predefined_classes.txt内容如下 # good_weld # blowhole # slag_inclusion # lack_of_fusion # crack # undercut标注时的bbox建议贴紧缺陷边缘不要留白太多但也不要切掉缺陷本身。工业相机拍的焊缝原始图像通常包含大面积背景比如母材余量、压板反光等如果bbox把大量背景框进去模型就要浪费通道去学习背景特征推理时容易把面积相似的背景误判为缺陷。2.3 标注数量与质量的下限5万张还是5000张很多人问做焊缝检测到底要标多少张图才够。这个数取决于两类变量场景复杂度和缺陷先验。如果产线光照稳定、焊缝位置固定、材质不变5000张标注图足够启动训练如果换产线型号就换衬底材质和光照角度那2万张起步还需要按产线划分训练/验证集不能让某条产线的数据全部落进验证集。提示数据划分建议按“批次”而不是按“单张”。同一卷钢带、同一个工件的连续帧其背景高度相似。按单张随机切分会让验证集的背景分布与训练集重叠过大指标虚高产线上线后经不起换型。对于标注质量的把控我在流程里会加一道复审环节。任何一版标注数据随机抽5%的样本让另一位标注员独立标注同一批图然后计算mIoU标注框的交并比。mIoU大于0.8的样本视为一致性合格低于0.7的样本需要回到标注员手上修正。这个环节能拦住大部分因疲劳导致的漏标和错标。3. 从预训练权重到微调训练YOLOv7焊缝模型的参数配置3.1 官方权重、SAM权重还是自训练权重标题里提到“权重”YOLOv7训练链路里权重文件的来源决定了训练的起点。官方发布的yolov7.pt是在COCO上从头训练的参数量约3700万直接用它做焊缝迁移学习的起点是标准操作。过程是先加载COCO预训练权重将最后一层类别数从80改成6冻结前50层只训练检测头和少量特征层等损失降下去之后再解冻全网络做精调。另一种“权重”用法是从BAIDU等网盘拉来的焊缝专用权重即别人标注好、训练好的成品模型。这类权重的可用性取决于两点对方的类别定义是否和你一致、对方的图像来源是否接近你的产线环境。直接拿别人的权重做推理有一个隐性风险——它可能只在某一特定光源和角度下表现优异换一个工厂的车间照明就崩。所以拿到权重后要做一次快速的冒烟验证用自己现场的50张图跑一遍统计mAP再决定是否直接用。SAM3权重是另一个思路。SAMSegment Anything Model的权重文件体积近2.5GB分割精度高但直接拿来做焊缝检测并不合适。它的作用是辅助生成高质量的伪标签即先用SAM自动分割出焊缝区域再人工把分割结果转成bbox。这个流程能显著降低标注成本但需要跑一次推理产线上如果对实时性敏感不建议在生产链路中内嵌SAM。3.2 训练命令与关键超参数batch、imgsz、mosaicYOLOv7训练入口是train.py执行前首先要确认几个参数设置这些参数直接决定训练是否能在单卡上跑起来。python train.py --workers 8 --device 0 --batch-size 16 \ --data data/weld.yaml --img 640 640 \ --cfg cfg/training/yolov7.yaml --weights yolov7.pt \ --name weld_exp --hyp data/hyp.scratch.p5.yaml \ --epochs 150--data指向自定义的data文件里面需要定义train/val的图片路径和类别数。焊缝合数据集如果采用6个类别的设计data文件的nc字段写6names字段列表排列顺序必须和数据集的classes.txt一一对应否则训练出来的模型推理时会错位。--img参数最常用的有两档640或1280。分辨率越高对小缺陷的召回就越友好但没有好卡不要盲上1280显存占用会翻三倍以上如果目标是检测长度仅占画面1%的细小裂纹先试640训练推理时再动态放大到1280或2160。--hyp指向超参数文件train.py加载后会用其中的数值覆盖模型结构中默认的优化器与数据增强配置。焊缝训练里值得手动改动的超参数包括超参数默认值建议值原因lr00.010.001工业小数据集学习率过大会震荡mosaic1.00.5焊缝缺陷形态细长mosaic拼接易裁掉小目标fl_gamma0.01.5类别不均衡时用focal loss压住易分样本hsv_h / hsv_s / hsv_v各0.015/0.7/0.4调低一半过度颜色增强会让金属反光特征失真translate0.10.2焊缝合图像中缺陷位置漂移平移增强较有效超参数文件是yaml格式修改后训练路径不变模型在加载配置时会自动读取替换值。插一句Mosaic增强在焊缝检测场景要慎用——焊缝图像中缺陷往往只占几十个像素mosaic把四张图拼在一起再随机裁剪小目标的像素会被进一步压缩模型特征提取时几乎丢光细节。把mosaic降到0.5甚至0.3在焊缝场景下通常比官方默认值效果更好。3.3 从验证集指标反推问题recall低还是precision低训练结束时在验证集上会输出P、R、mAP0.5、mAP0.5:0.95。这组指标非看不可因为它们能直接定位模型短板。Class Images Labels P R mAP.5 blowhole 120 80 0.91 0.74 0.86 slag 120 100 0.84 0.82 0.88 lack_fusion 125 48 0.66 0.45 0.52 crack 118 32 0.57 0.31 0.41 good_weld 200 200 0.93 0.95 0.96裂纹类别recall只有0.31说明模型漏检率近七成。此时按“多标数据”或“加大epoch”都行不通问题大概率出在裂纹样本在整幅图中的像素占比太小。针对这类目标我有三个常用调法把输入分辨率从640提到1280用TTA做测试时增强推理时同时跑原始尺寸和2倍尺寸再合并结果或是在训练集中对裂纹样本做复制粘贴增广将每个裂纹实例的bbox区域随机粘贴到多张背景图上。4. 焊缝模型的部署与推理ONNX导出、TensorRT加速与边界调优4.1 导出ONNX并解决动态尺寸问题训练完成后部署端的第一个动作是将PyTorch模型导出成ONNX。python export.py --weights runs/train/weld_exp/weights/best.pt \ --grid --simplify --img-size 640 640--grid参数决定输出是否需要包含解码后的坐标工业部署一般打开它让推理结果直接是框坐标--simplify用onnx-simplifier精简计算图能去掉一部分冗余的算子。导出完成后用onnxruntime验证一遍输出维度是否符合预期。如果产线相机分辨率不是正方形需要在导出前把img-size改成与相机分辨率近似的倍数并搭配letterbox做等比缩放剩余区域pad成灰色而不是黑色否则金属表面的反光会在pad区域产生伪目标。4.2 TensorRT的FP16精度与奇怪误检TensorRT加速是焊缝检测落到产线监控的标准操作。导出engine文件的命令通常长这样trtexec --onnxweld.onnx \ --saveEngineweld_fp16.engine \ --fp16 \ --workspace4096FP16能带来近2倍的推理加速但工业场景里有个隐患金属反光区域的像素值分布很极端在某些浅色反光面上FP16的半精度表示会损失暗部像素的区分度。实测下来FP16和FP32在小目标上的召回率差异能到3到5个百分点。所以做精度对比测试时至少要在独立的验证集上分别跑FP16和FP32模型对比每个类别的recall值如果裂纹类别退化明显可只对该类别保留FP32或者用INT8加校准集的方式进一步压缩体积。trtexec --onnxweld.onnx --saveEngineweld_int8.engine \ --int8 --calibcalibration.cacheINT8需要准备校准集一般取训练集中300-500张有代表性的图。校准集的质量决定量化后模型的精度如果校准图里大量是合格焊缝量化就会把缺陷特征压缩到不可分辨。4.3 置信度阈值和NMS阈值的产线调优焊缝检测的误检和漏检之间存在一个滑动权衡点产线上常见做法是不单独改模型而是调推理端的两个阈值。conf_thres默认0.25在钢结构焊缝场景里裂纹出现时灰度与背景区分度低置信度普遍在0.15左右直接把conf降到0.1能拉回不少召回。但代价是误检率会上升尤其焊接飞溅物容易被框出来。NMS阈值则控制重叠框的合并粒度。焊缝目标细长且可能密集并列默认的NMS IoU阈值0.45可能把两条紧邻的裂纹合并成一个框。调低到0.3允许保留更多相近的框之后再按面积和长宽比过滤掉明显不合理的检测结果。import onnxruntime as ort import numpy as np sess ort.InferenceSession(weld.onnx, providers[CUDAExecutionProvider]) results sess.run(None, {sess.get_inputs()[0].name: input_blob}) # 输出array形状为 [1, 25200, 6]末尾两维为 class_id 和 confidence # 过滤置信度低于0.15并做类别筛选 mask results[0][..., 4] 0.15提示真正确认模型在产线上是否稳定的办法是连续录像15分钟用全帧跑一次推理统计误检帧数和漏检帧数而不是只看单帧的效果。5. CBAM通道注意力在焊缝检测中的实践与误区5.1 通道、空间权重分配为什么对缺陷检测有效CBAMConvolutional Block Attention Module是一种轻量注意力模块串联通道注意力与空间注意力让网络更关注信息量大的通道和区域。焊缝缺陷本身特征不明显尤其裂纹和夹渣在灰度上极易与背景混淆但通道维度上不同特征图对应的语义不同——有的特征图对金属纹理敏感有的对边缘敏感。CBAM的可解释性在于它能动态地为这些特征图分配权重。在YOLOv7的backbone或neck中插入CBAM模块是可行的且改动不大import torch import torch.nn as nn class ChannelAttention(nn.Module): def __init__(self, in_planes, ratio16): super().__init__() self.avg_pool nn.AdaptiveAvgPool2d(1) self.max_pool nn.AdaptiveMaxPool2d(1) self.fc nn.Sequential( nn.Conv2d(in_planes, in_planes // ratio, 1, biasFalse), nn.ReLU(inplaceTrue), nn.Conv2d(in_planes // ratio, in_planes, 1, biasFalse) ) self.sigmoid nn.Sigmoid() def forward(self, x): avg_out self.fc(self.avg_pool(x)) max_out self.fc(self.max_pool(x)) return x * self.sigmoid(avg_out max_out)上面的代码定义了通道注意力的核心计算对空间维度做平均池化和最大池化得到两个通道描述符分别过两层卷积后融合再用sigmoid生成0到1之间的通道权重。这个权重会逐通道乘回原特征图就等于在告诉网络“哪些通道值得保留、哪些通道可以抑制”。空间注意力模块则在通道维度上做池化得到位置重要度。两者串联后网络对细长、低对比度的缺陷区域响应更强烈。实测中在YOLOv7-Small结构上加入CBAM推理耗时增加约0.2毫秒对产线完全可接受而裂纹类别的recall平均能提升4到6个百分点。5.2 错误的插入位置与损失不降反升不少人从GitHub上拿到CBAM代码后直接往YOLOv7每个CSP结构后面都插一遍结果训练损失比原版涨了一截。原因是CBAM的本质是重新校准特征如果插入位置在浅层且高分辨率特征图上空间注意力会过度关注背景区域反而抑制了真实缺陷的通道响应。我常用的做法是只把CBAM插到backbone的后两个stageP4和P5之后即分辨率降低到20x20和10x10的地方。这两个尺度的特征图捕获的是语义信息焊缝缺陷的类别判断在这里更依赖全局上下文。P2和P3层的高分辨率特征要保留原始细节不做通道重标定。loss不降时第一件事先确认打印出的训练loss曲线是否下降若震荡明显直接把插入的CBAM去掉回归基线再逐步添加。5.3 焊缝场景下注意力热力图的可视化与校验加不加注意力不能只看指标还要看热力图是否聚焦到正确区域。用Grad-CAM生成注意力热力图将模型输出层对裂纹类别的梯度反传到特征图得到空间重要性分布# 伪代码示意 import cv2 import torch def visualize_attention(model, image, target_class): 生成Grad-CAM热力图叠加到原图 image_tensor preprocess(image) feature_map model.get_feature_map(image_tensor) output model.classifier(feature_map) grad torch.autograd.grad(output[0, target_class], feature_map)[0] weights grad.mean(dim(2, 3), keepdimTrue) cam torch.relu((weights * feature_map).sum(dim1))[0] return overlay_cam(image, cam.cpu().numpy())正常情况下的热力图应当高亮在裂纹或气孔区域。如果热力图聚焦到母材纹理区说明网络学到的是背景特征要通过在训练集里增加“无缺陷但母材同样纹理”的硬负样本来纠正如果热力图太分散常见原因是类别定义过粗需要回到数据集标注层把“好焊缝”里的欠完美形态单独挑出来做补充标注。6. 用视觉验证和回归测试收尾一条值得固化的焊缝检测工作流模型训练完不代表项目交付完。最后一步值得做一个系统化的回归测试用固定数据集跑每次改动的对比把结果量化存档。我在实践中会固定三组数据一组是产线真实工况下采集的原始视频帧一组是人为构造的极端场景强反光、低照度、快速运动模糊一组是纯背景负样本无缺陷但纹理复杂。三组数据分别统计三类指标漏检数、误检数、平均置信度。如果模型在极端场景有漏检不急着改模型先用增强手段在推理端处理对输入图做CLAHE自适应直方图均衡化增强局部的灰度对比度再把结果输入模型如果加入CLAHE后漏检显著减少就可以把它固化到预处理管线中。这里的规范是一切改动都做成可配置项产线上某个型号需要强对比度另一个型号需要弱对比度不要写死成一个固定流程。# 固定回归测试命令每次提交代码前跑一遍 python test_regression.py \ --weights runs/train/weld_exp/weights/best.pt \ --data data/weld_env.yaml \ --conf 0.15 \ --iou 0.5 \ --save-json results/weld_regression.json回归测试的json输出里重点看按类别分的recall。如果一次分类结构调整后裂纹和夹渣的recall都下降可优先查看注意力模块是否破坏了该类别的低层边缘特征若确认是CBAM的副作用就在该类别上单独关闭空间注意力分支。最后建议把已训练好的模型和一批标注样本打包成一个固定版本存档训练数据和代码版本一一对应方便后续用新数据继续训练时快速复现历史结果。焊缝检测项目走到这一步才算真正具备了上线、换型、迭代三个能力。本文还有配套的精品资源点击获取
返回列表