ARTICLE DETAIL

资讯详情

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

针织品瑕疵检测数据集详解:YOLOv9标记版上手与训练避坑

针织品瑕疵检测数据集详解:YOLOv9标记版上手与训练避坑 简介面向工业质检场景的针织品瑕疵检测数据集压缩包共105个文件、5.37MB解压后包含52张原始jpg图像、52个txt标注文件以及1个yaml配置。txt标注文件采用YOLO格式逐行记录瑕疵对象的类别编号与归一化边界框坐标可直接作为YOLOv9的训练标签配套jpg图像展示真实针织面料在不同纹理、光照与拍摄角度下的形态便于检验模型的实际鲁棒性yaml文件定义类别名称、nc参数与数据路径解压后配置本地路径即可接入训练流程。数据规模虽不大但涵盖数据、标注、配置三类模块适合用于学习目标检测数据集的构建规范、完成YOLOv9的快速验证也可作为迁移学习、数据增强或课程设计的基础素材。目前已有836人学习下载主要面向计算机视觉初学者、工业质检算法工程师以及需要在小样本场景中测试检测效果的开发者。1. 针织品瑕疵检测数据集为什么我建议直接拿 YOLOv9 标记版上手做工业视觉的人应该都有同感找数据集比调模型还难。尤其是纺织行业网上能下到的瑕疵检测数据集大多是布匹、无纺布真正针对针织品的少得可怜。这份「针织品瑕疵检测数据集 yolov9标记.zip」恰恰是拿来就能用的类型——图片已经用 YOLOv9 格式标好解压后直接喂给 YOLOv9 训练就行。它解决的核心问题只有一个你不用再从零标注省掉两三天的人工打标时间适合刚入坑瑕疵检测的工程师、做毕设的学生以及想快速验证 YOLOv9 在自己产线上是否可行的从业者。文件名里带 .rf. 说明这些图是从 Roboflow 导出的标注信息齐全后面我会逐项拆开看。2. 数据集解剖YOLOv9 格式的目录结构、标签文件与 data.yaml 配置2.1 从文件名看懂数据集来源和划分逻辑先别急着解压把文件名读一遍能省很多事。这份 zip 里的图片文件名大致分两类一类是 IMG_14_JPG.rf.4b9f682814059eaf40b9fa484360129b.jpg 这种一类是 z4874860538074_9917321184aecfb61fc44bb74161ee10_jpg.rf.ab1907d32b941b1e98e3d277440a355e.jpg 这种。这两个前缀对应两种拍摄来源IMG 开头的是手机或相机直接拍的产线照片z487486 开头的是带设备编号的工业相机采集图。rf. 后面那串长哈希是 Roboflow 平台给每张图的唯一标识说明这批图曾经在 Roboflow 上做过标注和导出。如果你之前用过 Roboflow 导出的数据集会发现所有文件都遵循「原始文件名 .rf. 哈希值」这个约定。解压后务必检查有没有 train / valid / test 三个子目录。Roboflow 默认按 70/20/10 或 80/10/10 划分数据集每个子目录里图片和 txt 标签是成对出现的。我的习惯是先看 valid 目录里有没有图——如果只有 train说明导出时没做划分训练时得手动切分。# 解压并检查目录结构 unzip 针织品瑕疵检测数据集_yolov9标记.zip -d knit_defect cd knit_defect find . -type f | awk -F/ {print $2} | sort | uniq -c这段命令输出的应该是类似 train 310、valid 40、test 50 这样的数字分布。如果只看到一堆 图片.jpg 和对应 图片.txt 平铺在一起那就得自己写脚本划分数据集了。注意 unzip 时中文文件名可能乱码建议用 unzip -O GBK 选项解压这类细节后面避坑章节专门讲。2.2 YOLOv9 的标签格式每个 txt 里到底写了什么YOLOv9 和 YOLOv5/YOLOv8 一样标签是纯文本 txt 文件每一行表示一个目标框格式固定为五列class_id x_center y_center width height但有个细节必须注意后四列不是像素坐标而是归一化坐标。具体计算方式是相对于图片宽度和高度的比例。比如一张 640x640 的图一个瑕疵框的像素坐标是 (200, 300, 80, 50)那 x_center 就是 (200 40) / 640 0.375y_center 是 (300 25) / 640 ≈ 0.508width 是 80 / 640 0.125height 是 50 / 640 ≈ 0.078。0 0.375 0.508 0.125 0.078 2 0.812 0.214 0.063 0.047第一行的 0 是类别编号后面的数字全是 0 到 1 之间的小数。为什么用归一化坐标因为训练时 YOLO 会对输入图做 letterbox 缩放如果标签用像素坐标缩放后标签就全对不上目标了归一化之后无论输入尺寸怎么变标签比例始终不变。这也是 YOLO 系列和 Faster R-CNN 这类两阶段检测器的重大差异之一。用下面的脚本快速统计这份数据集有哪些类别import os from collections import Counter label_dir knit_defect/train/labels class_counter Counter() for label_file in os.listdir(label_dir): if not label_file.endswith(.txt): continue with open(os.path.join(label_dir, label_file), r) as f: for line in f: parts line.strip().split() if len(parts) 5: class_counter[int(parts[0])] 1 print(类别分布:, dict(class_counter))这个脚本遍历 train 目录下所有 txt 标签文件对每一行取出第一个数字——类别 ID然后计数汇总。跑完你会看到类似 {0: 320, 1: 156, 2: 89} 的输出其中 0 就对应 data.yaml 里 classes 列表的第一个名字。如果发现三个类别的数量差异悬殊比如某个类别只有几十个框而另一个有上千个后面训练时就得考虑加重该类别的 loss 权重或者用 mosaic 增强来缓解。2.3 data.yaml 的正确改法路径和类别名一个都不能错YOLOv9 训练时读的不是 txt 标签而是 data.yaml 配置文件。这个文件告诉训练脚本「图片在哪、标签在哪、有哪些类别」。解压后的数据集里如果没有 data.yaml就得按下面的模板自己写一份# data.yaml train: /absolute/path/to/knit_defect/train/images val: /absolute/path/to/knit_defect/valid/images test: /absolute/path/to/knit_defect/test/images nc: 3 names: [破洞, 污渍, 跳线]train 和 val 字段建议写绝对路径因为 YOLOv9 训练时会在当前工作目录下解析相对路径如果你把数据集放在别处训练脚本大概率找不到图片。nc 是类别总数names 是类别名列表顺序必须和标签文件里的 class_id 对应——第 0 行对应 names[0]第 1 行对应 names[1]以此类推。类别名可以改成你业务里的叫法比如「破洞」改成 holes「污渍」改成 stain但 names 的顺序和数量绝不能乱动。判断类别名是否匹配有个土办法随便打开一个标签 txt 文件看里面出现的最大的 class_id 数字是多少。如果看到 3但 yaml 里 nc 写的 3那第 3 个 id 就超范围了训练必然报错。YOLOv9 训练时对标签索引越界非常敏感轻则跳过该样本重则直接崩训练进程。3. 用这份数据集跑通 YOLOv9 训练环境准备、参数选型与完整命令3.1 环境搭建GPU 驱动、PyTorch 和 YOLOv9 代码库的版本匹配YOLOv9 官方代码库基于 PyTorch 实现源码在 GitHub 上克隆下来就能用。但环境配置有几个版本雷区我先列出来组件推荐版本备注Python3.8 - 3.103.11 以上部分依赖编译不过CUDA11.8 或 12.1对应不同 PyTorch 版本PyTorch2.0.0 或 1.13.1官方 requirements 里指定了版本范围torchvision与 PyTorch 匹配比如 2.0.0 配 0.15.1有个常见做法是用 conda 建一个独立环境避免把系统 Python 搞乱。安装 PyTorch 时注意 pip 源国内直接 pip install torch 大概率走 CPU 版必须用带 CUDA 的 index-url。装完验证一下 GPU 是否可用python -c import torch; print(torch.__version__, torch.cuda.is_available())输出 True 才说明 CUDA 环境正常。如果这里显示 False后面训练时 YOLOv9 会默默跑 CPU 模式一个 epoch 能慢十倍。遇到这种情况先检查nvidia-smi看驱动是否正常再检查 PyTorch 是不是 CPU 版pip list | grep torch看输出特征。然后是克隆 YOLOv9 官方代码并安装依赖git clone https://github.com/WongKinYiu/yolov9.git cd yolov9 pip install -r requirements.txtrequirements.txt 里列了 torch、torchvision、opencv-python、numpy 等依赖。我习惯先装好 torch 再跑 requirements否则 pip 会顺手把 torch 也装成 CPU 版覆盖掉刚才配好的 GPU 版。3.2 预训练权重与训练命令的选择逻辑YOLOv9 提供了两种模型规模yolov9-c基础版和 yolov9-e增强版另外还有配合 GPU 显存较小的 yolov9-t 版本。对于针织品瑕疵检测这种单类目标不算多的任务我一般直接上 yolov9-c精度够用训练速度也不至于让人等得心烦。预训练权重从官方 Release 页面下载注意下载链接里有 ckpt 后缀的版本还是 pt 后缀的版本。训练用 pt 版本即可ckpt 版里夹带了优化器状态和训练配置体积大几倍但精度没有额外收益。# 开始训练batch-size 根据显存调整 python train.py \ --batch-size 16 \ --epochs 100 \ --img 640 \ --data /path/to/knit_defect/data.yaml \ --weights yolov9-c.pt \ --device 0 \ --hyp hyp.scratch-high.yaml \ --project runs/kni_defect \ --name train_v1batch-size 是每轮喂给 GPU 的图片数16 对 8GB 显存是比较稳的起步值如果显存只有 6GB降到 8。epochs 100 对工业瑕疵检测通常够了我见过不少项目 50 轮就收敛。img 是训练输入尺寸640 是 YOLO 系列默认值如果你的瑕疵框特别小——比如几十个像素的跳线破洞——可以试试 960但显存占用会显著上升。hyp.scratch-high.yaml 是高数据增强的配置文件。瑕疵检测场景里目标形态变化大、样本量又有限增强策略直接决定模型能不能泛化到产线实拍图。这里不做特殊修改先用默认配置跑一轮后面根据 loss 曲线再调。3.3 训练过程中的监控指标loss 曲线和 mAP 怎么读训练起来之后终端会滚动输出每一轮的指标Epoch gpu_mem box obj cls labels img_size 49/100 6.73G 0.04810 0.06230 0 5 640box loss 是框回归损失obj loss 是置信度损失cls loss 是分类损失。对单类检测任务所有瑕疵算同一类cls loss 始终是 0 是正常的。关键看 box 和 obj 是否持续下降。训练结束时会在 runs/kni_defect/train_v1/ 目录下生成结果汇总包括 confusion_matrix.png、results.png、F1_curve.png 等图表。mAP 是核心指标的通俗说法分为 mAP0.5 和 mAP0.5:0.95 两种。前者只看 IoU 阈值 0.5 下的平均精度后者是 0.5 到 0.95 每隔 0.05 取一个阈值的平均值。工业质检场景我更看重 mAP0.5因为实际部署时我们通常把置信度阈值调得很低、把 IoU 阈值调成 0.5保证瑕疵一个不漏宁可误报再多开一档人工复核。4. 标签校验与数据增强动手检查这份数据集的真实质量4.1 批量可视化标签验证坐标是否和瑕疵位置对得上标注数据是机器学习里最不能省的一步。YOLOv9 这个项目我看过太多翻车案例——标签文件里坐标写了、格式也正确但画出来就是框不住目标。原因多是导出时坐标系搞错或者标注者手抖。拿到这份数据集后第一件事就是把标注画回图片上看。import cv2 import glob image_paths glob.glob(knit_defect/train/images/*.jpg) for img_path in image_paths[:20]: img cv2.imread(img_path) h, w img.shape[:2] label_path img_path.replace(images, labels).replace(.jpg, .txt) with open(label_path, r) as f: lines f.readlines() for line in lines: cls_id, xc, yc, bw, bh map(float, line.strip().split()) x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(check_ img_path.split(/)[-1], img)这段脚本把归一化坐标乘以图片实际宽高还原成像素坐标再用 OpenCV 画框。重点看三类问题一是框是否明显偏大偏小二是框是否偏离瑕疵位置三是有没有重复标注的情况。前 20 张图看下来基本能判断出标注员的水平。如果发现大面积标注偏移那训练前就得考虑重新标注或者做坐标校正否则模型会学到错误的位置信息。4.2 类别不平衡与数据增强策略针织品瑕疵存在一个常见情况破洞这类明显缺陷样本多跳线这类细微缺陷样本少。用之前统计脚本跑完类别分布如果最少的类别不到最大类别的 10%就需要做样本增广否则小类别基本学不出来。import albumentations as A import cv2 import numpy as np transform A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(p0.3), A.GaussNoise(p0.2), A.ShiftScaleRotate(shift_limit0.05, scale_limit0.05, rotate_limit15, p0.5) ]) img cv2.imread(knit_defect/train/images/IMG_14_JPG.rf.4b9f682814059eaf40b9fa484360129b.jpg) for i in range(5): transformed transform(imageimg) cv2.imwrite(faug_{i}.jpg, transformed[image])albumentations 库是工业视觉里做增强最顺手的工具。注意它只管图片增强不管标签同步——如果你做的是检测任务增强时标注框也得跟着旋转、平移albumentations 提供了 bbox 参数同步接口。上面这段只是图片演示实际用在训练管线里时YOLOv9 自带的 mosaic 策略会自动处理标签同步所以不一定非得引入 albumentations。4.3 标注格式快速校验脚本训练前再做一道硬校验统计所有标签检查坐标是否超出图片边界、有没有空标签文件、类别索引是否越界。这几个问题在 Roboflow 导出的数据集里相对少见但一旦出现会让训练中断或产生无效学习。# validate_labels.py import os import cv2 ok_count 0 error_list [] for split in [train, valid, test]: img_dir fknit_defect/{split}/images label_dir fknit_defect/{split}/labels for img_name in os.listdir(img_dir): img cv2.imread(os.path.join(img_dir, img_name)) h, w img.shape[:2] label_path os.path.join(label_dir, img_name.replace(.jpg, .txt)) if not os.path.exists(label_path): error_list.append(f{img_name}: 缺少标签文件) continue with open(label_path, r) as f: lines f.readlines() if len(lines) 0: error_list.append(f{img_name}: 空标签文件) continue for line in lines: parts line.strip().split() if len(parts) ! 5: error_list.append(f{img_name}: 格式错误 - {line}) continue xc, yc, bw, bh map(float, parts[1:]) if not (0 xc 1 and 0 yc 1 and 0 bw 1 and 0 bh 1): error_list.append(f{img_name}: 坐标越界 - {line}) print(f通过: {ok_count} 张, 异常: {len(error_list)} 条) for e in error_list[:20]: print(e)这段脚本把目录、坐标范围、格式全查了一遍。它不会修标签只负责把问题列出来。看到输出里只有「通过」没有「异常」时就可以放心进入训练环节了。5. 避坑指南训练 YOLOv9 检测针织品瑕疵的 5 条血泪经验5.1 解压后找不到标签文件图全躺在根目录现象解压 zip 后同目录下只看到一堆 jpg没看到 txt 标签文件。 原因Roboflow 导出时如果选择「JPG YOLOv9 .txt」标签和图片是并排放在同一个目录的但某些非官方打包工具会把 txt 抽离到单独文件夹或者干脆漏打包。 解决先ls看一眼有没有任何 txt 文件。如果有但不在图片旁边做一个循环把 txt 挪到对应图片目录如果完全找不到检查 zip 里是否嵌套了一层子目录——很多打包的人会把整个数据集目录塞进 zip解压后多出一层路径标签其实在下一层。我一般解压后第一件事就是find . -name *.txt | head -5看标签在哪。5.2 训练时报错 label class index out of range现象训练刚开始就报IndexError: label class 5 out of range或者日志里大量 skip 样本。 原因标签 txt 文件里的类别 ID 超出了 data.yaml 里 nc 指定的范围。比如 nc 配置成 3但标签里出现了 class_id 4。Roboflow 导出的数据有时会保留原始数据集的全部类别编号而这份针织品数据集如果做过多轮合并类别编号可能有空洞——比如原数据集有 5 类删掉 2 类后余下的类别 ID 还是 0、2、4没有重排为 0、1、2。 解决用 2.2 的统计脚本先找出标签里实际出现的最大 class_id然后把所有 txt 里的类别 ID 重映射为连续编号。可以写个循环先读全部 ID 排序建立旧 ID 到新 ID 的映射字典再逐文件替换。这个操作是数据预处理里最枯燥但最重要的一步跳过它训练必翻车。5.3 训练 mAP 一直很低但 loss 下降正常现象训练到 50 轮box loss 和 obj loss 都降得挺好mAP0.5 却卡在 0.3 上下。 原因标签坐标系或者 letterbox 参数不匹配。YOLOv9 对训练图做了自适应缩放如果原图本身不是正方形代码会用灰色填充补边。问题是如果数据集里的标签坐标在导出时是按「填充后图片」计算的而训练时又做了一次填充坐标就双重偏移了。另一种常见原因是图片里有 EXIF 旋转信息OpenCV 默认不处理 EXIF导致图片被旋转后标注没跟着转。 解决打开几张图和标注人工比对确认框是整体偏移还是方向错。整体偏移的话把填充逻辑关掉改为直接 resize 到 640x640方向错的话预处理阶段用 PIL 先把 EXIF 旋转应用掉再喂给训练。用 cv2.imread 读图时cv2.IMREAD_IGNORE_ORIENTATION这个标志位要留心。5.4 训练时显存溢出CUDA out of memory现象train.py 启动后没跑几步直接报RuntimeError: CUDA out of memory。 原因batch-size 太大或者 img 尺寸设置太高也可能同时跑的其它进程占了显存。检测模型训练时除了模型参数还要缓存梯度、优化器状态、特征图这些累积起来比推理时显存占用高 5 到 10 倍。 解决先把 batch-size 砍到 8如果还炸就换 yolov9-ttiny 版本。再不行就把 img 从 640 降到 512——对针织品瑕疵这种目标512 输入通常也能有不错效果。注意一个细节--workers参数如果设得太大dataloader 会抢占 CPU 内存而不是显存但会拖慢 GPU 喂数据速度一般设成 4 或 8 就好。5.5 验证集 mAP 高但实测新图一塌糊涂现象valid 集 mAP0.5 到 0.9但拿产线新拍的照片测试漏检一大片。 原因这是典型的过拟合数据集而不是过拟合模型。训练集和验证集来自同一个拍摄批次光线、角度、颜色分布完全一致模型学到的是「这个相机拍出来的图长什么样」而不是「瑕疵长什么样」。 解决训练完成后强制要求自己用另一台设备或另一个时段拍的图片做测试。如果这份数据集里 test 目录的图片和 train 出自同一场景那就得自己额外收集一组样张来验证。所谓泛化能力不是看测试集分数而是看换场景后还灵不灵。我从那以后每次训完都是先跑一遍「完全没见过」的图片再谈部署。6. 让模型上线前更稳置信度阈值调优与瑕疵定位验证技巧6.1 置信度阈值和 NMS 参数该怎么试模型训练完导出权重后推理阶段有两个参数直接决定实际效果conf-thres 和 iou-thres。YOLOv9 的 detect.py 或自定义推理脚本里这两个默认值分别是 0.25 和 0.45。但对瑕疵检测场景来说漏检的代价远高于误检——瑕疵漏过去意味着次品流入市场多标几个框顶多多看几眼。python detect.py \ --weights runs/kni_defect/train_v1/weights/best.pt \ --source /path/to/test_images \ --conf-thres 0.15 \ --iou-thres 0.5 \ --save-txt \ --save-confconf-thres 从 0.25 降到 0.15 通常能多召回 10% 的细小瑕疵代价是误检增多。工业部署时的常见做法是设一个低置信度阈值做初筛再用规则过滤掉明显不合理的框——比如面积过小、长宽比异常的检测结果。为了让这个过滤不变成玄学逐张看推理输出、统计误检样本的特征是唯一靠谱的路。6.2 用热力图和错误样本定位模型短板YOLOv9 训练完会在 runs 目录下生成混淆矩阵和 PR 曲线这些图表对判断模型短板很有帮助。还有一个实操上更直接的办法把所有验证集图片的推理结果保存下来重点看 false negative 样本——那些有瑕疵但模型没框出来的图。把这些图按瑕疵类型归档观察是否有共同特征比如都是暗光环境、都是深色背景、或者瑕疵都偏小。import cv2 import torch import glob model torch.hub.load(WongKinYiu/yolov9, custom, runs/kni_defect/train_v1/weights/best.pt) model.conf 0.15 model.iou 0.5 for img_path in glob.glob(valid_images/*.jpg): results model(img_path) if len(results.xyxy[0]) 0: print(f未检出: {img_path}) else: for det in results.xyxy[0]: x1, y1, x2, y2, conf, cls det.tolist() print(f检出: {img_path} | 类别{int(cls)} | 置信度{conf:.2f} | 框大小{w}x{h})这个脚本本质是把模型在验证集上的输出打出来找漏检样本。如果发现大量漏检集中在很小尺寸的瑕疵上可以考虑把 img 输入尺寸提到 960 重新训练或者在数据增强里增加随机裁剪放大的概率。尺寸问题靠调参解决不掉得从输入分辨率和样本分布下手。另一个值得做的是把特征图可视化出来。YOLOv9 在 neck 和 head 之间有 GELAN 结构用 hook 方式把特征图接出来看模型在漏检样本上是否给出了低置信度的置信度图。如果特征图有明显的响应但最后被 NMS 压掉那就调 iou-thres如果特征图根本没响应说明模型确实没学到这个特征得回头补数据。6.3 导出 ONNX 与部署前的量化检查训练结束了真正上线前还有一步把 PyTorch 权重导出成 ONNX 格式做一次精度对齐验证。PyTorch 训练时的推理逻辑和 ONNX 部署后有时会出现微小差异主要来自算子融合和坐标解码方式。YOLOv9 官方仓库提供了 export.pypython export.py \ --weights runs/kni_defect/train_v1/weights/best.pt \ --include onnx \ --img 640 \ --device 0导出后拿同一张图分别跑 pt 版和 onnx 版对比检测框坐标和置信度差异应该在 0.01 以内。我见过有人跳过了这一步直接上生产环境结果 onnx 版漏检率高一截排查了半天才发现是导出时 opset 版本和推理框架不匹配导致的精度损失。从那以后我每次导出 onnx 后都强制走一遍「同一张图双版本对比」的验证流程确认框坐标和置信度一致后再交给部署组。这份针织品数据集也一样——训练只是起点能稳定检测才算真正完成。希望这些踩坑经验能让你少走几步弯路。本文还有配套的精品资源点击获取
返回列表