ARTICLE DETAIL

资讯详情

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

小样本轴承缺陷检测:568张图如何用YOLO跑通产线

小样本轴承缺陷检测:568张图如何用YOLO跑通产线 简介面向工业视觉缺陷检测场景的YOLO轴承生产缺陷数据集与配套脚本适合目标检测学习者、工业质检开发者及希望复现YOLO训练流程的Python用户使用。数据集包含568张轴承图片标注三类常见生产缺陷预处理与标注思路可直接借鉴配套txt标签与XML标注可适配YOLO官方Darknet及YOLOv5等常见框架。压缩包共1772个文件涵盖624张JPG图片、577个txt标签、568个XML标注、2个Python脚本和1个YAML配置整体约755MB目录结构清晰可按图像、标签、配置分层使用。已有337人学习下载。利用该资源可完整体验从数据准备、标注格式转换、模型配置到缺陷检测的训练链路Python脚本和YAML文件有助于快速启动训练并降低调参门槛同时也可用于研究轴承检测中的光照变化、拍摄角度差异和背景干扰等鲁棒性问题。这套数据与代码组合可作为轴承外观质检和YOLO目标检测入门项目的起步材料。1. 568张图训YOLO做轴承缺陷检测到底靠不靠谱看到568张训练图不少人的第一反应是“数据量太少”。但在真实轴承产线上能整理出568张带标注的缺陷图已经是能启动项目的底子。轴承是标准件缺陷形态高度重复一张划伤样本能代表一整批同类故障可也正因为是标准件光照、角度、反光变化会让同一个缺陷长得不一样。这个标题把YOLO、568张、三类缺陷放在一起本质是一个工业小样本目标检测命题数据量有限、类别明确、要求尽快跑通并让产线接受。这篇笔记按数据准备、模型选型、训练参数、避坑、部署验证的顺序把这套方案拆完整。2. 把568张图准备成能训练的数据集三类缺陷标注与划分策略2.1 三类缺陷怎么定划伤、麻点、剥落的标注边界轴承表面缺陷最常被归成三类划伤scratch是细长沟状痕迹经常与金属反光混在一起麻点pitting是成片出现的细小凹坑单看轮廓不大但密度高剥落spalling是表面材料成块掉落后留下的不规则区域边界通常很毛糙。这三类在可见光成像下特征差异明显用YOLO做目标检测完全能分开前提是标注时不能抱着“差不多就行”的心态。标注边界是第一批坑。麻点通常成群出现逐个点去标的话一张图能标出几百个框标到怀疑人生而且YOLO的NMS会把密集框互相抑制导致漏检。常见做法是把一团密集麻点当作整体标成一个框框住聚集区域划伤则必须标完整条轨迹不能只标一小段剥落用外接矩形框住剥落块框里带进一点正常表面也能接受。如果一张图同时出现两类缺陷就分多个框标每个框只给一个类别。如果你用的是YOLO格式一张图对应一个同名txt文件每行是“class_id cx cy w h”坐标全部归一化到0到1。标注工具用labelImg这类能直接导出YOLO格式的即可labelme也行但输出JSON还要转一道。建议从第一天就直接存YOLO格式后面训练能省掉转换脚本的麻烦。2.2 按工件分组划分数据集而不是按图片随机划分568张图看着少真正的坑往往不在数量而在划分方式。假设一条产线上同一个轴承被拍了八张不同角度的图把这八张图随机分到train和val里模型训练时已经见过同一个表面的不同角度版本验证分数会虚高到产线换新批次就崩。轴承这类标准件正确的划分维度是“工件”而不是“图片”。我一般用按工件分组的分层采样先把同一个轴承ID下所有图片编号设成同一组再按每个类别的占比做分层划分。sklearn里可以这样实现import numpy as np from sklearn.model_selection import StratifiedGroupKFold image_files [...] # 568张图的路径列表 group_ids [...] # 同一个轴承的多张图填同一个ID例如 B001、B001、B002... labels [...] # 每张图的主缺陷类别 0/1/2 sgkf StratifiedGroupKFold(n_splits5, shuffleTrue, random_state42) for train_idx, val_idx in sgkf.split(image_files, labels, groupsgroup_ids): break # 取第一折相当于约 8:2 的划分 print(len(train_idx), len(val_idx))这段代码的核心是StratifiedGroupKFold同时做了两件事分层保证每一折里三类样本比例接近全量数据分组保证同一个轴承ID的图片不会同时出现在train和val。如果一张图包含多类缺陷labels就填数量最多的那个类别分组信息不受影响。划分完记得把结果落成目录常见做法是生成images/train和images/val两个文件夹再把对应txt按同样路径复制过去。验证集给到总数据的两成也就是110张左右如果样本实在太少也可以从train里再切一部分当test测试集只在最终评估时用一次训练过程中反复看测试集是给自己留雷。2.3 小样本增强策略在线增强要保守离线增强要克制YOLO默认开启的在线增强包括mosaic、mixup、HSV扰动、随机翻转和缩放这些是针对大数据集设计的。568张做基数时mosaic把四张图拼一起缺陷目标在拼接后被缩小甚至裁掉一半对小目标检测反而不利。我的习惯是mosaic降到0.3左右mixup降到0.1或者直接关掉上下翻转要看轴承摆放方向产线相机角度固定就关掉保留左右翻转、轻微旋转和亮度对比度扰动。离线增强可以补量但别无脑扩。旋转角度控制在5度到15度再大就违背轴承的实际成像规律高斯噪声、亮度变化、对比度拉伸这些模拟光照波动的增强性价比最高。离线增强要在数据集划分完成之后单独对train做验证集和测试集必须保持原始图像否则增强过的纹理会被模型当成特征验证分数虚高。见过有人把训练集扩到两三千张mAP看着不错一下产线就翻车最后查出来验证集也被增强过评估结果根本不代表真实水平。注意产线上除了缺陷图还会出现大量正常件建议单独留一批OK工件图做误检验证不要混进缺陷训练集。训练时没有负样本不代表部署时没有误检率要用真实产线数据单独统计。3. YOLO模型选型与训练参数小数据集下从n到s的务实配置3.1 为什么小数据集先选YOLOv8n或YOLOv5n而不是大模型标题只写了“基于YOLO”没限定版本实际项目里用得最多的还是YOLOv8和YOLOv5两个系列。对568张这个量级模型容量的选择比版本选择重要得多。YOLOv8n参数量在3M级别YOLOv8s在11M级别再往上在这个数据量下基本必过拟合。小模型收敛快、显存占用低、部署也轻松而轴承缺陷模式高度重复n和s的精度差距没有想象中那么大。我习惯先用YOLOv8n跑通完整流程把数据划分、标注质量、评估指标都理顺再换YOLOv8s对比一次。如果两类提升明显就留下来如果只涨零点几个点果断用n后面做TensorRT部署时帧率差距非常直观。YOLOv5n也完全可以如果你有一张老卡要跑推理v5的部署生态更成熟。小模型另一个好处是对增强关闭更宽容。大模型需要更强增强压过拟合小模型容量有限增强稍微保守反而收敛更干净。3.2 用YOLOv8训练自己的轴承数据集最小可复现命令动手训练前先把数据配置文件写好。data.yaml放在项目根目录path: /work/bearing train: images/train val: images/val names: 0: scratch 1: pitting 2: spallingnc可以不写YOLO会从names长度推断类别数。类别名用英文是为了避免输出层编码问题也方便后面做TensorRT导出时映射类别。path建议用绝对路径训练时能少踩一个“相对路径找不到图片”的坑。训练命令如下yolo detect train \ data/work/bearing/data.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ patience30 \ optimizerAdamW \ lr00.001 \ ampTrue \ project/work/bearing/runs参数按顺序说明data指向刚才的yamlmodel用yolov8n.pt预训练权重别从零开始训epochs给150小数据集在100到200轮之间就能收敛再长就是背训练集噪声imgsz先固定640后面因为小目标漏检再考虑提960batch在T4这种16G显存上用AMP能开到16甚至32显存小就降到8patience30表示验证指标连续30轮不提升就早停优化器我用AdamW而不是默认SGD小数据集下AdamW收敛更平滑lr0给0.001偏保守够用。训练完看runs/detect/train/weights下的best.pt和last.ptbest是按验证集指标保存的部署用best。第一次训练不要急着调参先看清日志里的P、R、mAP50三个数再决定动哪里。3.3 损失函数与关键超参哪些值得动哪些别乱动YOLOv8默认边界框损失是CIoU分类损失是BCE这对多数缺陷检测够用。很多教程让换SIoU或者加focal loss但在568张规模下换损失函数带来的提升通常不如修正标注和增强策略。我倾向于把损失函数当最后手段不是第一优化项。需要动的是三个地方。第一是imgsz麻点这类小目标漏检多时从640提到960mAP往往直接涨三五个点代价是显存和推理时间上升。第二是类别样本量失衡比如划伤300张、麻点只有80张YOLOv8命令行没直接暴露类别权重参数常见做法是用Python API自定义loss或者对少数类做离线过采样。第三是mosaic前文说过小数据集、小目标场景下mosaic经常起反作用直接降权重最省事。还有一个容易忽略的点batch太小会让BatchNorm统计不稳显存不够时不要硬开batch4不如用accumulate等效增大batch或者减小输入分辨率保证batch能上去。训练时看一眼loss曲线的震荡幅度如果剧烈跳动先怀疑batch过小或lr过大这两个参数的优先级高于换损失函数。4. 避坑小数据集训YOLO的五个翻车点与排查方法4.1 训练loss一直在降验证mAP却纹丝不动现象日志里box_loss和cls_loss一路向下表面看训练很健康但每个epoch结束后的mAP50卡在0.2甚至更低。原因八成是增强过强模型学到了增强引入的伪纹理也可能标注框偏移大、类别标错loss主要在拟合噪声。两种情况的共同特征是训练loss降得快验证指标不动。解决先把mosaic降到0、mixup关掉、亮度扰动减弱用最朴素的数据跑一轮再对比train loss和val loss的gapgap越拉越大就是过拟合砍增强或换更小的模型提前早停。如果是标注噪声问题抽20张图人工复核标注框这条检查比调任何参数都有效。4.2 细小缺陷漏检严重召回率上不去现象划伤、麻点这类小目标在测试集上大量漏检输出的框位置基本对但recall只有0.3到0.4。原因YOLO的下采样倍数对极小目标不友好640输入下小目标特征经过几轮下采样后只剩几个像素密集麻点互相靠近NMS还会把相邻框合并成一个框。解决先试imgsz960或1280通常立竿见影显存不够就用切片推理把原图切成带重叠的块分别检测再合并也就是SAHI的常见思路。切片尺寸一般取640重叠率20%推理时间会增加但召回率提升明显。机油盖、齿轮这类小金属件的缺陷检测也常遇到同一个问题处理方式基本一致。4.3 验证集分数比训练集还高先查数据泄漏现象训练集mAP50是0.7验证集反而0.85怎么看都不合常理。原因几乎可以肯定是同一个工件ID的图片同时进了train和val模型记住了该工件表面的纹理验证时直接套答案。轴承是标准件同批次表面纹理高度一致这种泄漏很难靠肉眼发现。解决回到2.2用StratifiedGroupKFold按工件分组重新划分再训练。这个坑查起来最费时间因为数据量少人工翻图很难看出哪张图两边都出现过不如一开始就把划分逻辑写对。4.4 三类中有一类AP几乎为0现象划伤和剥落的AP都到0.7以上麻点那一类只有0.05。原因该类别样本量太少或者标注方式有问题。比如麻点被标成一个巨大的框正样本质量低模型学不到该类边界特征。解决先检查该类图片数量和标注框尺寸分布。样本少就做离线过采样把包含该类的小图区域复制粘贴到空白图上扩到和最多类一个量级框太大就重新标把密集麻点拆成多个紧贴的小框。数据补齐后重训比换损失函数有效得多。负样本也要注意训练集全是缺陷图没有OK件图部署时正常件的纹理、油污会被误判成缺陷所以单独准备一批OK图做验证十分必要。4.5 TensorRT FP16导出后精度明显掉点现象PyTorch里mAP50有0.85导出TensorRT FP16后直接掉到0.7有时还在小目标上疯狂误检。原因FP16的数值范围和精度低于FP32小目标的框坐标回归对这些数值误差更敏感测试集本身有边界case时FP16会放大这种不稳定。解决先跑一遍FP32引擎确认不是数据泄漏导致的虚高再看掉点幅度。掉点超过一个百分点就用INT8加校准集INT8也稳不住就把敏感层保留FP32。掉点在合理范围内且误检率可接受FP16的提速优势是值得换的但上线前必须用验证集完整比对一轮不能只看几张图的视觉效果。5. 上线前的最后一公里TensorRT加速与按类统计漏检率5.1 导出ONNX并生成TensorRT引擎训练完的best.pt是PyTorch权重产线推理一般不用PyTorch直接跑。先导出ONNX再转TensorRTyolo export modelbest.pt formatonnx imgsz640 opset12 trtexec --onnxbest.onnx --saveEnginebest.engine --fp16trtexec执行完会在终端打印引擎的mean inference time这是估算并发路数的第一手数据。在T4这类16G卡上常见结果在几毫秒到十几毫秒之间具体由模型大小和输入分辨率决定拿自己训练的模型实测最准。5.2 单卡能带几路视频流用延迟倒推并发很多人搜“T4 1080P 25帧每秒用TensorRT YOLO 640分辨率能支持多少路”这个问题没有固定答案只能按自己的引擎实测倒推。假设RTSP拉流后每帧切到640×640送入引擎单帧耗时t毫秒单卡理论吞吐就是1000/t FPS。目标要求每条流25FPS理论路数是(1000/t)除以25再按50%到70%的利用率扣除取帧、预处理、NMS和调度开销得到实际可带路数。举例测得t5ms理论200FPS除以25FPS等于8路按60%利用率算大概稳带5路。不要满打满算推理卡满后CPU取帧和图像编解码会最先扛不住。多路并发时单独起取帧线程不要让推理线程等网络帧。5.3 用三类召回率评估缺陷检测的实际价值最终评估不是只看整体mAP要按类别分别看召回率。轴承缺陷检测里漏检比误检贵一个缺陷滑过去可能直接造成整批退货。我习惯用下面这段脚本对测试集做最终评估from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) metrics model.val(datadata.yaml, splittest, conf0.25, iou0.45) print(各类别 mAP50-95:, metrics.box.maps) print(整体 precision/recall:, metrics.box.p, metrics.box.r)conf降到0.1时召回率还能往上走但误检也会增多。上线前用一段时间真实产线的OK工件图统计误检率只报单一阈值下的数字没有参考意义。我现在的习惯是拿到这类小样本项目先把数据按工件分组切好再固定用轻量模型跑通baseline确认增强策略不激进最后才谈TensorRT和并发路数。这个顺序帮我少踩了很多坑希望帮到你。本文还有配套的精品资源点击获取
返回列表