ARTICLE DETAIL

资讯详情

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

煤矸石识别数据集与YOLOv8训练实战:从标注到部署避坑指南

煤矸石识别数据集与YOLOv8训练实战:从标注到部署避坑指南 简介煤矸石识别数据集面向煤矿智能化与选煤场景提供基于现场采集原始图片的煤炭、煤矸石、高岭石三类目标标注数据采用YOLOv8格式组织可供目标检测模型训练、微调与算法对比验证使用适合具备一定深度学习基础的开发者和矿业智能化研究人员。压缩包共205个文件、2.26MB含102张jpg现场图片、102个同名txt标注文件及1个yaml配置文件其中txt文件以YOLO标准格式记录每个目标的类别与归一化坐标yaml文件可直接用于后续训练前的类别与路径配置。目前已有459人学习下载数据规模较小但来源真实便于快速完成数据迭代与模型初调。图片保留了矿区实际的物料形态与光照差异有助于提升模型在复杂现场条件下的泛化能力同时同名标注对应关系清晰也适合用于数据增强、标签可视化与检测性能评估等扩展工作。1. 煤矸石识别数据集从现场图片到 YOLOv8 可用的三分类标注煤矿选矸和洗选环节里煤、煤矸石、高岭石这三类物料经常混在一起人眼盯着皮带盯久了会疲劳传送带速度一快就漏选。这份煤矸石识别数据集的价值在于它不是从公开数据集里拼凑的合成样本而是现场采集的 102 张原始图片并且已经按 YOLOv8 格式完成类别标注——煤炭、煤矸石、高岭石三类都框好了。对于刚开始跑目标检测的工程师这组数据能直接喂给 YOLOv8 做训练也可以作为现场数据采集和标注格式的参照样本。适合谁用做煤矿智能化分选、皮带异物识别、矿物视觉检测的算法工程师以及想用 YOLOv8 练手但找不到工业现场数据的学生。102 张图不算多但配合迁移学习做小样本训练足够把基线模型跑通。2. 数据集结构摸底三类目标的标注到底长什么样2.1 现场图片的文件命名与原始样本特点这份数据集的图片文件名类似012_png.rf.1fcc9085833b5c1b93d64d030804ac7e.jpg前缀的012_png是现场采集时的原始照片序号中间的rf以及后面的长串哈希字符是数据标注平台 RoBoFlow 处理后的文件标识。理解这一点很重要因为这种命名不代表业务含义只说明这批图片来源是真实场景拍摄而不是从网上下载的合成图。从文件名可以看到图片编号从 007 到 052 不等覆盖了至少几十个现场镜头位。现场采集的图片通常包含几个共性特点光照不均匀——室外矿区有阳光直射和阴影交叠物料堆叠——煤和矸石在皮带上或料堆上相互遮挡尺度差异——近处物料占画面比例大远处物料小到十几个像素。这些特点都会直接影响后续标注框的质量也会在训练时暴露给小目标检测的短板后面第 4 章会展开讲这些问题。2.2 YOLOv8 标注格式的核心类别编号与归一化坐标YOLOv8 的标注文件不是存坐标像素值而是存归一化后的相对坐标。每个.txt标签文件对应一张图片文件里的每一行代表一个目标框格式固定为五列第一列类别编号整数。0 代表煤coal1 代表煤矸石gangue2 代表高岭石kaolinite具体编号按数据集作者给的data.yaml决定。第二、三列目标框中心点的 x、y 坐标归一化到 0~1。第四、五列目标框的宽度 w 和高度 h同样归一化到 0~1。用记事本打开任意一个标签文件看到的行内容大致是这样的0 0.4859 0.6325 0.2137 0.1842 1 0.7123 0.5481 0.1652 0.2210 2 0.3567 0.7194 0.1809 0.1433逻辑说明这样的设计是为了与输入图片尺寸解耦。YOLOv8 在训练时会统一缩放图片到 640×640默认如果用绝对像素坐标图片一变尺寸所有标注就都失效了归一化坐标则保证训练时的缩放和推理时的缩放都不影响框的位置比例。参数说明两个坐标值都做了归一化意味着打开标注文件时看到的所有数字都介于 0~1。新接触 YOLO 格式的人常犯的错是拿到标注文件后直接把 0.48 当成像素坐标去画框结果画出一个缩在角落的小方框。实际操作中我会先写个小脚本把归一化坐标转回像素坐标叠加在原图上检查一遍再投入训练。2.3 数据集类别分布与场景覆盖的快速检查方法拿到数据集后不要急着训练先做一次类别分布统计。这三类物料的样本量如果悬殊过大模型会把大头类别学得很好、小头类别直接忽略。用 Python 读一遍所有标签文件就能出数import os from collections import Counter label_dir labels/train class_names [coal, gangue, kaolinite] counter Counter() for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname), r, encodingutf-8) as f: for line in f: cls_id int(line.strip().split()[0]) counter[cls_id] 1 for cls_id in range(3): print(f{class_names[cls_id]}: {counter.get(cls_id, 0)} boxes)逻辑说明这段脚本遍历训练集标签目录下的所有 txt 文件逐行读取取每行第一个字段类别编号做计数。如果 coal 的框数远大于 gangue 和 kaolinite后面需要在损失函数里给少数类加权重或者用数据增强把少数类样本复制粘贴扩充。参数说明label_dir路径按你自己的数据集目录结构调整如果标签文件只有 train 没有 val可以用train_test_split或 YOLOv8 自带的ultralytics工具自动划分。这组数据只有 102 张图我一般会按 8:2 划成训练集和验证集并用--seed 42固定随机种子保证每次实验可比。提示检查标注框是否越界同样重要。归一化坐标理论上不会超过 [0, 1]但如果标注工具导出时出现过小数精度问题个别框可能超出边界训练时 YOLOv8 会自动裁剪但会报警告先处理干净再训练更稳。3. 用 YOLOv8 训练煤矸石识别模型从目录整理到跑通第一个 epoch3.1 数据集目录结构YOLOv8 默认的 images 与 labels 组织方式YOLOv8 官方训练脚本对数据集目录有默认约定图片放在images/train和images/val标签放在labels/train和labels/val。两份数据的文件名主体必须一一对应只是后缀不同——图片是.jpg标签是.txt。把这份数据集落盘到正确结构后目录树应该是这样的coal_gangue_dataset/ ├── data.yaml ├── images/ │ ├── train/ │ │ ├── 012_png.rf.1fcc9085833b5c1b93d64d030804ac7e.jpg │ │ └── ... │ └── val/ │ ├── 008_png.rf.b45a742bb7c2bd24a6f99a2f29457cff.jpg │ └── ... └── labels/ ├── train/ │ ├── 012_png.rf.1fcc9085833b5c1b93d64d030804ac7e.txt │ └── ... └── val/ ├── 008_png.rf.b45a742bb7c2bd24a6f99a2f29457cff.txt └── ...结构没理顺就直接训练是常见的翻车点。YOLOv8 对不上图名和标签名时不会报明显的错误而是默默跳过这些图片的训练最后 mAP 低到离谱。3.2 编写 data.yaml类别名与路径的关键配置YOLOv8 训练前要指定一个数据集描述文件路径、类别名都写在这里。我的习惯是把路径写成绝对路径避免不同工作目录下相对路径解析出错。# data.yaml train: /home/user/datasets/coal_gangue_dataset/images/train val: /home/user/datasets/coal_gangue_dataset/images/val nc: 3 names: 0: coal 1: gangue 2: kaolinite逻辑说明train和val指向的是图片目录不是标签目录YOLOv8 会自动找同名的 txt。nc写死类别数 3names列表的顺序必须和标签文件里的类别编号一致——0 对应 coal1 对应 gangue2 对应 kaolinite。顺序写反了模型也能训练但推理出来框名是错位的这是最容易浪费半天时间的问题。参数说明可以用相对路径但训练脚本如果在别的目录下启动就会找不到数据文件而直接报错。另外这个 YAML 文件需要保存为 UTF-8 无 BOM 格式Windows 记事本默认可能带 BOMLinux 下解析会报错。3.3 训练命令与关键参数预训练权重、imgsz、epochs、batch数据集小不建议从头训练直接加载 COCO 预训练权重做迁移学习。命令如下yolo detect train \ modelyolov8s.pt \ datacoal_gangue_dataset/data.yaml \ epochs100 \ imgsz640 \ batch16 \ patience20 \ device0 \ projectrun_coal \ nameexp_gangue逻辑说明modelyolov8s.pt是 YOLOv8s 的 COCO 预训练权重模型自身学过 COCO 的 80 类通用物体特征迁移到煤矸石场景时只需要微调后几层就能较快收敛。patience20表示验证集 mAP 连续 20 个 epoch 不提升就提前结束训练防止小数据集上后期过拟合白白浪费时间。参数说明imgsz640是默认分辨率对这份数据集的现场图片来说是合理选择。如果发现小目标远处物料漏检严重可以尝试imgsz1024但显存占用会明显上升2GB 显存的卡不建议硬上。batch16在 102 张图的规模上有些大如果显存不够降到 4 或 8 即可。device0指定用第一块 GPU没有 GPU 就写devicecpu但 100 个 epoch 的 CPU 训练时间会非常漫长建议先用一个小 epoch 数跑通流程。3.4 检查训练输出loss 曲线、P 曲线、R 曲线和 mAP 曲线训练完成后YOLOv8 会在run_coal/exp_gangue/目录下生成results.png里面包含训练和验证的 box loss、cls loss、精确率、召回率、mAP50、mAP50-95 曲线。看曲线有几个重点训练 loss 和验证 loss 同步下降属于正常收敛训练 loss 下降但验证 loss 回升就是过拟合信号需要回退 epoch 或加大数据增强。mAP50 在 0.3~0.5 区间对这份数据集来说属于可接受水平——因为三类物料外观接近煤和矸石在灰度上差异小强区分本身就是难题。精确率和召回率不平衡时优先保住召回率——漏检一块矸石流到下游比误检一块煤被多停一次皮带的代价更大。results.png只是汇总图如果想看每一类的独立指标运行下面这段代码from pathlib import Path # YOLOv8 训练完成后 val 目录里会有 confusion_matrix.png 和 results.csv results_csv Path(run_coal/exp_gangue/results.csv) if results_csv.exists(): import pandas as pd df pd.read_csv(results_csv) print(df.iloc[-1]) # 打印最后一个 epoch 的全部指标 else: print(results.csv 不存在请检查训练是否完成)逻辑说明results.csv是 YOLOv8 自动记录的每个 epoch 的指标明细比读图更精确。最后一行的值就是模型最终性能打印出来后你会看到metrics/precision(B)、metrics/recall(B)、metrics/mAP50(B)等列名。参数说明这套指标是按 COCO 风格计算的mAP50表示 IoU 阈值取 0.5 时的平均精度mAP50-95是 IoU 从 0.5 到 0.95 取多个阈值的平均。工业现场通常围绕mAP50判断够不够用因为现场不要求像素级精度框大体位置对就行。4. 煤矸石识别训练避坑指南六个最容易翻车的细节4.1 小目标漏检皮带远端物料几乎不报框现象训练出的模型对图片近处的大块物料都能框住但画面远端小尺寸物料几乎没有检出甚至完全忽略。原因这份数据集里大量图片是现场皮带或料堆的广角镜头远处物料在 640×640 分辨率下只有 10~20 像素见方。YOLOv8s 的下采样倍数大小目标经过多层卷积后特征信息已经丢失。解决优先把输入分辨率调到 1024并在训练配置里开启augmentTrue的 mosaic 增强YOLOv8 默认开启。mosaic 把四张图拼成一张相当于变相增加了小目标的数量。如果 102 张图原始标注里小目标占比确实低建议补充一些局部放大裁剪的图片重新标注。4.2 煤与矸石互相误检类别外观接近导致混淆严重现象验证集上 coal 的召回率不错但 precision 低很多 gangue 被框成 coal看混淆矩阵时 coal 和 gangue 之间存在明显交叉。原因煤和煤矸石在视觉上都是深色块状物边缘纹理接近特别是湿度大的环境下两者灰度直方图高度重合。单靠 RGB 颜色做区分本来就勉强而这类现场数据集通常没有利用多光谱信息。解决一是检查标注框边界是否把两类目标框得太紧或太松框内背景多会引入额外噪声二是把训练 epoch 数适当调长让模型有更多时间学会纹理差异三是考虑在数据增强中增加对比度和锐度的随机变化帮助模型脱离对特定光照条件的依赖。4.3 高岭石样本过少模型完全学不到这个类现象训练结束后 kaolinite 类的 mAP 接近 0召回率低到个位数部分 epoch 甚至没预测出任何高岭石框。原因高岭石颗粒颜色浅、表面细腻和煤矸石在图像上区分度差加上数据集里高岭石的标注框数量远少于另外两类模型在类别不平衡下容易直接把样本归到多数类。解决在 loss 层面给少数类加权。做法是把data.yaml里的类顺序不变训练时在 PyTorch 侧修改类别权重或者更简单直接——用albumentations做样本复制增强把高岭石区域的裁剪图通过随机旋转、亮度变化后粘贴到其他图片上。对 102 张图的数据集来说手工粘贴增强比调 loss 权重更直观、更容易控制质量。4.4 训练早停但 mAP 很低验证集划分不合理现象patience触发提前停止后mAP50 只有 0.15 左右明显低得异常重跑也是类似的低位收敛。原因102 张图随机划分时可能验证集里恰好全是难样本堆叠重叠严重的场景训练集缺少同类样本模型没见过这类形态自然学不出好结果。解决固定随机种子做多次划分比较不同划分下验证集表现。如果某一划分 mAP 明显低于其他说明划分不均衡。常见做法是手动挑出覆盖不同光照、不同堆叠形态的图进验证集确保验证集分布和训练集一致。4.5 显存溢出batch 和 imgsz 同时拉到高位直接 OOM现象训练启动后瞬间报CUDA out of memory进程被杀。原因batch16加imgsz1024同时启用时显存占用轻松超过 8GB即使是imgsz640在 4GB 显存的卡上 batch 超过 8 也可能溢出。解决显存不够就把 batch 降到 4imgsz保持 640或者开启ampTrue混合精度训练显存占用能降一半速度还更快。YOLOv8 默认不开启 AMP需要显式指定。4.6 推理时框偏移模型训练正常但实际预测位置偏现象模型在验证集上 mAP 正常部署到现场视频流后框会整体偏移尤其画面边缘位置。原因训练时缩放图到 640 宽高但推理视频流时帧分辨率不是方形YOLOv8 内部做了 letterbox 处理。如果推理脚本没有正确配置imgsz或没有维护与原图对应的坐标变换关系输出框相对原图就会错位。解决不要自己手写坐标变换用model.predict(source..., imgsz640)YOLOv8 官方实现已经处理了 letterbox 和坐标回映射。我自己在写推理脚本时踩过这个坑后来强制所有推理入口都走ultralytics的封装接口不再手算缩放比例。注意这组数据集的标签文件来自 RoBoFlow 平台框坐标精度对标点工具操作者的手劲。拿到数据后我建议快速扫一遍标签特别关注有没有把物料边缘阴影也框进去的情况这类框会引入额外背景噪声影响模型收敛速度。5. 从基线到可用小样本数据集的调优与部署思路5.1 只用 102 张图怎么把效果往上推迁移学习与数据增强组合102 张图对目标检测训练来说是极小规模直接训练很容易过拟合。把第 3 章的基线模型跑通后想往上提升效果我会按下面三个顺序做第一换更大的预训练权重。YOLOv8s 换成yolov8m.pt或yolov8l.pt模型容量大能学到的特征更细。代价是推理速度下降部署在边缘设备上要谨慎。对煤炭皮带分选这类实时性要求高的场景先评估一下现场算力再选。第二强化数据增强策略。YOLOv8 的增强参数可以通过训练命令直接调比如hsv_h0.015、hsv_s0.7、hsv_v0.4、degrees10。煤和矸石的颜色本来就是主要区分特征色相增强不能调太大否则会让煤变成红色块。我的经验是饱和度增强保持 0.3 以下亮度增强 0.3~0.5 之间让模型适应暗光和逆光但不要改变色相。第三分阶段训练策略。先用imgsz640训练 50 个 epoch 拿到初步权重再加载这个权重把imgsz1024训练 30 个 epoch。这样模型先学整体结构、再学细节纹理比从头直接用 1024 训练更稳也能缓解小目标漏检。5.2 验证模型性能的量化方式混淆矩阵与单类指标训练完成后不能只看总 mAP要把每一类的混淆情况拆开看。YOLOv8 训练输出里有confusion_matrix.png这是一个 4×4 的矩阵三类加背景横轴是真实类别纵轴是预测类别。重点关注两个位置coal真实那一行里gangue预测列的值代表有多少煤被误判成矸石。gangue真实那一行里coal预测列的值代表有多少矸石漏检成了煤。工业上矸石漏检混入煤流影响煤炭品质煤误判成矸石被排掉造成资源浪费。两类错误的代价不同所以只看 mAP 不够要按业务权重分别优化。输出单类指标用下面这段代码# 用训练好的 best.pt 在验证集上跑详细评估 from ultralytics import YOLO model YOLO(run_coal/exp_gangue/weights/best.pt) metrics model.val(datacoal_gangue_dataset/data.yaml) # 逐类打印 box 的 mAP50 for i, name in enumerate(metrics.box.ap50): class_name [coal, gangue, kaolinite][i] print(f{class_name} mAP50: {name:.3f})逻辑说明metrics.box.ap50返回一个长度为 3 的数组按data.yaml里names的顺序排列。这个逐类指标比总 mAP 更能暴露问题——如果 gangue 的 mAP 只有 0.2 而 coal 有 0.6说明模型严重偏向某一类。参数说明best.pt是训练过程中验证集 mAP 最优的权重文件推理时用这个而不是最后一个 epoch 的last.pt。5.3 部署环节的注意点模型导出与边缘设备兼容训练得到best.pt是 PyTorch 格式部署到现场工控机或边缘盒子比如 RK3588 这类常见平台前要转格式。YOLOv8 的导出命令很简单yolo export modelrun_coal/exp_gangue/weights/best.pt formatonnx imgsz640导出成 ONNX 后再用各平台的工具链转成对应推理格式。几个实际经验导出的 ONNX 如果要在 CPU 上跑记得开启opset12以上版本不然某些算子兼容性有问题。现场光照条件和训练集不同部署前最好在现场采集几十张图跑一遍推理看看误检率确认没有出现大面积漏检后再上产线。输入图片尺寸要和训练时一致。训练用了 640推理也用 640突然换成 800 或 1280 输入模型输出不会报错但精度会下降。6. 我验证模型是否真的可靠的一整套流程模型训练完不能只看 mAP把整批验证集图片跑一遍推理、把结果叠在原图上存下来逐张看的效果比任何指标都直观。我从那次被 mAP 骗过之后就养成了一套固定习惯每次项目都强制走一遍。首先把best.pt对训练集和验证集全部做一次批量推理推理结果保存成带框的图片单独放在一个目录里。我实际用的是下面这段脚本from ultralytics import YOLO model YOLO(run_coal/exp_gangue/weights/best.pt) results model.predict( sourcecoal_gangue_dataset/images/val, imgsz640, conf0.25, saveTrue, save_txtTrue, projectinspect_result, nameval_check )逻辑说明conf0.25是置信度阈值低于这个值的框会被过滤掉。现场场景如果误报多就调高到 0.35~0.45如果漏检多就调低到 0.1~0.15。saveTrue保存带标注框的图片save_txtTrue同时输出推理的坐标文件方便后续做批量分析。预测完成后我会重点看四类情况大量重叠的物料堆、明暗对比强烈的图片、光照均匀的图片、以及含高岭石的图片。如果四类里有任何一类预测框与人工判断差异大就需要回到训练侧调参。第二步对比推理框和标注框的偏差。脚本输出推理 txt 后我把这些 txt 和原始标注的 txt 做逐框匹配凡是不重合的框单独截图出来看。这个步骤能暴露标注本身的问题——类似 4.1 小节说的小目标标没标、4.2 小节说的框偏移以及整个框完全漏标的少见情况。第三步也是最后一步把模型拿到现场做一次快速面测。选一个有代表性的场景比如皮带上料或者堆料区域用笔记本摄像头或手机对着拍 30 秒视频拉回来看帧级别的检测效果。我在现场测过才敢说模型能用因为数据集里的静态图和真实连续帧之间还有一道鸿沟——真实的皮带振动、物料滑动、遮挡变化是静态图片完全模拟不了的。从那以后我每次拿到数据集无论来源多可信都会先做一遍这份验证流程再决定是否进入训练环节。小数据集的坑藏在细节里只有快速验证才能把时间花在有效的问题上。希望这些经验能帮到你在训练煤矸石识别模型时少走我走过的弯路。本文还有配套的精品资源点击获取
返回列表