ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

3258张马路裂缝数据集:YOLO双格式标签训练与避坑实践

3258张马路裂缝数据集:YOLO双格式标签训练与避坑实践 简介这份面向道路裂缝检测的YOLO系列目标检测数据集适合正在训练YOLOv5、YOLOv8、YOLOv9、YOLOv10、YOLO11等模型的开发者与算法工程师可直接用于路面病害识别、裂缝定位等场景。数据集已预先划分好训练集、验证集和测试集并附带可直接使用的data.yaml配置无需额外整理即可开始训练标注格式同时提供YOLO风格的TXT文件和VOC风格的XML文件分别存放在独立文件夹中方便不同框架与脚本读取也便于做格式转换或二次标注。压缩包内共2000个文件以标注数据为主整体大小约104.55MB目录结构清晰且对YOLO格式中类别索引、中心点坐标、宽高比例等字段做了明确说明上手门槛低。目前已有187人学习下载适合需要快速获得带标签道路裂缝数据集并进行YOLO系算法训练与效果验证的学习者使用。1. 这套马路裂缝数据值在哪3258张、双格式标签与训练即用设计做目标检测的都有这种经历数据集到处找要么图像够但标签格式五花八门要么标签齐了但没划分训练前光整理数据就花一下午。这份马路裂缝数据集的好处恰恰在省事——3258张道路裂缝图像同时给了 yolo 格式txt和 voc 格式xml两套标签分别放在两个文件夹里train/val/test 已经按比例切好连 data.yaml 配置都写好了YOLOv5 到 YOLO11 拿到手可以直接开训。对我这种经常要快速验证模型在道路病害场景下能不能跑通的人来说省掉的是最枯燥的预处理环节。但它也不是没有坑——双格式标签虽方便用错一套、路径写错、或者尺寸方向处理不当训练照样静默翻车。下面按我拿到这份资源后的实际推进顺序来拆目录核对、训练启动、验证反馈、避坑记录最后给一个把误检样本回流训练集的进阶做法。2. 解压后先别急训练目录核对与标签-图像一致性校验2.1 解压步骤与目录结构确认下载下来是个 zip 压缩包别用 Windows 资源管理器直接双击解压到带空格或中文的路径后面 ultralytics 读路径时会出幺蛾子。我习惯直接命令行解压信息看得清楚Linux 下用 unzipWindows 下同样可用 Git Bash 或 WSLunzip yolo算法-马路裂缝数据集-3258张图像带标签.zip -d ./crack_dataset cd ./crack_dataset find . -maxdepth 2 -type d | sort解压完先看目录树而不是急着打开 data.yaml。这里一个常见情况是压缩包内部还套着一层同名文件夹如果你直接把data.yaml里的路径指到解压根目录训练时大概率报Dataset not found。find命令的-maxdepth 2限制只显示两层目录避免输出刷屏-type d只列文件夹一眼看出 images、labels、yolo_format、voc_format 这些关键目录到底在哪一层。确认目录结构之后逐个目录打开看一眼再动手改配置。这份数据集的目录设计是图像单独一个文件夹yolo 格式的 txt 标签和 voc 格式的 xml 标签各占一个文件夹。这样做有一个直接好处——你可以在不碰原始图像的前提下同时跑 YOLO 训练和做 VOC 格式的迁移实验。很多从网上扒下来的数据集标签跟图像混在一个目录里整理起来非常痛苦。这套把格式隔离的做法值得你自己整理数据集时也沿用。2.2 标签-图像一致性自动校验这是我认为最不能跳过的一步。数据集在反复压缩、上传、转存的过程中偶尔会出现某张图像的标签文件丢失或者文件名被批量重命名过导致标签对不上图像。YOLO 训练时如果标签缺失ultralytics 默认行为是跳过那张图继续训你根本察觉不到直到验证集 mAP 上不去才开始怀疑数据有问题。拿这份数据集来说文件名类似img_0104_1741.xml、img_0104_103.xml不是简单的0001.jpg这种连续编号人眼很难看出有没有漏。我一般拿到手先跑一遍这个脚本# verify_matching.py import os from pathlib import Path img_dir Path(crack_dataset/images) # 图像目录 yolo_label_dir Path(crack_dataset/yolo_labels) # yolo格式txt目录 voc_label_dir Path(crack_dataset/voc_labels) # voc格式xml目录 img_names {p.stem for p in img_dir.glob(*.jpg)} yolo_names {p.stem for p in yolo_label_dir.glob(*.txt)} voc_names {p.stem for p in voc_label_dir.glob(*.xml)} missing_yolo img_names - yolo_names missing_voc img_names - voc_names extra_yolo yolo_names - img_names extra_voc voc_names - img_names print(f图像总数: {len(img_names)}) print(fyolo标签缺失: {len(missing_yolo)} - {sorted(missing_yolo)[:5]}) print(fvoc标签缺失: {len(missing_voc)} - {sorted(missing_voc)[:5]}) print(f多余yolo标签: {len(extra_yolo)} - {sorted(extra_yolo)[:5]}) print(f多余voc标签: {len(extra_voc)} - {sorted(extra_voc)[:5]})这段脚本逻辑很直白分别取图像的stem不含扩展名的文件名和两套标签的stem做集合差。img_names - yolo_names得到的是有图但没标签的样本这类样本在训练时会被静默跳过属于必须处理的extra_yolo yolo_names - img_names则是孤儿标签说明某些标签对应的图像已丢失。集合运算比逐个循环快3258 张图毫秒级出结果。跑完这个脚本如果两类标签各自都缺 0 张、多 0 张再继续往下走训练流程。如果缺了别自己凭感觉补先确认是不是图像目录里混了非 jpg 格式比如 png、bmp那glob(*.jpg)会漏统计改成glob(*.*)再跑一次。3. 跑通 data.yaml 到训练yolov5 到 yolo11 的命令与参数取舍3.1 data.yaml 逐字段拆解与路径写法这套数据集自带的data.yaml是 yolov5/v8 系列通用的配置文件格式但拿到手不建议直接训先打开看一眼路径。很多数据集作者在自己机器上配置的是绝对路径发出来后你解压路径不同就废了。文件内容一般是这个样子# data.yaml path: ./crack_dataset # 数据集根目录相对于当前运行位置 train: images/train val: images/val test: images/test nc: 1 names: [crack]path字段是根目录train、val、test写的是相对于根目录的子路径nc是类别数names是类别名列表索引从 0 开始和 txt 标签里的第一列一一对应。这份数据是单类别所以nc: 1names里只有crack。这里我建议把path改成在训练命令里用绝对路径而不是依赖 yaml 里的相对路径。原因是path的相对路径基准是你执行训练命令时所在的目录一旦换终端、换目录启动训练路径就失效。我一般这么改# data.yaml 修改后 path: /home/user/crack_dataset train: images/train val: images/val test: images/test nc: 1 names: [crack]把path写成绝对路径后train/val/test 仍然用相对子路径这样无论从哪个目录启动训练都能正确定位。另外注意test目录有没有真实数据——有些数据集只给 train 和 valtest留空字符串。这份数据集的 test 是真实存在的验证时能给出更可信的泛化指标。如果遇到test为空的资源val 就要承担最终评估职责最好从 val 里再切一小块出来做 test避免验证集被反复使用导致指标虚高。3.2 YOLOv8/YOLO11 训练命令与参数说明ultralytics 系列YOLOv8/v9/v10/11的训练命令几乎同构区别主要在模型权重文件。以 YOLO11 为例yolo detect train \ modelyolo11s.pt \ data/home/user/crack_dataset/data.yaml \ epochs200 \ imgsz640 \ batch16 \ patience50 \ project./runs_crack \ nameexp_crack逐参数说modelyolo11s.pt是预训练权重s 是 small 版本裂缝检测目标相对简单s 足够没必要上 xl 徒增显存和训练时间data必须是上一步改好的绝对路径相对路径在这里最容易翻车epochs200对 3258 张图的数据集来说偏常规裂缝特征清晰一般 100 轮就能收敛但多给训练轮次配合早停没坏处patience50是早停参数验证集 mAP 连续 50 轮不提升就自动停止防止过拟合浪费时间imgsz640是 YOLO 系列默认输入尺寸原图如果大于 640ultralytics 会自动等比缩放再 padding 成 640x640batch16根据显存来定16G 显存跑 s 模型没问题显存小降到 8。train/val/test 的划分在数据里已经做好了data.yaml 引用到的目录存在即可。YOLOv5 的命令稍微不一样它的data参数写的是dataset.yaml模型权重是yolov5s.ptpython train.py \ --data /home/user/crack_dataset/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 200 \ --patience 50 \ --project ./runs_crack \ --name exp_yolov5yolov5 的train.py在仓库根目录下--img而不是--imgsz--weights而不是--model。命令结构不同容易搞混如果两边框架都装了就注意区分。值得留意的是无论哪个版本第一次训练都会在数据集目录下生成一个缓存文件如labels.cache用于加速后续训练启动如果你中途手动增删过标签文件记得把缓存删掉再训否则它会按缓存里的索引来读标签导致新加入的样本不生效find /home/user/crack_dataset -name *.cache -delete对于这份代码我没有去动--cache参数默认即可。如果你的机器内存小于 16G建议训练时别打开缓存盘加载直接在命令里加cacheFalse明确关闭防止 RAM 被打满。4. 验证不是走过场从 mAP 数字到 PR 曲线的坏样本归因4.1 验证命令与输出指标解读训练完runs_crack/exp_crack/下会生成weights/best.pt和weights/last.ptbest 是验证集 mAP 最优的权重。对这份数据集我建议直接用独立的 test 集做一次干净评估yolo detect val \ model/home/user/crack_dataset/runs_crack/exp_crack/weights/best.pt \ data/home/user/crack_dataset/data.yaml \ splittest \ imgsz640 \ batch32注意splittest这个参数——如果不写默认用 val 集做验证。val 集已经在训练过程中参与过早停判断指标存在间接影响test 集才是完全没碰过的数据。验证完成后终端会输出一行 mAP 汇总大概长这样指标含义这份数据的合理区间Precision预测为裂缝的框中真正是裂缝的比例0.85 以上Recall真实裂缝中被模型检出来的比例0.85 以上mAP50IoU 阈值 0.5 时的平均精度0.90 左右mAP50-95IoU 从 0.5 到 0.95 步进取平均0.60-0.75 算不错如果 mAP50 有 0.9 以上说明这个数据集训练出的模型在相似场景的道路裂缝检测上是能用的如果只有 0.7先别急着调模型回头检查第 2 章的标签一致性——我见过很多模型效果差的案例根因是标签和图像错位模型学了一堆错误对应关系。mAP50-95 比 mAP50 更低是正常的因为更严格的 IoU 阈值要求预测框和真实框几乎像素级重合裂缝这种长条形细目标天然对框精度敏感。验证目录下还会生成confusion_matrix.png、PR_curve.png和F1_curve.png。PR 曲线是最值得看的——横轴 Recall、纵轴 Precision曲线越往右上凸越好。如果 P-R 曲线在 Recall 大于 0.9 后 Precision 急剧掉到 0.5 以下说明模型在高召回区间大量误检典型表现是把路面纹理误判成裂缝。4.2 从 PR 曲线到坏样本归因曲线只能给出整体趋势真正定位问题要靠把预测结果可视化。ultralytics 验证时加一个参数就能输出每张图的预测框叠加图yolo detect val \ model/home/user/crack_dataset/runs_crack/exp_crack/weights/best.pt \ data/home/user/crack_dataset/data.yaml \ splittest \ save_jsonTrue \ save_confTruesave_jsonTrue会生成predictions.json里面是每张图上每个预测框的类别、置信度、框坐标save_confTrue在输出的val_batch0_pred.jpg这类图上把置信度数字标在框上方。拿着这些输出图重点看两类样本一类是置信度高但框明显框错位置的另一类是置信度中等0.4-0.7且模型坚持认为是裂缝的。前者往往对应裂缝和路面阴影交界处后者多半是路面接缝或水渍。在这个环节我还习惯把预测错误的图集中翻一翻。对马路裂缝数据来说最容易误检的无非三类目标路面横向伸缩缝和裂缝形态极度相似、轮胎刹车印深色条状区域、白色车道线边缘在低分辨率下和裂缝纹理相近。如果模型在这类干扰上大量翻车单纯加训练轮次没用要回到数据层面处理——这正好引出第 6 章说的难例回流先把这些误检图收集起来确认是否需要在训练集里补充对应负样本或难例。5. 避坑记录从 exif 旋转到中文路径四条踩坑复盘5.1 图像 exif 旋转信息导致标签框整体错位现象训练时 loss 能正常下降验证集 mAP 却不升画出来的预测框全部向左偏转了约 90 度而且只在部分图上出现。原因手机或部分运动相机拍摄的 JPG 图像会写入 exif 的 Orientation 字段标记图片应该旋转 90 度、180 度或 270 度显示。操作系统看图软件会自动读 exif 旋转看起来是正的但 YOLO 训练管线用 OpenCV 读图cv2.imread默认不解析 exif 方向读进来就是原始存储的像素方向。标签框坐标是在图像经过显示旋转后的画面上标的训练时模型看到的却是旋转前的图像框自然全部错位。解决拿到任何来源不明的图像数据集第一步批量清除 exif 并把图像按取向字段真正转正。用 Python 处理from PIL import Image, ImageOps from pathlib import Path img_dir Path(crack_dataset/images) for p in img_dir.glob(*.jpg): img Image.open(p) img ImageOps.exif_transpose(img) # 按exif方向转正 img.save(p, JPEG, exifb) # 保存时不保留exifexif_transpose会根据 Orientation 字段把像素真正旋转到显示方向exifb清空元数据。执行完重新跑一遍第 2 章的校验脚本并且抽几张图肉眼对比原图确认没有重复旋转。从那以后我拿到任何数据集第一步都是清除 exif不清理干净坚决不进训练流程。5.2 data.yaml 或路径含中文导致数据读取失败现象训练启动时报FileNotFoundError或Dataset not found但路径明明存在有些版本不报错而是静默训练了空数据集跑完 loss 始终不下降。原因压缩包文件名和解压目录都带中文比如yolo算法-马路裂缝数据集-...ultralytics 底层拼接路径时涉及 OpenCV 的imdecode在不同平台上对非 ASCII 路径的处理行为不一致。Windows 下最容易触发Linux 下取决于 locale 设置。解决解压后立刻把根目录改名成纯英文比如crack_dataset整个项目路径也不要有空格。这是纯防御性做法不讨论中文路径应该支持——在工程上少踩一个平台的坑比争论标准更有用。改完路径记得同步修改 data.yaml 里的path并把第 3.1 节说的缓存文件删掉。5.3 标签文件与图像文件名不同源出现孤儿数据现象用第 2 章的脚本校验时发现 extra_yolo 和 missing_yolo 同时不为 0即存在有标签没图像和有图像没标签的样本。原因这类数据集在上传转存过程中图像文件夹被人为重命名过或者部分图像在传输中损坏被剔除但标签目录没有同步更新导致两边文件名集合错位。项目正文里列出的文件名是img_0104_1741.xml这种带采集信息的长名和常见自动编号的0001.jpg风格不一致更容易出现不同源问题。解决以图像目录为准脚本自动删除孤儿标签并把缺失标签的图像单独移到一个need_relabel文件夹。等模型训练出第一版后用模型对这些图像做预标注人工修正后再并入数据集。注意不能直接删图像了事删除图像会损失样本多样性对裂缝这种类内差异大的目标影响明显。5.4 多类别混合训练时索引漂移现象单类别训练一切正常一旦把自己的其他类别数据比如坑槽、修补和这套裂缝数据混合训练mAP 骤降预测框的类别标签全部错乱。原因这份 txt 标签第一列是类别索引单类别下恒为 0。混合数据时如果直接用np.concatenate这类操作拼接标签没有把原数据的索引 0 映射到新类别列表中的正确位置就会把裂缝样本标记成了其他类别。YOLO 训练并不校验标签里的类别索引是否在nc范围内索引漂移属于静默错误。解决混合数据集前先各自加载标签到内存按类名合并再统一重新分配索引。具体做法是读取 txt 第一列用names列表把索引转成类名合并后再从新names中查索引写回import glob cls_name_to_idx {crack: 0, pothole: 1} # 新数据集的类别映射 for txt_path in glob.glob(labels/*.txt): lines [] for line in open(txt_path): parts line.strip().split() old_idx int(parts[0]) old_name old_names[old_idx] # 旧数据集的names列表 new_idx cls_name_to_idx[old_name] lines.append(f{new_idx} .join(parts[1:])) with open(txt_path, w) as f: f.write(\n.join(lines))这个脚本的核心逻辑是把每个标签行的类别索引先翻译成文本类名再根据新的映射表重新编号。任何时候都不要相信两个数据集碰巧用了相同的索引names顺序一变所有标签都得跟着动。6. 难例回流把误检样本变成下一轮的训练增量训练完第一版模型后别急着收工。我习惯把 test 集上被误检的样本全部导出来按置信度区间分层抽样人工看一遍。对这份裂缝数据集误检集中在两个区间置信度 0.7 以上的高置信误检模型非常自信地把接缝/水渍当裂缝和 0.3 到 0.5 的低置信漏检真实裂缝被漏掉。前者是负样本问题后者是正样本不够。导误检样本不需要写复杂脚本用 predict 模式把验证集整个跑一遍同时输出图像和 jsonyolo detect predict \ modelruns_crack/exp_crack/weights/best.pt \ source/home/user/crack_dataset/images/test \ save_txtTrue \ save_confTrue \ project./fp_analysis然后在fp_analysis目录里按文件名把预测结果和真实标签做比对凡是预测了裂缝但 xml 里没有对应目标的就是高价值误检样本。把这些图像复制到一个新目录用当前模型先自动标注一版再人工修正——注意修正不是删掉误检框那么简单而是给误检目标重新标注上它真实所属的类别比如joint接缝、stain水渍这就等于给模型补充了显式负样本。相比直接调超参数这是见效更稳的提点手段。回流训练时把新增样本按 8:1:1 切分并入 train/val/test重新生成 data.yaml然后接着训练而不是从头训练modelruns_crack/exp_crack/weights/best.pt作为预训练权重继续微调学习率会自动降低避免旧数据被新数据冲击。一般一轮难例回流就能把高置信误检压下去一半以上。从那以后我每次训练完都会强制走一遍误检导出和难例回流就算 mAP 已经很好也要看一眼 PR 曲线的尾巴确认没有藏着置信度虚高的误检再收工。希望帮到你。本文还有配套的精品资源点击获取
返回列表