热轧带钢表面缺陷数据集:从分类目录到YOLOv8检测训练全流程

发布时间:2026/10/6 3:08:05
热轧带钢表面缺陷数据集:从分类目录到YOLOv8检测训练全流程 简介东北大学热轧带钢表面缺陷数据集面向材料、冶金与机器视觉方向的研究人员和学生用于热轧带钢表面缺陷的识别与分类研究可支撑深度学习模型训练与工业质检算法验证。压缩包为7z格式共2000个文件包含1800张jpg图像与1800个xml标注文件整体约251.02MB图像覆盖裂纹、氧化皮、夹杂、凹坑等典型缺陷xml文件提供对应目标框与类别标注可直接用于监督学习与目标检测任务。目前已有1333人学习下载适合作为缺陷检测课题、课程设计或论文实验的数据基础。读者可据此构建训练集、验证集与测试集开展图像预处理、数据增强与卷积神经网络训练并对比不同模型在缺陷分类与定位上的表现从而掌握从数据标注解析到模型评估的完整流程为产线自动化质检提供可复用的实验素材。1. 热轧带钢表面缺陷数据集从压缩包到可用训练集的第一步拿到一个名为东北大学热轧带钢表面缺陷数据集.7z的压缩包解压后看到一堆crazing_50.jpg、crazing_270.jpg这样的文件很多人第一反应是「就这」——没有标注文件、没有划分脚本、没有说明文档只有图片。但如果你正在做工业质检方向的缺陷检测或者想找一个真实产线场景的数据集来跑通yolov8训练自己的数据集全流程这个包的价值恰恰在于它的「原始」。它对应的是东北大学公开的 NEU-DET 热轧带钢表面缺陷数据包含六类典型缺陷crazing裂纹、inclusion夹杂、patches斑块、pitted_surface麻点、rolled-in_scale氧化皮压入、scratches划痕。每类若干张灰度图分辨率不高但缺陷纹理真实适合用来验证小样本条件下的分类与检测方案。这份资源适合两类人一是想快速搭一个缺陷检测 demo 的工程师二是需要真实工业图像做算法对比的研究者。它不提供现成的 YOLO 格式标签所以你得自己走一遍「分类目录 → 检测标注 → 训练配置」的链路而这正是本文要拆清楚的部分。2. 数据集结构与六类缺陷的物理含义为什么不能直接拿来训检测模型2.1 目录组织与文件命名规律解压后的目录通常长这样一个总文件夹下按缺陷英文名分子文件夹每个子文件夹里是若干.jpg。文件名格式为类别名_编号.jpg编号不连续说明原始采集时做过筛选。以crazing为例你看到的crazing_50.jpg、crazing_270.jpg、crazing_48.jpg只是冰山一角完整六类加起来约 1800 张左右。这种「按类分目录」的结构天然适合做图像分类任务torchvision.datasets.ImageFolder可以直接读取。但如果你想做目标检测问题就来了没有边界框坐标没有 XML 或 JSON 标注模型无法知道缺陷在图像中的具体位置。常见做法是两条路第一条把它当分类数据集用训练一个 CNN 分类器推理时用滑动窗口或整图分类第二条自己补标注用 LabelImg 或 CVAT 画框转成 YOLO 格式。第一条路快但只能告诉你「这张图有没有缺陷、是哪类」不能定位第二条路慢但能落地产线做实时报警。我一般会先走第一条路验证特征可分性再决定要不要投入标注成本。2.2 六类缺陷的视觉特征与混淆风险这六类缺陷在灰度图上的表现差异很大但有两组特别容易混缺陷类别英文名典型视觉特征易混淆项裂纹crazing细密网状、方向不规则划痕走向更单一夹杂inclusion块状暗斑、边界模糊斑块面积更大斑块patches不规则亮/暗区域氧化皮压入麻点pitted_surface密集小凹坑、点状氧化皮压入氧化皮压入rolled-in_scale条带状、沿轧制方向划痕划痕scratches直线状、平行排列裂纹提示如果你只做分类建议先把crazing和scratches的混淆矩阵单独拉出来看这两类在低分辨率下误判率最高。2.3 为什么必须做训练/验证/测试划分原始包没有划分文件如果你直接把所有图丢进训练集评估结果会虚高。常见做法是按 7:2:1 或 8:1:1 分层抽样保证每类在三个子集中的比例一致。下面这段脚本可以直接用它按类别建目录、复制文件并输出划分统计import os import shutil import random from pathlib import Path # 原始解压目录按类别分子文件夹 src_root Path(NEU-DET) # 输出目录 dst_root Path(NEU-DET-split) # 划分比例 ratios {train: 0.7, val: 0.2, test: 0.1} random.seed(42) for cls_dir in src_root.iterdir(): if not cls_dir.is_dir(): continue cls_name cls_dir.name imgs list(cls_dir.glob(*.jpg)) random.shuffle(imgs) n len(imgs) n_train int(n * ratios[train]) n_val int(n * ratios[val]) splits { train: imgs[:n_train], val: imgs[n_train:n_train n_val], test: imgs[n_train n_val:] } for split, files in splits.items(): out_dir dst_root / split / cls_name out_dir.mkdir(parentsTrue, exist_okTrue) for f in files: shutil.copy2(f, out_dir / f.name) print(f{cls_name}: total{n}, train{len(splits[train])}, val{len(splits[val])}, test{len(splits[test])})逻辑说明random.seed(42)保证每次划分结果一致方便复现shutil.copy2保留原文件元信息按类别分别划分而不是全局打乱是为了避免某类在验证集中完全缺失。参数方面ratios可以根据你的数据量调整如果某类样本少于 200 张建议改成 8:1:1把更多数据留给训练。3. 从分类目录到 YOLO 检测格式标注转换与配置文件写法3.1 标注工具选择与 YOLO 格式要求如果你决定走检测路线下一步是标注。LabelImg 是最轻量的选择输出 Pascal VOC XMLCVAT 支持多人协作和视频帧标注适合团队。YOLO 需要的标签格式是每张图对应一个.txt每行class_id x_center y_center width height全部归一化到 0~1。假设你已经用 LabelImg 标好了 XML下面这个脚本把 XML 批量转成 YOLO txtimport xml.etree.ElementTree as ET from pathlib import Path # 类别名到 id 的映射按你的实际类别顺序改 class_map { crazing: 0, inclusion: 1, patches: 2, pitted_surface: 3, rolled-in_scale: 4, scratches: 5 } def convert(xml_path, txt_path, img_w, img_h): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_map: 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) # 归一化中心点和宽高 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{class_map[cls_name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) txt_path.write_text(\n.join(lines)) # 遍历所有 XML假设图片尺寸已知或从 XML 的 size 节点读取 for xml_file in Path(annotations).glob(*.xml): tree ET.parse(xml_file) size tree.getroot().find(size) w int(size.find(width).text) h int(size.find(height).text) txt_file Path(labels) / (xml_file.stem .txt) convert(xml_file, txt_file, w, h)参数说明class_map的顺序必须和你的data.yaml里names列表一致否则训练时类别会错位x_center等归一化计算前要确认img_w、img_h是原图尺寸不是缩放后的。常见翻车点是 XML 里size节点缺失这时候得用 OpenCV 读图补上。3.2 data.yaml 与训练入口配置YOLOv8 的训练配置集中在data.yaml路径、类别数、类别名三样必须对path: /home/user/NEU-DET-yolo train: images/train val: images/val test: images/test nc: 6 names: [crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches]注意path用绝对路径最稳相对路径在不同工作目录下容易找不到图nc必须等于names长度多一个少一个都会在训练启动时报错。启动训练的命令行yolo detect train datadata.yaml modelyolov8n.pt epochs100 imgsz640 batch16yolov8n.pt是轻量模型适合先跑通流程imgsz640对这批低分辨率图偏大可以降到 320 或 416 节省显存batch16在 8G 显存下比较安全。如果你用yolov5训练自己的数据集把yolo detect train换成python train.py --data data.yaml --weights yolov5n.pt即可参数含义类似。3.3 数据增强策略与灰度图处理这批图是灰度图但 YOLO 默认按三通道读入会在训练时自动复制通道不影响使用。增强方面mosaic和mixup对小样本有帮助但crazing的细密纹理容易被mosaic拼接后变得更碎建议对这类别降低增强强度。常见做法是在data.yaml同级加一个hyp.yaml把mosaic: 0.5、mixup: 0.1调低然后训练时用--hyp hyp.yaml指定。4. 避坑与排查标注、路径、显存三类高频翻车记录4.1 现象训练 loss 不降mAP 始终为 0原因标签文件里的类别 id 和data.yaml的names顺序不一致或者标签文件根本没被读到。YOLO 在找不到对应.txt时会静默跳过该图导致有效训练样本极少。解决先跑一遍yolo detect train ... epochs1看日志里train: Scanning ... images, ... backgrounds的数字是否和你的图片总数吻合。如果差很多检查labels目录是否和images目录同级、文件名是否一一对应。4.2 现象报错FileNotFoundError: No such file or directory: images/train原因data.yaml里的path和train拼接后路径不对。YOLO 会把path和train用/拼起来如果你path末尾带了/或者train开头带了/都会出问题。解决path写绝对路径且末尾不加斜杠train写相对路径且开头不加斜杠。改完用python -c from ultralytics import YOLO; YOLO(yolov8n.pt).train(datadata.yaml, epochs1)快速验证。4.3 现象CUDA out of memorybatch 降到 4 还是炸原因imgsz设得太大或者workers太多导致内存泄漏。这批图原始分辨率不高但 YOLO 会统一 resize 到imgsz设 640 时显存占用远高于 320。解决先把imgsz降到 320batch设 8workers设 2。如果还炸检查是不是同时开了其他占显存的进程。我一般会在训练前nvidia-smi看一眼确认没有残留进程。4.4 现象验证集 mAP 很高但测试集一塌糊涂原因划分时没有分层抽样某类缺陷在测试集中占比过高或过低导致评估偏差。另外如果同一张图的增强版本同时出现在训练和验证集也会造成信息泄漏。解决用第 2 章的分层划分脚本重新生成数据集确保每类在三个子集中的比例一致。增强只在训练时做验证和测试不做增强。4.5 现象推理时把正常区域也框出来置信度还很高原因训练集中负样本无缺陷图太少或没有模型没学会「背景」这个概念。NEU-DET 原始数据全是缺陷图没有正常样本。解决从产线或公开数据里找一些无缺陷的热轧带钢图作为背景类加入训练集标签文件留空即可。YOLO 会把空标签文件当作负样本处理能显著降低误检。5. 进阶用法用预训练特征做小样本分类与产线部署验证如果你不想花时间标注但又想快速验证这批数据能不能区分六类缺陷可以用预训练 CNN 提取特征 线性分类器。下面这段代码用torchvision的 ResNet18 做特征提取再训一个 LogisticRegressionimport torch import torchvision.models as models import torchvision.transforms as T from torch.utils.data import DataLoader from torchvision.datasets import ImageFolder from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report import numpy as np # 用 ImageFolder 读取划分好的训练集和验证集 train_ds ImageFolder(NEU-DET-split/train, transformT.Compose([ T.Grayscale(num_output_channels3), T.Resize((224, 224)), T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])) val_ds ImageFolder(NEU-DET-split/val, transformT.Compose([ T.Grayscale(num_output_channels3), T.Resize((224, 224)), T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])) train_loader DataLoader(train_ds, batch_size32, shuffleFalse) val_loader DataLoader(val_ds, batch_size32, shuffleFalse) # 加载预训练 ResNet18去掉最后的全连接层 model models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1) model.fc torch.nn.Identity() model.eval() device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device) def extract_features(loader): feats, labels [], [] with torch.no_grad(): for imgs, lbls in loader: imgs imgs.to(device) out model(imgs) feats.append(out.cpu().numpy()) labels.append(lbls.numpy()) return np.concatenate(feats), np.concatenate(labels) X_train, y_train extract_features(train_loader) X_val, y_val extract_features(val_loader) clf LogisticRegression(max_iter1000, multi_classmultinomial) clf.fit(X_train, y_train) y_pred clf.predict(X_val) print(classification_report(y_val, y_pred, target_namestrain_ds.classes))逻辑说明model.fc torch.nn.Identity()把 ResNet18 的分类头换成恒等映射输出 512 维特征向量shuffleFalse是为了让特征和标签顺序对应后面 sklearn 直接按顺序训练。参数方面max_iter1000保证收敛multi_classmultinomial对多分类更稳。这套流程在 NEU-DET 上通常能跑到 90% 以上的验证准确率说明预训练特征对这批缺陷图有足够的区分度。验证方法上我习惯在训练完成后抽 20 张验证集图片用model.predict跑一遍把预测框画到原图上肉眼确认有没有明显漏检或误检。这一步比看 mAP 数字更直观尤其是crazing这种细密纹理mAP 高不代表框得准。从那以后我每次拿到新的工业图像数据集都会先跑一遍「分层划分 → 预训练特征分类 → 小样本检测」这条链路确认数据本身可分、标注格式无误再投入大规模训练。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询