简介:本资源为谢韦尔钢材表面缺陷检测数据集,面向从事工业质检、缺陷识别与深度学习目标检测的开发者与研究人员,可用于训练和验证钢材表面缺陷检测模型。数据集同时提供Pascal VOC与YOLO两种标注格式,包含6666张jpg图片及一一对应的xml与txt标注文件,标注类别共4类:crack、patches、pitting、scratches,总标注框数达20017个,其中scratches与pitting样本较为丰富,适合开展多类别缺陷检测实验。压缩包为7z格式,共约2000个文件,以xml标注文件为主,另含一份使用前必读说明,整体大小约606.94MB,目录结构清晰,便于直接接入主流检测框架。目前已有1142人学习下载,可作为钢材缺陷检测课题的可靠数据基础,帮助读者快速搭建训练与评估流程。
1. 谢韦尔钢材缺陷检测数据集:6666 张 VOC+YOLO 双格式的落地价值
拿到一个钢材缺陷检测数据集,第一反应不该是「有多少张」,而是「标注格式能不能直接喂进训练管线」。谢韦尔钢材缺陷检测数据集给的是 6666 张、4 类别、VOC 与 YOLO 双格式并存,这个组合本身就说明它面向的是工业质检场景下的目标检测任务。钢材表面缺陷检测在产线上属于典型的少样本、高误检代价场景——漏检一块带裂纹的钢板,下游可能就是整批冲压件报废。所以这类数据集的核心价值不在图片数量,而在于类别定义是否贴近真实缺陷形态、标注框是否贴合缺陷边界、双格式是否省去你手写转换脚本的时间。
这份资源适合三类人:一是做工业质检方向、需要快速搭起 YOLO 训练基线验证算法改动的工程师;二是拿它做数据增强、损失函数对比实验的研究者;三是想跑通「VOC 标注 → YOLO 训练 → 推理验证」完整链路的新手。6666 张的体量不算大,单卡就能跑,但足够暴露数据加载、类别不平衡、标注噪声这些真实问题。下面按「先看清结构、再动手训练、最后避坑」的顺序拆开讲。
2. 数据集结构与 VOC/YOLO 双格式解析
2.1 目录组织与文件命名规律
解压后的目录通常遵循 VOC 的标准布局,同时附带一份 YOLO 格式的标签目录。常见做法是保留Annotations(XML)、JPEGImages(原图)、ImageSets/Main(划分文件)三件套,再额外给一个labels目录存放 YOLO 的 txt。先别急着训练,用几条命令把结构摸清楚,比盲目开跑省时间。
# 查看解压后的顶层结构,确认 VOC 与 YOLO 目录是否齐全 ls -lh ./severstal_defect/ # 统计图片数量,验证是否与简介的 6666 张一致 find ./severstal_defect/JPEGImages -type f \( -name "*.jpg" -o -name "*.png" \) | wc -l # 统计 XML 标注数量,正常应与图片数一一对应 find ./severstal_defect/Annotations -name "*.xml" | wc -l # 查看 YOLO 标签目录,确认每张图对应一个同名 txt ls ./severstal_defect/labels/ | head -20逻辑说明:图片数与 XML 数不一致,说明有图没标或标了没图,这是后续训练报KeyError或空标签的根源。参数上,find的-name用通配符兼容 jpg/png 混存的情况,工业数据集经常两种格式混着来。YOLO 标签目录里每个 txt 的文件名必须和图片主名严格一致,差一个下划线都会导致加载时找不到标签。
2.2 VOC XML 与 YOLO txt 的字段映射
VOC 的 XML 存的是绝对像素坐标xmin/ymin/xmax/ymax,YOLO 的 txt 存的是归一化后的class_id cx cy w h。两者转换的核心是除以图像宽高,并把类别名映射成从 0 开始的整数索引。下面这段脚本把 VOC 转 YOLO,同时生成classes.txt,这是训练前必须落地的第一步。
import os import xml.etree.ElementTree as ET # 类别顺序必须固定,训练和推理时索引要一致 CLASSES = ["defect_1", "defect_2", "defect_3", "defect_4"] class_to_id = {c: i for i, c in enumerate(CLASSES)} def voc_to_yolo(xml_path, img_w, img_h, out_path): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.findall("object"): cls_name = obj.find("name").text.strip() if cls_name not in class_to_id: continue # 跳过不在预定义类别里的标注,避免索引越界 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) # 归一化并转为中心点+宽高 cx = (xmin + xmax) / 2.0 / img_w cy = (ymin + ymax) / 2.0 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h lines.append(f"{class_to_id[cls_name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") with open(out_path, "w") as f: f.write("\n".join(lines))逻辑说明:CLASSES的顺序一旦定下就不能改,否则训练好的权重换一份classes.txt就全乱。归一化保留 6 位小数是 YOLO 官方推荐的精度,太少会丢框,太多没必要。continue那行是血泪经验——工业数据集常有标注员写了不在类别表里的名字,不跳过就会在训练时抛异常。参数上,img_w/img_h必须从对应图片读取,不能硬编码,因为数据集里图片尺寸可能不统一。
2.3 训练集/验证集划分与 data.yaml 配置
VOC 的ImageSets/Main里通常有train.txt和val.txt,但 YOLO 训练需要的是图片路径列表加一份data.yaml。如果数据集没给划分文件,就按 8:2 自己切,注意保持 4 个类别的分布均衡,别让某个类别在验证集里一张都没有。
import random from pathlib import Path img_dir = Path("./severstal_defect/JPEGImages") imgs = sorted([p.stem for p in img_dir.glob("*.jpg")]) random.seed(42) # 固定种子,保证每次划分一致,方便复现 random.shuffle(imgs) split = int(len(imgs) * 0.8) train_list, val_list = imgs[:split], imgs[split:] for name, lst in [("train", train_list), ("val", val_list)]: with open(f"./severstal_defect/{name}.txt", "w") as f: for stem in lst: f.write(f"./JPEGImages/{stem}.jpg\n")逻辑说明:random.seed(42)是复现实验的基本要求,不固定种子两次划分结果不同,指标没法对比。写进 txt 的是相对路径,配合data.yaml里的path字段使用。对应的data.yaml长这样:
path: ./severstal_defect train: train.txt val: val.txt nc: 4 names: ["defect_1", "defect_2", "defect_3", "defect_4"]参数说明:nc必须等于names的长度,写错会在构建检测头时报维度不匹配。names的顺序和前面CLASSES完全一致,这是整条链路对齐的锚点。
3. 用 YOLO 跑通训练:环境、命令与参数
3.1 环境配置与依赖安装
钢材缺陷检测对显存要求不算高,6666 张、4 类别,单张 24G 显存的卡跑 YOLOv8n 或 v8s 都够。环境上建议用 conda 隔离,避免和系统里的 torch 版本打架。常见做法是 Python 3.9 到 3.10,torch 2.x 配对应 CUDA。
# 创建独立环境,避免依赖冲突 conda create -n steel_defect python=3.10 -y conda activate steel_defect # 安装 ultralytics,它会自动拉取匹配的 torch pip install ultralytics # 验证环境,确认能识别到 GPU yolo checks逻辑说明:yolo checks会打印 CUDA 是否可用、torch 版本、GPU 型号。如果这里显示 CPU only,后面训练会慢到无法接受,先解决驱动和 CUDA 匹配问题再往下走。参数上,不建议手动pip install torch再装 ultralytics,版本对不上是新手最常见的翻车点,让 ultralytics 自己解析依赖更稳。
3.2 启动训练与关键参数含义
训练命令本身很短,但每个参数都影响结果。下面这条是能直接抄的基线配置。
yolo detect train \ data=./severstal_defect/data.yaml \ model=yolov8s.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=./runs/steel \ name=baseline逻辑说明:model=yolov8s.pt用的是 COCO 预训练权重,钢材缺陷和 COCO 类别不重叠,但底层边缘、纹理特征仍能迁移,比从零训练收敛快得多。imgsz=640是速度和精度的平衡点,缺陷如果特别小可以提到 1024,但显存占用翻倍。patience=20表示 20 轮指标不涨就早停,省时间。lr0=0.01是 SGD 的初始学习率,如果换成 AdamW 建议降到 0.001。batch=16在 24G 显存上跑 640 分辨率比较稳,爆显存就减半。
训练过程中重点看三个输出:box_loss是否稳定下降、mAP50是否在涨、cls_loss有没有异常震荡。cls_loss剧烈震荡通常意味着类别不平衡或标注里有大量空框。
3.3 推理验证与结果解读
训练完别只看最后的 mAP,拿几张验证集图片实际跑一遍,肉眼确认框的位置和类别对不对。
# 对验证集图片做推理,保存带框结果 yolo detect predict \ model=./runs/steel/baseline/weights/best.pt \ source=./severstal_defect/JPEGImages \ conf=0.25 \ save=True \ project=./runs/steel \ name=pred逻辑说明:conf=0.25是置信度阈值,工业质检场景通常宁可多报也别漏报,可以适当降到 0.15 观察召回。save=True会把画框后的图存下来,方便和原图对比。如果发现某类缺陷几乎没框出来,先回去查这个类别的标注数量,很可能是样本太少导致模型没学到。
结果解读上,mAP50看整体,mAP50-95看框的精度。钢材缺陷边界往往模糊,mAP50-95偏低是正常的,别一味追求这个指标而把框标得过紧,反而丢泛化。
4. 避坑与常见问题排查
4.1 解压 7z 报错但密码正确
现象:用7z x解压时提示密码错误,但确认密码没问题。原因多半是压缩包用了非 UTF-8 的文件名编码,或者分卷压缩没下全。解决:Linux 下先装p7zip-full,用7z x -p密码 -mcp=936 文件名.7z指定中文编码;如果是分卷,确认.001/.002都在同一目录再解压。Windows 下换 7-Zip 最新版,老版本对某些压缩算法支持不全。
4.2 训练时 BN 层崩溃或 loss 变 NaN
现象:训练几十轮后loss=nan,或者报 BN 相关错误。原因通常是学习率过大、batch 太小导致批统计量不稳,或者数据里有损坏图片。解决:先把lr0降到 0.001 试,再把batch提到 16 以上;同时用脚本扫一遍图片,把打不开的图剔除。钢材数据集里偶有截断的 jpg,加载时不一定报错,但会污染统计量。
4.3 类别索引错位导致全预测成同一类
现象:推理结果所有框都是同一个类别。原因:data.yaml的names顺序和生成 YOLO 标签时的CLASSES顺序不一致。解决:回头核对两处顺序,必须逐字一致。这个坑很隐蔽,因为训练不会报错,只是指标虚高。
4.4 验证集 mAP 虚高但实际漏检严重
现象:mAP50到 0.9 了,实际产线图却漏检。原因:训练集和验证集划分时没固定种子,或者验证集图片和训练集高度相似,等于变相泄漏。解决:固定random.seed,并尽量按时间或批次划分,别随机打散。工业数据尤其要注意,同一块钢板的多个视角不能分到训练和验证两边。
4.5 显存够但训练极慢
现象:GPU 利用率低,训练速度远低于预期。原因:数据加载成了瓶颈,workers设太小,或者图片存在机械硬盘上。解决:把workers提到 8,数据放 SSD,imgsz如果不是必须 640 可以先降到 416 验证流程通不通。
5. 进阶技巧:用混淆矩阵定位类别混淆
训练跑通只是起点,真正决定这份数据集能不能用于产线的是类别间的区分度。YOLO 训练完会在runs/steel/baseline/下生成confusion_matrix.png,这张图比 mAP 更能说明问题。横轴是预测类别,纵轴是真实类别,对角线越深越好,非对角线上的亮点就是混淆源。
我一般会先看两类:一是某个缺陷被大量预测成背景,说明召回不足,可能是标注框太小或该类别样本太少;二是两个缺陷类别互相混淆,说明它们的视觉特征在 640 分辨率下难以区分,这时候要么提高输入分辨率,要么在数据增强里加针对性的裁剪和旋转。钢材缺陷里裂纹和划痕经常混,靠调参解决不了,得回到标注层面确认边界定义是否清晰。
验证方法上,除了看混淆矩阵,还可以把val集里预测错误的样本单独抽出来,按错误类型分文件夹,人工过一遍。这一步很枯燥,但能发现标注本身的系统性错误——比如某个标注员把氧化皮全标成了夹杂。这类问题不解决,模型再调也是学错。
一个具体技巧:用yolo detect val时加save_json=True,导出 COCO 格式的预测结果,再用 pycocotools 按类别算 AP,比 YOLO 自带的汇总更细。这样能定位到具体是哪个类别拖了后腿,而不是只看一个总数。
从那以后我每次拿到新数据集,都强制先跑一遍混淆矩阵再决定要不要加数据或改标注,而不是一上来就调模型结构。希望帮到你。
本文还有配套的精品资源,点击获取