简介:面向地质学与矿业智能识别场景,这份“岩石表面矿物质检测数据集”提供超过1000张高分辨率岩石图片及对应标注,覆盖石英、斑铜矿、黄铁矿等8类矿物,适合使用YOLO系列目标检测算法开展训练与验证的算法工程师、地质科研人员及入门学习者。数据已转换为YOLO格式,并完成数据增广,可省去格式转换与预处理环节;配套训练集、验证集划分、class类别文件和show脚本,便于直接训练、快速可视化检测边界框。整个压缩包共2000个文件,以1138个txt标签文件、861张jpg图片及1个py可视化脚本为主,资源包大小59.08MB,结构紧凑实用。已有454人浏览学习。借助该数据集,用户可以快速搭建岩石矿物自动检测流程,减少数据清洗和标注成本,同时通过展示脚本直观评估模型在岩石表面目标识别上的表现,为进一步优化检测精度提供了完整基础。
1. 岩石表面矿物质检测数据集:超过1000张图,YOLO格式直接开训
做目标检测项目,最烦的不是调参,是找数据。尤其是地质、矿业这种垂直场景,公开数据集少得可怜,能直接喂给YOLO的更是稀缺。这套岩石表面矿物质检测数据集,超过1000张带标签的高分辨率图片,已经转成YOLO格式,训练集、验证集划分好,还带了class文件和可视化脚本,下载下来就能开训。对正在做地质勘探自动化、矿物识别、岩矿鉴定相关项目的工程师和研究生来说,省掉的不是一两天,是整个数据准备阶段。8个矿物类别,覆盖石英、斑铜矿、黄铁矿这些常见矿物,量不大,但做迁移学习、效果验证、算法对比完全够用。接下来直接拆目录结构、标签格式、训练细节和踩坑点。
2. 数据集结构与YOLO格式:先搞清文件组织再动手
2.1 目录结构:images、labels、data.yaml 一套齐活
拿到数据集第一步不是急着训练,是先看目录结构,搞清楚每个文件是干什么的。这套数据集是标准的YOLO组织方式,下载解压后大概是这样的:
rock_mineral_dataset/ ├── train/ │ ├── images/ # 训练集图片 │ │ ├── 0011_jpg.rf.7a7655516b6ade13a199ad135383cba7.jpg │ │ └── ... │ └── labels/ # 训练集标签 │ ├── 0011_jpg.rf.7a7655516b6ade13a199ad135383cba7.txt │ └── ... ├── valid/ │ ├── images/ # 验证集图片 │ └── labels/ # 验证集标签 ├── test/ # 有的数据集有,有的没有 ├── data.yaml # 类别配置和路径配置 └── classes.txt # 类别清单train和valid下的images、labels一一对应,文件名完全相同,只是扩展名不同。jpg对应txt,这个对应关系是YOLO系列训练的前提。图片和标签文件名里的.rf.字段,说明这份数据经过 Roboflow 平台导出,这直接决定了标签格式和data.yaml的写法,后面细说。
提示:拿到数据集后第一步,先数一下train和valid里图片数量和标签数量是否一致。不一致的话,训练过程会报「Can't find label」的错,或者静默跳过某些图片,导致实际训练样本比预期少。
2.2 标签内容解读:归一化坐标和类别ID
打开任意一个txt标签文件,你会发现每行5个数字,对应一个目标框。格式是:
class_id x_center y_center width height具体数值示例:
0 0.4512 0.5633 0.1234 0.0891 2 0.7890 0.2341 0.0567 0.0678这些坐标全是归一化的,范围在0到1之间,是相对于图片宽高的比例。比如x_center=0.4512,表示目标框中心点在图片从左往右45.12%的位置。类别ID从0开始计数,对应classes.txt里的行顺序。classes.txt内容类似:
quartz bornite pyrite ...这个文件决定了模型输出的类别索引和实际矿物名称的映射关系,训练前必须确认data.yaml里的类别列表和classes.txt完全一致。
2.3 data.yaml的坑:路径写绝对还是写相对
data.yaml是所有YOLO训练入口的配置文件,里面定义了train路径、val路径和类别名。这套数据集的data.yaml大致长这样:
train: ../train/images val: ../valid/images nc: 8 names: ['quartz', 'bornite', 'pyrite', ...]这里最容易翻车的点在于路径。Roboflow导出时的默认路径可能是绝对路径,比如C:/Users/xxx/rock_mineral_dataset/train/images,换了一台机器根本找不到。我拿到任何数据集的第一件事,就是把data.yaml里的路径改成相对路径,然后整个数据集文件夹放到项目目录下,这样换机器不会出问题。
另外要注意nc参数必须和names列表长度一致。有个偷懒校验方法是数一下names里的引号数量,8个类别就是8个名字,nc写成8,不一致的话YOLO训练直接报错,连模型都不会加载。
3. 数据增广与训练集划分:泛化能力从哪里来
3.1 已有的增广做了什么
这套数据集做了数据增强,常见做法是旋转、翻转、缩放、亮度调整的组合。增广的意义不是制造更多图片,而是模拟不同光照条件、拍摄角度下的岩石表面状态。野外采集的岩石照片,光照强弱差异极大,同一块石英,逆光和侧光下视觉特征完全不同。如果训练集里全是同一光照条件下的图片,模型会把光照当成矿物特征的一部分,换一批图片效果立刻崩掉。
但增广也是有代价的。过度的几何变换会让矿物纹理失真,尤其是黄铁矿这种靠晶面反光特征识别的矿物,旋转90度加上亮度抖动,可能让标注框里的目标看起来不像黄铁矿。所以增广比例需要克制,一般控制在原图数量的1.5到3倍比较合适。
3.2 划分比例问题:验证集够不够用
数据集已经做了train/valid划分,默认比例一般是80/20或70/30。这里有一个常被忽略的问题:如果原始图片只有1000多张,验证集可能只有200多张,每个类别分下来可能只有20到30个目标框。对于8个类别的检测任务,这个验证集规模评估出来的mAP波动会比较大。
我习惯在训练前自己重新划分一次,或者至少检查一下现有划分是否均匀。划分脚本如下:
import os import random import shutil # 统计每个类别在train和valid里的目标框数量 def count_labels(labels_dir, nc=8): counts = [0] * nc for f in os.listdir(labels_dir): if not f.endswith('.txt'): continue with open(os.path.join(labels_dir, f), 'r') as fh: for line in fh: cls_id = int(line.strip().split()[0]) counts[cls_id] += 1 return counts train_counts = count_labels('rock_mineral_dataset/train/labels') valid_counts = count_labels('rock_mineral_dataset/valid/labels') for i in range(8): print(f'class {i}: train={train_counts[i]}, valid={valid_counts[i]}')这个脚本的作用是把每个类别在训练集和验证集中的目标框数量分别统计出来。如果发现某个类别在valid里只有个位数目标框,说明这个类别的验证结果不具备统计意义。这个时候需要手动从训练集挪一些样本到验证集,或者采用k-fold交叉验证的方式训练。
注意:重新划分数据集时,图片和对应txt标签文件必须一起移动,只挪图片不挪标签,或者反过来,训练时就会出现图上没框、框没图配的情况。血的教训。
3.3 数据集量级与迁移学习策略
1000多张图、8个类别,这个数据量从头训练YOLO是铁定过拟合的。常规做法是加载COCO预训练权重,冻结前若干层,只训练检测头。具体做法在YOLOv5里是:
python train.py --data rock_mineral_dataset/data.yaml --weights yolov5s.pt --freeze 10 --epochs 100 --batch 16--freeze 10的意义是冻结前10层,这些层学到的是通用视觉特征(边缘、纹理、颜色),对域不敏感,直接复用;后面层微调去学矿物特有的判别特征。这个策略在这个数据量级下基本是最优解。
4. show脚本可视化:训练前必须做的检查
4.1 可视化脚本的价值
数据质量是整个训练流程里最关键也最容易出问题的环节。标签坐标写错、类别标错、图片旋转没同步标签,这些问题靠肉眼审阅txt文件很难发现,但一可视化就全暴露了。这套数据集自带的show脚本就是干这个的。如果没有脚本,我一般自己写一个:
import cv2 import os import numpy as np def show_bbox(img_path, label_path, class_names, save_path=None): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path, 'r') as f: lines = f.readlines() for line in lines: cls_id, x_c, y_c, bw, bh = map(float, line.strip().split()) # 反归一化:把0-1的坐标换算回像素坐标 x1 = int((x_c - bw / 2) * w) y1 = int((y_c - bh / 2) * h) x2 = int((x_c + bw / 2) * w) y2 = int((y_c + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, class_names[int(cls_id)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) if save_path: cv2.imwrite(save_path, img) else: cv2.imshow('check', img) cv2.waitKey(0) cv2.destroyAllWindows() # 遍历验证集前50张 labels_dir = 'rock_mineral_dataset/valid/labels' images_dir = 'rock_mineral_dataset/valid/images' for i, fname in enumerate(os.listdir(labels_dir)): if i >= 50: break if not fname.endswith('.txt'): continue img_name = fname.replace('.txt', '.jpg') img_path = os.path.join(images_dir, img_name) label_path = os.path.join(labels_dir, fname) show_bbox(img_path, label_path, class_names, save_path=f'vis_{i}.jpg')这段代码的逻辑是从标签文件读取每一行,把归一化坐标乘以图片宽高还原成像素坐标,画框和类别名。核心参数是反归一化的换算过程,写错的话画出来的框就会偏移到搞笑的位置。可视化结果存成图片,方便批量检查,不必一张一张弹窗查看。
4.2 可视化检查的三个重点
抽检时重点关注三类问题。
第一类是框的大小是否合理。如果很多框占图片面积的80%以上,可能是标注粒度太粗,把整个岩石表面框进去而不是框单个矿物颗粒;反过来如果框都特别小,可能是忘了标注一些小目标。
第二类是框和矿物纹理是否对齐。人工标注难免有偏移,轻微的没问题,但如果偏移超过10%的面积,模型训练时就会学到错误的位置信息。
第三类是类别是否肉眼可辨。如果石英和黄铁矿标注相互混用,说明标注人员的标准不统一,这种情况必须回头修正标签,不能指望模型自己学会区分错误标注。
4.3 文件夹级批量检查
单张可视化效率太低,更实用的是批量生成缩略图拼版检查。用上面的脚本把所有验证集图片都输出到vis_output文件夹,然后用图像拼接工具把几十张小图拼成一张大图,肉眼扫一遍就能发现问题。这一步花费的时间不超过30分钟,但能避免训练了十几个小时后才发现标签错位的惨剧。
5. 训练避坑:八类标签里的常见问题与排查
5.1 现象:训练loss正常下降,但mAP一直在0.3左右上不去
原因:最常见的是类别不平衡问题。岩石表面矿物分布天然不均匀,石英可能占了50%以上的标注框,而斑铜矿可能只有几十个框。模型把绝大多数精力用来学石英的特征,其他类别几乎没学到。验证集上石英的AP可能到0.8,但少数类别的AP只有0.1左右,整体mAP就被拉下来了。
解决:先跑一下2.2节那个统计脚本,确认每个类别的目标框数量。差距超过一个数量级的,用类别权重或者在损失函数里调整每个类别的惩罚系数。YOLOv5里用--cls 0.8提高分类损失的权重,配合数据增广补充少数类样本。
5.2 现象:训练loss为nan,或者验证集loss出现剧烈震荡
原因:先检查学习率,默认学习率在1000张图这样的数据集上通常偏高,到后半程容易出现震荡。再检查标签文件里有没有异常的bbox坐标,比如x_center大于1或者width为负数。这种脏数据在训练时会让loss变成nan,然后整个训练过程就废了。
解决:批量检查标签文件,过滤掉坐标不在0到1范围内的行。如果是Roboflow导出的数据,理论上不应该有问题,但经过手动修改或者二次处理时很容易引入脏数据。写一个清洗脚本,把所有标签读一遍,过滤异常行再写回:
def clean_labels(label_path): valid_lines = [] with open(label_path, 'r') as f: for line in f: parts = line.strip().split() if len(parts) != 5: continue cls_id, x_c, y_c, bw, bh = map(float, parts) if 0 <= x_c <= 1 and 0 <= y_c <= 1 and bw > 0 and bh > 0: valid_lines.append(line) with open(label_path, 'w') as f: f.writelines(valid_lines)5.3 现象:训练集loss很低,验证集loss不断上升
原因:典型的过拟合。数据集只有1000多张图,模型容量大,容易把训练集样本的特征背下来。尤其岩石表面纹理细节丰富,背景复杂,模型很容易学到「记住这张图的纹理分布」而不是「学会识别石英的通用特征」。
解决:除了加载预训练权重外,增加数据增强的强度,开启mosaic增强,把多张图拼接起来训练。同时early stopping的patience设置得小一点,比如YOLOv5里--patience 20,验证集loss连续20轮不降就停,避免浪费时间。另外一个有效手段是把输入分辨率调低到416,让模型被迫关注整体结构而不是细节纹理,图像分辨率和模型复杂度的匹配直接影响泛化性能。
5.4 现象:预测时大量误报,把背景纹理识别成矿物
原因:训练时背景和矿物的区分度不够。岩石表面本身就是高纹理表面,有的矿物和背景的灰度值接近,模型学到的可能不是「矿物的形状、颜色特征」,而是「某个纹理区域大概率有矿物」。这个问题在野外光线不均匀的照片上尤其突出。
解决:如果数据集的增广里没有包含随机擦除(Random Erase),可以在训练时开启。这个策略随机遮挡图片的一部分,迫使模型学习目标的整体特征而不是局部纹理。YOLOv5的--augment参数可以开启更激进的增广组合,包括随机擦除、色调抖动、饱和度抖动。刚开始训练看到loss波动大是正常的,增广越激进,收敛越慢,但最终的鲁棒性会好很多。
5.5 现象:valid和train的mAP差距不大,但实际部署时效果很差
原因:数据划分太随机,train和valid里的图片可能来自同一个拍摄现场,背景纹理高度相似,相当于变相的数据泄露。模型在验证集上看起来不错,一旦部署到新的采集环境就露馅了。这个问题在小的私有数据集上非常普遍。
解决:按采集场景分组划分数据,同一个拍摄场景的图片要么全在训练集,要么全在验证集。如果数据集没有提供分组信息,就按照文件名的前缀去分。这属于经验判断,没见到具体文件结构不好说,但值得花时间做。
6. 进阶:小目标矿物的专项调优与验证方法
这套数据集的检测目标是岩石表面的矿物,和COCO数据集里的常规目标相比,最大的问题是目标尺度差异大。有的矿物颗粒有拳头大,在图片里占据几百个像素,有的矿物颗粒只有指甲盖大小,可能就十几个像素。YOLO的默认锚框是基于COCO数据集统计出来的,直接用在岩石矿物上,小目标检出率会明显偏低。
我现在拿到新数据集后的固定套路是:先用默认锚框跑一轮baseline,记录每类矿物的AP。然后跑YOLO自带的锚框自适应脚本,基于训练集的目标框尺寸重新聚类:
python train.py --data rock_mineral_dataset/data.yaml --weights yolov5s.pt --epochs 50 --batch 16 --noautoanchor第一次自动锚框计算会在启动时打印新的锚框值,对比一下和默认锚框的差距。如果新的锚框尺寸整体偏小,说明数据集里小目标占比远高于COCO,这时候可以开启--noautoanchor关闭自动计算,改为手动调整。再训练时关注小目标的mAP,看看是否有改善。
输入分辨率也是一个关键参数。YOLOv5默认是640×640,但岩石矿物的纹理细节对小目标识别影响很大,提升到960甚至1280,小目标的mAP通常能涨几个点。代价是训练速度变慢、显存占用变大。我用过的惯例是:先640跑通流程,再换960做最终版本。
类别不平衡在这类地质数据集里几乎无法避免,除了调整损失权重之外,我还习惯在验证阶段按类别分别输出AP,而不是只看整体的mAP。只关心石英的AP还是关心所有8个类别的平均性能,直接决定训练策略的选择。如果某个类别目标是漏检重灾区,可以用数据拼接的方式把该类别与其他类别组合成一张训练图,让模型在每个batch里都看到这个类别。上面项目用Roboflow做增广时已经做了一部分工作,但Roboflow的增广是离线增广,效果有限。
从那以后我每次训练任何数据集,都会强制走一遍「统计类别分布 → 可视化抽检 → 清洗标签 → 跑baseline → 按类别查AP」这个流程。看起来多花了几小时,但能从源头排除掉数据问题,后面调参时才不会像无头苍蝇一样乱试。这套岩石矿物数据集对做地质目标检测入门来说手感不错,标签质量和格式规范程度都算上乘,希望帮到你。
本文还有配套的精品资源,点击获取