ARTICLE DETAIL

资讯详情

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

瓷砖缺陷分类数据集实战:从数据采集到模型部署全解析

瓷砖缺陷分类数据集实战:从数据采集到模型部署全解析 简介工业视觉缺陷检测是智能制造中的关键环节而图像分类技术作为核心算法之一通过深度学习模型对产品表面缺陷进行自动识别与分类能够大幅提升质检效率。在构建工业级分类数据集时需关注数据采集一致性、标注规范、类别定义与样本均衡性并配合数据增强、迁移学习等手段优化模型性能。本文以瓷砖质检场景为例系统梳理5种常见缺陷裂纹、崩边、针孔、麻面、色差的分类数据集构建流程涵盖数据划分、模型选型、训练调参、常见问题排查及ONNX/TensorRT部署实践并结合YOLOv8分类模式提供快速落地方案帮助开发者将深度学习分类模型高效应用于实际产线。 瓷砖质检这个场景在工业视觉里算是非常经典的落地项目了。我刚入行那会儿生产线上瓷砖缺陷检测还主要靠老师傅肉眼盯后来才开始慢慢转向基于深度学习的图像识别方案。这个项目标题——5种常见瓷砖缺陷分类数据集——看起来只是一个数据准备的工作但实际上它背后牵扯到的数据采集、标注规范、类别定义、模型选型、训练调参每一个环节都有不少坑。这篇文章我就围绕这套分类数据集的构建和使用把我实际做过的方案、踩过的坑、总结出来的经验完完整整分享出来。1. 项目整体设计与思路拆解1.1 为什么选这5类缺陷作为分类目标做瓷砖缺陷检测第一步不是急着找模型而是先定义清楚到底要分哪些类别。你翻几家瓷砖厂的质量检验标准会发现缺陷类型五花八门什么落脏、熔洞、坯裂、釉裂、缺角、波纹、色差加起来能有几十种。但实际生产线上真正高频出现、对产品等级判定影响最大的其实就那么几类。我这次定的是5类裂纹、崩边、针孔、麻面、色差。选择标准很简单——覆盖高频、形态差异足够明显、便于标注一致性控制。裂纹细线状方向不固定长度和深度变化大是导致瓷砖降级甚至报废最主要的原因。崩边边缘区域的块状缺损通常在切割或搬运环节产生形状相对规整。针孔釉面微小孔洞直径多在1毫米以内分布密度不均匀属于烧成阶段气泡破裂遗留。麻面表面粗糙局部区域光泽度下降通常由釉料配方或烧成温度异常引起呈现片状分布。色差同一批次或同一片砖内颜色不均匀涉及灰度或色相偏移对视觉一致性影响明显。这5类放在一起既涵盖了点状、线状、块状、面状四种几何形态也涵盖了浅色底、深色底、纹理底等不同背景条件作为训练集来说多样性足够。1.2 分类思路还是检测思路的选择很多人拿到这个需求第一反应是既然要识别缺陷为什么不直接上目标检测把每个缺陷框出来我的回答是看场景。这套数据集定位是“分类数据集”那核心逻辑就是——输入一张瓷砖图像输出5个类别中的一个或者加一个正常类共6类。这里有个关键点是每张图像只包含一种缺陷还是允许一张图包含多个缺陷同时出现如果允许混合缺陷分类任务的标签就变成多标签训练难度和评估复杂度都会提升。我这次采用单标签分类方案。理由很直接在生产节拍固定的流水线上检测系统通常会对每片瓷砖拍摄多张图像然后按区域或按单张图像做缺陷判定。如果一张图像里只有单一缺陷形态用分类模型做初筛速度快、精度高、易解释后续再配合检测模型做精确定位整个流程是清晰的两级架构。如果非要一步到位全用目标检测那就不是这个数据集要解决的问题了。1.3 数据集规模的确定逻辑图像识别模型的性能很大程度上取决于训练数据量和类内多样性。不是图多就一定好而是要看每个类别的变化是否覆盖充分。比如裂纹有直线型、弧线型、网状型有深色裂纹、浅色裂纹有在纯色砖上的有在仿古砖纹理上的——这些都要在数据里体现否则模型学到的只是“训练集裂纹的样子”。我这次的数据规模是每类1200张左右总共6000余张训练集、验证集、测试集按8:1:1划分。划分的时候有讲究同一片瓷砖拍摄的多张图像要放进同一个集合不能这边一张训练那张验证否则会造成数据泄漏评估结果虚高。表1数据规模规划缺陷类别训练集验证集测试集合计裂纹9601201201200崩边9601201201200针孔9601201201200麻面9601201201200色差9601201201200合计480060060060002. 核心细节解析与实操要点2.1 图像采集环境的一致性控制图像识别模型对采集环境极其敏感。同一个缺陷在光源角度、亮度、相机曝光时间不同的情况下拍出来特征分布会差异很大模型训练出来就可能“认生”。所以采集环节要模拟产线真实环境光源位置固定、色温恒定、拍摄角度垂直、曝光参数锁定。我遇到的典型问题是早期采集的一部分样本是在实验室环境拍的背景干净、光照均匀但产线现场拍的图片有粉尘、有震动模糊、光照有波动。两个来源的数据混在一起训练模型在验证集上表现还行一到产线实测准确率掉了十来个点。后来把产线数据单独抽出来做测试集问题立刻暴露了。实操建议采集时固定相机型号和参数不要多台相机混采后在标注时不记录来源建议至少采集3个不同批次的产品覆盖不同釉色和纹理光照明暗变化通过数据增强模拟不要依赖现场补拍2.2 标注规范与质量管控数据集的灵魂在标注质量。分类任务虽然只标注一个类别标签看起来简单但缺陷类别的边界判断非常容易产生分歧。比如一条很短的裂纹它算裂纹还是算瑕疵品一个直径不到0.5毫米的凹陷算针孔还是麻面我制标注规范的时候几条硬性规定如下裂纹必须长度大于5毫米或贯穿多个纹理周期短于该阈值的线性缺陷不计入崩边必须是边缘区域距离边界3毫米内的缺损内部缺损不算针孔限定为直径1毫米以内的单个凹陷超过1毫米按麻面处理麻面要求成片区域面积占比超过瓷砖表面的5%色差以人眼可辨识为标准并通过像素统计确认灰度偏差大于设定阈值这些规则不是拍脑袋定的而是和工厂质检负责人反复对齐后的结果。标注人员也要经过培训和考试保证不同人对同一种情况的判断一致。2.3 标注工具与格式转换分类数据集标注相对简单不需要画框、画多边形只需要把图像按类别放入不同文件夹或者维护一个CSV映射表。我推荐的做法是目录即标签train/crack/xxx.jpg、train/chip/xxx.jpg这样后续切换PyTorch的ImageFolder、Keras的flow_from_directory、YOLO的分类模式都非常方便。不过考虑到很多实际项目后面会升级到目标检测我建议即使是分类项目也顺手把关键缺陷的边界框标注一起做了用LabelImg或X-AnyLabeling都可以。多花一点标注时间后续切换到目标检测的时候就不用重新标注了。这个经验是从一个真实项目里学到的——前期只做了分类年底客户说要缺陷定位整个数据集重新标了一遍痛苦至极。标注格式如果后续需要兼容YOLO文件夹结构可以这样组织dataset/ ├── images/ │ ├── train/ │ │ ├── crack/ │ │ ├── chip/ │ │ ├── pinhole/ │ │ ├── blister/ │ │ └── color_diff/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ └── val/ └── classes.txt2.4 数据增强策略选择6000张图像对深度学习来说不算多尤其CNN模型参数量大容易过拟合。数据增强是最好的“免费数据扩充”手段。但不是所有增强方式都适合瓷砖缺陷这是很多人容易踩坑的地方。比如随机旋转90度对大多数场景没问题但如果瓷砖有方向性纹理旋转后语义就变了再比如水平翻转对于裂纹这种方向敏感特征确实能增加方向多样性但过度翻转可能导致模型对真实缺陷方向产生误判。我在这个项目中采用的增强组合如下随机水平翻转 垂直翻转概率0.5随机旋转范围0到30度配合旋转后裁剪避免黑边随机亮度调整系数0.8到1.2随机对比度调整系数0.8到1.2随机高斯噪声标准差0.005CutMix/MixUp概率0.3用于提升泛化能力还要注意一点验证集和测试集绝对不能做增强。增强只用于训练过程否则评估结果失真。3. 实操过程与核心环节实现3.1 环境准备与依赖安装训练这套分类模型硬件配置不需要特别夸张一张8GB显存的GPU就能跑起来。我用的环境是Ubuntu 22.04 PyTorch 2.1 CUDA 11.8显卡是RTX 3060 12GB。如果只有CPU也能跑一个Epoch可能要几分钟总训练时间会长很多但逻辑完全一样。安装关键依赖pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install numpy pandas matplotlib opencv-python scikit-learn tqdm这里有个小提示torchvision的版本和torch必须匹配。如果后续要转换模型到TensorRT加速CUDA版本最好和部署环境一致不要图省事装了最新版后面部署时才发现不兼容又得重新配环境。3.2 数据加载与预处理用PyTorch实现分类任务的数据加载通常用torchvision.datasets.ImageFolder最简单。但在工业场景里还要在预处理阶段多做几步统一图像尺寸、归一化、通道顺序确认。瓷砖图像的原图分辨率通常很高4000x3000很常见。直接送到网络里不现实我先把图像统一缩放到224x224对模型识别微小缺陷如针孔会有影响所以实际项目中用了512x512。Timm库中很多预训练模型支持任意输入尺寸在创建模型时设置好即可。数据加载代码import torch from torchvision import datasets, transforms from torch.utils.data import DataLoader train_transform transforms.Compose([ transforms.Resize((512, 512)), transforms.RandomHorizontalFlip(p0.5), transforms.RandomVerticalFlip(p0.5), transforms.RandomRotation(degrees15), transforms.ColorJitter(brightness0.2, contrast0.2), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) val_transform transforms.Compose([ transforms.Resize((512, 512)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) train_dataset datasets.ImageFolder(rootdataset/images/train, transformtrain_transform) val_dataset datasets.ImageFolder(rootdataset/images/val, transformval_transform) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue, num_workers8) val_loader DataLoader(val_dataset, batch_size32, shuffleFalse, num_workers8)注意mean和std用的是ImageNet统计值。如果你的数据集和ImageNet分布差异大建议自己在训练集上计算均值和标准差效果会更好尤其是色差这类颜色敏感的缺陷。3.3 模型选型ResNet、EfficientNet还是VGG分类任务可选的模型很多我实测对比过几款模型参数量单张推理耗时(ms)验证集准确率备注ResNet5025.6M1296.8%经典稳定部署友好ResNet1811.7M895.2%轻量适合边缘设备EfficientNet-B312.3M1597.4%精度高但部署稍麻烦MobileNetV34.2M693.6%适合移动端精度略低VGG16138M2295.8%参数量大不推荐选择模型时除了精度还要看推理速度和部署难度。如果产线用GPU服务器ResNet50是不错的选择如果要上边缘盒子选择MobileNetV3或EfficientNet-Lite更合适如果只有CPU环境那MobileNetV3是首选。实际项目里我最后选了ResNet50搭配迁移学习。理由精度足够、对GPU推理引擎支持完善、踩坑资料最多、后续做剪枝量化的技术路线成熟。追求极致的可以用EfficientNet-B3但量化部署时会遇到一些自定义算子兼容性问题调试成本高一些。3.4 训练过程与关键参数解析迁移学习是最合理的起点。使用ImageNet预训练权重能大幅缩短收敛时间防止过拟合。关键是冻结部分层的策略和超参数调整。训练代码核心部分import torch.nn as nn import torch.optim as optim from torchvision import models from timm import create_model # 使用timm创建模型支持更多预训练权重 model create_model(resnet50, pretrainedTrue, num_classes6) # 修改分类头 model.reset_classifier(6) # 冻结特征层参数 for param in model.parameters(): param.requires_grad False # 只训练最后的分类头 for param in model.get_classifier().parameters(): param.requires_grad True # 或者用渐进解冻策略 # 先训练分类头几个epoch再解冻最后两层 criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.get_classifier().parameters(), lr1e-3) scheduler optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max30)训练50个epoch前10个epoch冻结特征层只训练分类头后面40个epoch解冻全部参数使用更小的学习率微调。初始学习率设为1e-4并使用余弦退火调度。这里我给一个完整的训练脚本模板import torch import torch.nn as nn import torch.optim as optim from tqdm import tqdm from sklearn.metrics import confusion_matrix, classification_report def train_one_epoch(model, train_loader, criterion, optimizer, device): model.train() running_loss 0.0 correct 0 total 0 for images, labels in tqdm(train_loader, descTraining): images, labels images.to(device), labels.to(device) optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() * images.size(0) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() epoch_loss running_loss / total epoch_acc correct / total return epoch_loss, epoch_acc def validate(model, val_loader, criterion, device): model.eval() running_loss 0.0 correct 0 total 0 all_preds [] all_labels [] with torch.no_grad(): for images, labels in tqdm(val_loader, descValidating): images, labels images.to(device), labels.to(device) outputs model(images) loss criterion(outputs, labels) running_loss loss.item() * images.size(0) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() all_preds.extend(predicted.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) epoch_loss running_loss / total epoch_acc correct / total return epoch_loss, epoch_acc, all_preds, all_labels device torch.device(cuda if torch.cuda.is_available() else cpu) model create_model(resnet50, pretrainedTrue, num_classes6).to(device) criterion nn.CrossEntropyLoss() optimizer optim.AdamW(model.parameters(), lr1e-4, weight_decay5e-4) scheduler optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max50) best_acc 0.0 for epoch in range(50): train_loss, train_acc train_one_epoch(model, train_loader, criterion, optimizer, device) val_loss, val_acc, preds, labels validate(model, val_loader, criterion, device) scheduler.step() print(fEpoch {epoch1:3d}/{50} | Train Loss: {train_loss:.4f} | Train Acc: {train_acc:.4f} | Val Loss: {val_loss:.4f} | Val Acc: {val_acc:.4f}) if val_acc best_acc: best_acc val_acc torch.save(model.state_dict(), best_model.pth)3.5 类权重处理如果数据集中各类别样本数量不均衡或者某种缺陷的漏检代价大于误检就需要调整损失函数的权重。瓷砖缺陷场景下裂纹漏检是最严重的所以我会适当提高裂纹类别的损失权重。class_weights torch.tensor([1.5, 1.0, 1.0, 1.2, 1.0]).to(device) criterion nn.CrossEntropyLoss(weightclass_weights)权重的设置需要结合业务逻辑和生产数据中各类缺陷的实际频率。如果某一类缺陷在生产中极少出现但在质检中一旦漏掉会造成重大客诉那这个类别需要更高的权重。这里要在实验基础之上定量分析不能全凭感觉。4. 常见问题与排查技巧实录4.1 模型严重过拟合怎么办症状训练集准确率接近100%验证集准确率只有85%左右而且每个epoch验证集的指标波动很大。排查步骤检查数据划分是否泄漏——同一片瓷砖的图像是否被同时分到训练集和验证集检查增强策略是否足够强——试试更激进的CutMix、RandAugment检查模型的Dropout和权重衰减——ResNet50默认没有Dropout可以在分类头前加一个Dropout层检查学习率是否过大——过大的学习率会导致模型记住训练集中的噪声模式实际项目中我曾经调试一个模型过拟合严重怎么调都降不下来最后发现问题是数据划分时用了随机划分导致同一片瓷砖的多张图像同时出现在训练集和验证集。重新按瓷砖ID划分之后问题立刻解决。4.2 针孔和麻面分类混淆严重这个问题非常典型。针孔和麻面在形态上确实有重叠尤其是密集针孔区域视觉上跟麻面很相似。我在项目中的处理方式是回到数据层面重新审视标注规范把两类缺陷的判定规则更加明确化增加高分辨率的局部特征提取分支在训练时对图像的关键区域进行裁剪放大引入注意力机制让模型更关注微小的局部纹理差异最终帮助最大的是用EfficientNet替换ResNet。EfficientNet使用更细粒度的缩放策略在微小纹理差异的捕捉上更敏感混淆率从12%降到了7%。4.3 色差类缺陷在灰度图像上看不出来如果是灰度相机拍摄的图像色差问题确实很难通过RGB信息来识别。这种情况下要么换成彩色相机重新采集数据要么在预处理阶段做颜色特征提取。我的建议是色差缺陷检测尽量使用彩色相机。如果条件不允许可以使用HSV颜色空间的色相和饱和度通道作为辅助输入。具体的做法是把RGB图像转为HSV取H和S通道作为额外通道和灰度图拼接成三通道输入模型。4.4 推理速度不达标产线对检测速度有硬性要求每片瓷砖的检测时间通常不能超过几百毫秒。如果模型推理耗时超过限制有以下几个优化手段模型轻量化用MobileNetV3、EfficientNet-Lite或者对ResNet50做通道剪枝输入尺寸降级从512x512降到384x384精度损失通常在1到2个百分点以内TensorRT加速FP16精度推理能将速度提升2到3倍INT8量化能提升3到5倍ONNX Runtime支撑多线程和批处理推理我实际做过的一个项目里ResNet50用TensorRT FP16推理在Jetson Xavier上单张图像推理时间从28毫秒降到9毫秒完全满足产线节拍要求。4.5 标注规范不一致导致模型学习混乱多人参与标注时容易出现同一类缺陷有的人标裂纹有的人标麻面的情况。这种情况对模型的影响极其隐蔽——训练集标注噪声高模型学到的决策边界会被拉偏验证集准确率虚高但实际效果差。解决方案标注完成后做二次审核随机抽20%人工复核训练后用模型预测结果和标注结果做交叉比对找出不一致的样本如果模型在某个类别的置信度高但标注标签不同大概率是标注问题4.6 类别定义完整性问题项目初期定义5类缺陷模型训练完成后上线不久就遇到一种从未见过的缺陷类型。模型会把所有没见过的东西强行分到已知类别里的某一类造成误判。这是封闭集分类的固有问题。解决办法是加一个“正常”类别让模型至少能区分“有没有问题”然后再考虑“是什么问题”。更进一步的做法是引入异常检测机制——先用自编码器学习正常样本的表征当输入图像的重构误差超过阈值时直接判定为“未知缺陷”再交给分类模型处理。5. 部署与工程化实践5.1 模型导出与格式转换训练好的PyTorch模型要部署到生产环境通常需要先导出为通用格式。我推荐ONNX作为中间格式再根据目标推理引擎转换成TensorRT或其他格式。导出代码import torch import onnx import onnxruntime as ort model.load_state_dict(torch.load(best_model.pth)) model.eval() dummy_input torch.randn(1, 3, 512, 512) torch.onnx.export( model, dummy_input, tile_defect.onnx, export_paramsTrue, opset_version13, do_constant_foldingTrue, input_names[input], output_names[output], dynamic_axes{input: {0: batch_size}, output: {0: batch_size}} ) # 验证ONNX模型 ort_session ort.InferenceSession(tile_defect.onnx) outputs ort_session.run(None, {input: dummy_input.numpy()})动态轴配置允许推理时改变batch size但如果部署时只用单batch推理可以去掉dynamic_axes部分推理引擎对静态shape优化更好。5.2 推理服务与接口设计生产环境部署推荐使用FastAPI封装推理服务。核心代码from fastapi import FastAPI, UploadFile, File import numpy as np import cv2 import onnxruntime as ort app FastAPI() ort_session ort.InferenceSession(tile_defect.onnx) def preprocess(image_bytes: bytes): nparr np.frombuffer(image_bytes, np.uint8) img cv2.imdecode(nparr, cv2.IMREAD_COLOR) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (512, 512)) img img.astype(np.float32) / 255.0 mean np.array([0.485, 0.456, 0.406], dtypenp.float32) std np.array([0.229, 0.224, 0.225], dtypenp.float32) img (img - mean) / std img np.transpose(img, (2, 0, 1)) img np.expand_dims(img, axis0) return img app.post(/predict) async def predict(file: UploadFile File(...)): image_bytes await file.read() input_tensor preprocess(image_bytes) outputs ort_session.run(None, {input: input_tensor}) probabilities softmax(outputs[0][0]) predicted_class np.argmax(probabilities) confidence probabilities[predicted_class] return { class: class_names[predicted_class], confidence: float(confidence), probabilities: probabilities.tolist() }接口设计要考虑生产环境的需求需要记录日志每个请求的耗时、返回结果和置信度要存储方便后续做模型监控和迭代。需要加一层缓存机制相同图像重复请求直接返回结果不重复推理。5.3 边缘设备部署如果产线没有GPU服务器需要部署到边缘设备上。目前工业上主流的边缘计算设备包括Jetson系列设备、各类RK3588盒子等。整体部署逻辑类似但要注意设备内存和算力限制。我踩过的坑在Jetson上部署ONNX模型直接用CPU模式推理速度只有几个FPS后来启用TensorRT加速才把性能提上来。如果边缘设备是英伟达平台建议直接导出TensorRT引擎不要走ONNX Runtime再转一层。TensorRT导出流程简述trtexec --onnxtile_defect.onnx \ --saveEnginetile_defect_fp16.engine \ --fp16 \ --workspace4096转换完成后在Jetson上加载.engine文件推理速度提升明显。6. 基于YOLOv8的分类路径补充如果只是做分类任务上面的PyTorch方案已经完全够用。不过很多读者在搜“yolov8训练自己的数据集”我就在这里再补充一种方案用YOLOv8的分类模式做瓷砖缺陷分类。YOLOv8的detect模块广为人知但它的classify模式同样好用训练流程比自写方案简单得多。# 训练分类器 yolo classify train datadataset/ modelyolov8s-cls.pt epochs50 imgsz512 batch32 # 验证 yolo classify val modelruns/classify/train/weights/best.pt datadataset/ # 推理 yolo classify predict modelruns/classify/train/weights/best.pt sourcetest.jpg目录结构要求如下dataset/ ├── train/ │ ├── crack/ │ ├── chip/ │ ├── pinhole/ │ ├── blister/ │ └── color_diff/ └── val/ ├── crack/ ├── chip/ ├── pinhole/ ├── blister/ └── color_diff/YOLOv8s精度在类似数据集上已经不错实测能达到96%左右。如果精度还不够换yolov8m或yolov8l。训练的日志和指标曲线自动保存非常方便。我个人的对比结论是YOLOv8分类模式适合快速验证和工程落地代码量小、流程自动化。但如果你想做更深度的定制——比如自定义损失函数、多分支网络、注意力机制嵌入——还是用PyTorch方案更灵活。两者并不冲突先跑YOLOv8拿到Baseline再上PyTorch微调效率最高。7. 数据集迭代与模型持续优化7.1 困难样本挖掘模型上线之后不代表工作就结束了。持续收集误判样本、标注、补充训练是保证模型在生产环境中长期稳定的关键。我通常是这么做的每月从产线收集所有预测置信度低于0.85的样本质检人员人工复核这些低置信度样本将确认的新样本按类别加入训练集定期增量训练每次增量训练后用固定测试集回归测试确保没有类别退化7.2 测试集管理测试集要作为“压箱底”的数据不能频繁变动。每次模型迭代都用同一个测试集做最终效果评估才能公平对比不同版本模型的优劣。如果测试集长期不更新可能和实际生产数据的分布产生漂移建议每季度从新增数据中抽取一批样本更新测试集同时保留上一版测试集做对比确保评估连续性。7.3 数据版本管理深度学习项目很大一个痛点就是数据和模型版本混乱。训练了一个新模型想复现上次的效果结果发现数据集已经被更新过训练结果对不上。推荐用DVC做数据版本管理或者至少把数据集上传到NAS后按日期和版本号命名目录。我习惯用下面的命名规范dataset/tile_defect_v1.0_20250115/ dataset/tile_defect_v1.1_20250301/ dataset/tile_defect_v2.0_20250601/模型权重同样规范管理训练脚本、配置参数、数据集版本、训练日志打成一套存到固定目录。这样任何一个版本出了问题都能追溯回当时的环境。8. 实操总结与经验沉淀做这套瓷砖缺陷分类数据集的完整流程走下来我最深的体会是深度学习模型训练只是整个项目最后一步前面数据采集、标注规范、验证集设计才是决定成败的关键。实际项目里模型选型那一步通常半天就能定训练调参一周内也能完成但数据采集和标注花了将近一个月。而且前期的数据和标注质量直接决定了后期模型精度的上限。用一句话总结标注规范和验证集划分这两个环节前期打磨得越好后面省下的时间越多。再分享一个具体的小技巧训练前先跑一个包含10个epoch的“冒烟测试”只取少量数据验证整条训练流程是否跑通检查数据加载器是否有问题、类别映射是否正确、代码有没有隐藏的Bug。这个冒烟测试不会花太多时间但能避免你启动一个完整训练后才发现代码问题白等一两个小时。按照这套流程下来分类模型在5类缺陷上的准确率能做到96%以上。如果后续有定位需求分类数据和检测标注可以复用迁移成本不高这是我在项目开始就规划好的也建议你考虑进去。本文还有配套的精品资源点击获取
返回列表