简介这份资源面向从事道路巡检、自动驾驶感知或缺陷检测方向的研究者与算法工程师提供一套按YOLOV5目录格式整理好的日本马路路面缺陷检测数据集可直接投入目标检测模型训练省去格式转换与标注清洗环节。压缩包共约2000个文件以1999个txt标注文件与1个Python可视化脚本为主整体约753.56MB图像为600×600的RGB图片涵盖纵向裂纹、横向裂纹、坑洞、不规则裂缝等7个类别并附有类别文本说明。数据已划分为训练集7757张图片及对应标签、验证集1955张图片及对应标签目录结构规范便于直接接入YOLOV5训练流程。配套的show.py脚本可随机读取一张图片并绘制边界框无需修改即可运行方便快速核验标注质量。目前已有327人学习适合需要真实路面缺陷样本、希望快速验证检测方案的中高级开发者参考使用。1. 日本马路路面缺陷检测数据集7 类标注到底能训出什么模型如果你正在找一份能直接丢进 YOLOV5 训练脚本、不用自己写转换代码的目标检测数据集日本马路路面缺陷检测数据7 类别大概率就是你要的东西。它按 YOLOV5 目录格式组织也就是 images/labels 分家、每张图配一个同名 txt 标注文件类别覆盖路面开裂、坑槽、修补痕迹等常见病害。这类数据在道路巡检、无人小车、市政养护里需求很实在——摄像头拍一段路模型告诉你哪块路面该修了。但拿到数据集只是起点。真正决定你能不能训出可用模型的是 7 个类别之间的边界怎么划、标注框贴不贴边、以及 YOLOV5 那套超参数在小目标密集的路面场景里怎么调。这篇笔记按「数据集长什么样 → 怎么接进 YOLOV5 → 训练参数怎么设 → 坑在哪 → 怎么验证」的顺序讲新手能照着跑通熟手能直接看参数和边界条件。2. 拆开这份 YOLOV5 目录格式数据集结构、类别与标注质量2.1 目录结构与文件命名规则YOLOV5 认的目录结构很固定拿到数据集先别急着训先确认它是不是这个形状dataset/ ├── images/ │ ├── train/ │ │ ├── road_0001.jpg │ │ └── road_0002.jpg │ └── val/ │ ├── road_0101.jpg │ └── road_0102.jpg ├── labels/ │ ├── train/ │ │ ├── road_0001.txt │ │ └── road_0002.txt │ └── val/ │ ├── road_0101.txt │ └── road_0102.txt └── data.yaml关键点在于 images 和 labels 是镜像目录图片road_0001.jpg对应的标注必须是labels/.../road_0001.txt文件名不含扩展名严格一致。YOLOV5 的 dataloader 是靠路径替换找标签的名字对不上就直接当负样本处理训练时 loss 会莫名其妙不降。我一般拿到数据集第一件事就是跑个脚本核对配对情况import os from pathlib import Path root Path(dataset) for split in [train, val]: imgs {p.stem for p in (root / images / split).glob(*.jpg)} labs {p.stem for p in (root / labels / split).glob(*.txt)} only_img imgs - labs only_lab labs - imgs print(f[{split}] 图片 {len(imgs)} 张, 标签 {len(labs)} 个) print(f 有图无标签: {len(only_img)} - {list(only_img)[:5]}) print(f 有标签无图: {len(only_lab)} - {list(only_lab)[:5]})这段脚本做的是集合差运算把图片名和标签名的 stem去掉扩展名各自收成集合相减就得到单边缺失的清单。参数上没什么可调的唯一要注意的是扩展名——如果你的图片是.png或.jpegglob 模式要跟着改否则会把所有图都判成「有标签无图」。跑完如果两个「有图无标签」数量都是 0说明配对没问题可以进下一步。2.2 7 个类别的定义与标注格式YOLO 格式的每行标注是class_id x_center y_center width height后四个都是归一化到 0~1 的相对值。路面缺陷这类数据类别通常是开裂crack、坑槽pothole、修补patch、车辙、剥落、标线破损、井盖异常之类。7 类不算多但路面病害的类间相似度很高——细裂缝和修补边缘的纹理在低分辨率下几乎一样这是后面训练难分的根源。先确认 data.yaml 里的类别顺序和标注文件里的 class_id 对得上# data.yaml path: ./dataset train: images/train val: images/val nc: 7 names: 0: crack 1: pothole 2: patch 3: rutting 4: spalling 5: line_damage 6: manholenc必须等于 names 的条目数names 的索引就是标注里的 class_id。这里最容易翻车的是数据集作者给的 yaml 顺序和实际标注不一致。验证方法是统计每个 class_id 的出现次数再抽几张图可视化看框和类别名是否合理。from collections import Counter from pathlib import Path cnt Counter() for txt in Path(dataset/labels/train).glob(*.txt): for line in txt.read_text().strip().splitlines(): if line: cnt[int(line.split()[0])] 1 print(类别分布:, dict(sorted(cnt.items())))这段统计的是训练集里每个类别的标注框总数。如果某个类别数量是个位数基本可以判定这一类训不出来要么补数据要么合并类别。参数上没得调但结果要会看正常的路面数据集crack 和 patch 通常占大头manhole 这种可能很少类别不平衡是常态。2.3 标注质量自查三个必看的指标标注质量决定模型上限YOLOV5 再强也救不了烂标注。我一般看三个东西框的宽高分布、是否有越界坐标、是否有零面积框。import numpy as np from pathlib import Path ws, hs, bad [], [], 0 for txt in Path(dataset/labels/train).glob(*.txt): for line in txt.read_text().strip().splitlines(): if not line: continue c, x, y, w, h line.split() x, y, w, h map(float, (x, y, w, h)) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): bad 1 ws.append(w); hs.append(h) print(f越界/异常框: {bad}) print(f宽 中位数 {np.median(ws):.3f}, 5% 分位 {np.percentile(ws,5):.3f}) print(f高 中位数 {np.median(hs):.3f}, 5% 分位 {np.percentile(hs,5):.3f})归一化坐标必须落在 0~1宽高必须大于 0。bad不为 0 说明有脏标注得回去清理。宽高的 5% 分位很关键如果小于 0.02说明有大量极小目标YOLOV5 默认的 anchor 和输入尺寸可能抓不住后面要专门调。路面裂缝经常就是这种细长小目标这是这份数据集的核心难点也是它比通用数据集更值得练手的原因。3. 把数据集接进 YOLOV5从环境到第一次训练3.1 环境准备与仓库拉取YOLOV5 对环境不挑Python 3.8、PyTorch 1.8 就能跑。我一般用 conda 隔离避免和系统里的 torch 打架conda create -n yolov5_road python3.9 -y conda activate yolov5_road git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt装完先验证 torch 能不能看到 GPUpython -c import torch; print(torch.__version__, torch.cuda.is_available())如果cuda_is_available是 False训练会退到 CPU路面数据集动辄几千张图CPU 训一轮能等到天亮。常见原因是 CUDA 版本和 torch 不匹配去 PyTorch 官网按你的驱动版本重装对应 wheel 即可。这一步没有玄学就是版本对齐。3.2 用 data.yaml 挂载数据集把第 2 章的 dataset 目录放到 yolov5 同级或任意位置然后确认 data.yaml 里的path指向正确。YOLOV5 支持相对路径但相对的是path字段本身不是你的当前工作目录这点很多人搞混。稳妥做法是写绝对路径path: /home/user/dataset train: images/train val: images/val nc: 7 names: [crack, pothole, patch, rutting, spalling, line_damage, manhole]train和val是相对path的子路径。names 用列表写也行顺序必须和 class_id 一致。改完 yaml用 YOLOV5 自带的检查脚本过一遍python train.py --data data.yaml --img 640 --batch 16 --epochs 1 --weights yolov5s.pt --nosave跑 1 个 epoch 只为验证数据管道通不通。如果报No labels found或class label out of range回去查第 2 章的配对和 class_id。--nosave表示不存权重纯冒烟测试。这一步过了才说明数据集真正接进了 YOLOV5。3.3 第一次正式训练的命令与参数含义冒烟通过后正式训练我一般从 yolov5s 起步输入 640batch 按显存给python train.py \ --data data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml \ --project runs/road \ --name exp1 \ --cache逐个说--weights yolov5s.pt用 COCO 预训练权重小数据集上比从头训收敛快得多--img 640是输入分辨率路面小目标多的话可以提到 960 甚至 1280但显存和速度代价明显--batch 16是每批图片数显存不够就降到 8 或 4YOLOV5 会自动做梯度累积补偿--epochs 100对几千张图的数据集通常够看验证集 mAP 不再涨就可以停--hyp指定超参文件小数据集建议用 low 增强那套避免过拟合--cache把图片缓存到内存第二次 epoch 开始速度提升明显但内存要够。训练过程中重点盯三个输出box_loss、obj_loss、mAP0.5。box_loss 不降说明标注或学习率有问题obj_loss 震荡说明正负样本划分不稳mAP 卡在低位多半是类别不平衡或小目标没学好。这些在第 5 章会展开。4. 路面缺陷场景的超参数与增强策略怎么调4.1 针对小目标和细长裂缝的 anchor 与输入尺寸路面裂缝在 640 分辨率下经常只有十几个像素宽YOLOV5 默认 anchor 是为 COCO 那种中等目标设计的直接套用会漏检。两个办法提分辨率或者重聚类 anchor。提分辨率最直接--img 960或--img 1280小目标像素数翻倍召回率通常能涨几个点。代价是显存和推理时间部署到树莓派或 RK3568 这类边缘设备时要权衡。重聚类 anchor 用 YOLOV5 自带的脚本python utils/autanchor.py --data data.yaml --img 640 --thr 4.0 --n 9--n 9是 anchor 数量YOLOV5 默认 9 个分三层--thr 4.0是 IOA 阈值路面这种密集小目标可以适当调低到 3.0 让聚类更细。跑完把输出的 anchor 填进模型配置或 hyp 文件。注意 anchor 要和输入尺寸匹配你按 640 聚类的 anchor 用到 1280 上就不准了得重新聚。4.2 数据增强哪些开、哪些关YOLOV5 的增强都在 hyp 文件里。路面缺陷数据有几个特殊性病害的纹理和颜色是判别关键过度颜色抖动会让裂缝和阴影混淆但几何变换翻转、缩放、平移是安全的因为路面病害没有固定朝向。# hyp 片段 hsv_h: 0.015 # 色调抖动路面建议调小 hsv_s: 0.5 # 饱和度可保留 hsv_v: 0.3 # 明度阴影多的场景调小 degrees: 0.0 # 旋转路面不需要 translate: 0.1 # 平移保留 scale: 0.5 # 缩放小目标场景保留 shear: 0.0 # 剪切关 flipud: 0.0 # 上下翻转路面语义上不合理关 fliplr: 0.5 # 左右翻转开 mosaic: 1.0 # 马赛克小目标友好开 mixup: 0.0 # 混合小数据集慎用重点说三个flipud一定要关路面上下翻转后天空跑到下面语义完全错乱mosaic对小目标帮助大它把四张图拼一张等效增加了小目标出现频率但训练后期建议关掉YOLOV5 会自动在最后 10 个 epoch 关闭mixup在小数据集上容易让模型学糊除非你数据量上万否则保持 0。4.3 类别不平衡与损失权重第 2 章统计过类别分布如果 manhole 只有几十个框而 crack 有几千个模型会偏向多数类。YOLOV5 本身没有直接的类别权重参数常见做法有三个过采样少数类、在 data.yaml 里复制少数类图片、或者改用 focal loss 变体。最省事的是过采样import random from pathlib import Path import shutil root Path(dataset) minority manhole # 找出含少数类的图片 targets [] for txt in (root / labels/train).glob(*.txt): for line in txt.read_text().splitlines(): if line and line.split()[0] 6: # manhole 的 class_id targets.append(txt.stem) break # 复制 3 倍 for stem in targets: for i in range(3): shutil.copy(root / fimages/train/{stem}.jpg, root / fimages/train/{stem}_dup{i}.jpg) shutil.copy(root / flabels/train/{stem}.txt, root / flabels/train/{stem}_dup{i}.txt)这段把含 manhole 的图片复制 3 份文件名加后缀避免覆盖。参数上复制倍数按不平衡比例定目标是让少数类占比到 10% 以上。注意复制后要重新跑第 2 章的配对检查确保新图片和新标签成对出现。过采样会让这部分图被多次看到有轻微过拟合风险配合增强能缓解。5. 训练路面缺陷模型最容易踩的坑5.1 现象mAP 一直卡在 0.1 以下不涨原因通常是标注和类别对不上或者 data.yaml 的nc写错。YOLOV5 在类别数不匹配时不一定报错而是把越界的 class_id 静默丢弃导致大量标签失效。解决跑第 2 章的类别统计脚本确认最大 class_id 小于nc再抽 5 张图用labels可视化工具叠加框肉眼确认框位置合理。我遇到过 yaml 写nc: 7但标注里出现 class_id 7 的情况多出来的那一类全被丢了。5.2 现象训练 loss 正常但验证集 mAP 极低这是典型过拟合路面数据集如果只有几百张图yolov5s 都能背下来。原因可能是增强太弱或训练太久。解决把--hyp换成 low 增强那套加大 mosaic 和 scale减少 epochs加早停--patience 20。另外确认 train 和 val 没有重复图片——有些数据集划分不严同一段路的不同帧同时进了训练和验证验证集分数虚高实际部署就翻车。5.3 现象小裂缝全部漏检大坑槽正常原因是默认 anchor 和输入尺寸不适合小目标。解决先按 4.1 提分辨率到 960 试一轮如果显存不够就降 batch再跑 anchor 聚类替换默认 anchor。还有一个容易忽略的点验证时的--conf-thres默认 0.25小目标置信度普遍偏低评估时可以降到 0.1 看召回上限但部署时别降太低否则误检爆炸。5.4 现象训练到一半 CUDA out of memory原因多半是--img或--batch给大了或者--cache把内存吃满。解决先降 batch 到 8YOLOV5 会自动调整还不行就降 img 到 512。--cache在图片多的时候会占几个 G 内存内存紧张就用--cache disk或者干脆不开。注意 YOLOV5 的显存占用在第一个 epoch 最高因为要做增强和缓存后面会稳下来别在第一个 epoch 就 panic。5.5 现象推理时框重叠严重同一个坑出好几个框原因是 NMS 的 IoU 阈值不合适或者模型没训好导致同一目标多个高置信预测。解决调--iou-thres默认 0.45密集小目标可以提到 0.5~0.6如果还重叠说明模型置信度分布太散回去看训练是否充分。另外路面缺陷本身有相邻的情况一条裂缝旁边一个补丁NMS 阈值太高会把相邻目标误合并这个要在验证集上手动调平衡。6. 验证与部署怎么确认模型真能用训练完不能只看 mAP 数字得落到具体场景验证。我一般分三步验证集细看、单图推理、边缘设备实测。先看验证集的混淆矩阵和 PR 曲线YOLOV5 训练完会自动生成在runs/road/exp1/下。重点看 crack 和 patch 之间有没有大量互错——这两个类在路面场景最容易混。如果混淆严重要么合并类别要么补更多区分性样本。单图推理用detect.pypython detect.py \ --weights runs/road/exp1/weights/best.pt \ --source test_images/ \ --img 960 \ --conf-thres 0.3 \ --iou-thres 0.5 \ --save-txt--source可以是单图、目录或视频--save-txt把检测结果存成 YOLO 格式方便后续统计病害数量。--conf-thres 0.3比默认 0.25 略高路面场景误检代价高误报一个坑就要派人去看宁可漏一点。跑完肉眼过一遍结果图看有没有系统性漏检或误检。如果要部署到树莓派或 RK3568 这类边缘设备先导出 ONNX 或量化python export.py --weights runs/road/exp1/weights/best.pt --include onnx --img 640导出时--img要和训练一致否则精度掉得厉害。边缘设备上推理速度是瓶颈yolov5s 在树莓派 4B 上大概几 FPSRK3568 有 NPU 会快些但量化后小目标精度通常掉 2~5 个点这个代价要提前评估。我的习惯是先在 PC 上把 mAP 和单图效果调满意再导出量化量化后重新在验证集上跑一遍对比掉点是否可接受不能接受就换更小的输入尺寸而不是硬上量化。最后说个我自己的教训路面缺陷数据集最坑的不是模型是标注一致性。同一批数据里不同标注员对「裂缝」和「修补边缘」的界定可能不一样模型学出来就是模棱两可。拿到数据集先花半天抽检标注比后面调一周超参都值。希望帮到你。本文还有配套的精品资源点击获取