YOLOv5道路裂缝检测实战:从数据增强到TensorRT部署 简介一份基于改进YOLOv5模型的高速道路裂缝检测本科毕业论文采用docx格式共1个文件压缩包约30KB适合计算机科学与技术、深度学习和智慧交通方向的学生作为毕业设计或课题研究参考。论文系统梳理了YOLOv5模型原理与高速道路裂缝检测现状重点设计了改进方案包括网络结构调整、注意力机制引入及数据预处理并围绕数据集构建、实验设置、mAP与召回率等指标展开结果对比和可视化分析验证了改进模型在检测精度与速度上的优势。文档共六章覆盖引言、相关技术综述、数据集与实验设计、改进模型、结果分析与结论展望章节结构完整便于快速把握研究思路和实验流程。目前已有433人学习下载适合正在撰写相关论文、需要借鉴目标检测改进思路或了解道路裂缝检测实验设计的读者。1. YOLOv5检测道路裂缝任务特征与选型边界高速公路路面裂缝的巡检过去靠人工徒步或用道路检测车拍照后离线筛查效率和发现率都跟不上养护需求。用YOLOv5把裂缝检测做成端到端目标检测核心收益是推理链路短、部署面广但真正的难点在于裂缝本身的特殊性它细长、宽窄不一、可能断续和车牌识别、水果识别这类目标检测任务有本质区别——车牌是强结构化目标水果是强纹理目标裂缝两者都不占。本文不讨论学术刷点只按「数据集 → 网络改进 → 训练调参 → 部署验证」的顺序把基于YOLOv5做高速道路裂缝检测这条路怎么走通、参数怎么设、坑在哪讲清楚。适合正在做道路病害检测、桥梁表观检测以及想把检测模型压到边缘设备上的工程师。2. 裂缝数据集构建与针对性数据增强2.1 数据来源与目录布局先解决分辨率差异裂缝检测的数据一般来自三处车载工业相机、无人机航拍、便携式相机人工补拍。这三种来源的分辨率差异极大有的单张图是8000×6000有的只有1200×1000。直接统一缩放成640再训练小裂缝会被下采样抹掉后续改进网络结构也救不回来。常见做法是按裂缝在原始图像中的像素宽度决定训练输入尺寸。如果裂缝宽度在十几个像素左右训练分辨率要提高到1280如果只做块状破损或发达裂缝检测640就够用。采集设备典型分辨率建议训练尺寸备注车载工业相机8192×40961280需先按车道切片无人机航拍6000×40001280配合切片推理手持设备补拍4000×3000640拍摄距离近裂缝像素大训练集目录布局按YOLOv5推荐的结构images和labels严格同目录名、同文件名扩展名不同否则训练时会报found X images and Y labels的数量不匹配。dataset/ ├── images/ │ ├── train/ # 约80% │ └── val/ # 约20% ├── labels/ │ ├── train/ │ └── val/ └── crack.yamlcrack.yaml 里的配置很简单path指向数据集根目录train和val填写相对路径nc: 1names: [crack]。类别第一版只建议设一个「crack」不要立刻把横向裂缝、纵向裂缝、网状裂缝分开。裂缝类别的边界模糊标注员之间的一致性差第一版类别分得越细mAP被标注噪声拖得越低。先让模型把「有无裂缝」这个二分类学好第二版再细分评估才有意义。2.2 标注规范细长目标别用一个大框包住标注环节最常见的问题是一条2米长、宽度只有2厘米的裂缝标注员习惯性画一个把整条裂缝包住的矩形大框。这种极端宽高比的框在anchor回归中非常不友好框内大部分是背景正样本特征被稀释。通用的做法是把长裂缝拆成多段标注每段长度控制在宽度的5到15倍之间如果裂缝宽度太小导致框面积过小就把相邻的断裂段合并但必须保证框内裂缝连续可见。YOLO格式的标签文件是txt每行对应一个目标class x_center y_center width height四个坐标值都是相对图片宽高的0到1浮点数。实际动手前可以先用几行Python统计一下训练集全部标注框的宽高分布确认anchor的初始取值范围这个统计脚本很短直接读labels下的txt即可。import os, numpy as np boxes [] for f in os.listdir(dataset/labels/train): for line in open(fdataset/labels/train/{f}): _, x, y, w, h map(float, line.strip().split()) boxes.append((w, h)) arr np.array(boxes) print(宽高比中位数:, np.median(arr[:, 0] / arr[:, 1]))运行这个统计后如果宽高比中位数集中在0.05附近说明标注框整体呈细长形后续anchor聚类就能给出合理的初始框而不是用COCO默认的通用anchor去硬凑。2.3 增强策略让裂缝的形态变化贴近现场YOLOv5自带的hyp.scratch-low.yaml提供了通用增强参数。对裂缝场景有两个项值得专门调整mosaic保持1.0它把四张图拼接后强迫模型在小尺寸下也能看到裂缝对小目标训练几乎必开copy_paste不建议在这种细长目标上用裂缝副本粘贴到新背景时容易在拼接边界产生断裂属于负优化。更有价值的增广是模拟裂缝的形态变化。用网格变形模拟裂缝的弯曲走向用随机膨胀腐蚀模拟不同路况下的缝宽差异。这些在线增强可以直接写进数据加载器也可以在训练前用albumentations离线造一批样本。在线增强的配置片段如下按YOLOv5的hyp文件格式填入mosaic: 1.0 mixup: 0.0 copy_paste: 0.0 hsv_h: 0.02 hsv_s: 0.4 hsv_v: 0.4这份参数里hsv_h是重点。高速路有桥墩阴影、防眩板照射、沥青颜色差异颜色轻微扰动能让模型对光照更鲁棒但hsv_h调到0.05以上就会让裂缝和路面阴影的边界被抹掉实测掉点明显。0.02是一个在多个裂缝数据集上验证过不过不失的取值。3. 改进YOLOv5网络小目标检测头与注意力机制的取舍3.1 P2小目标检测头的插入方式与显存代价YOLOv5默认检测头在stride 8、16、32三个尺度输出对应P3、P4、P5。十几像素宽的裂缝到了stride 32的特征图上一个grid cell就覆盖过去了。常规改进是增加P2层stride 4检测头让模型在小特征图上也能保留裂缝的位置信息。修改方式是在yaml配置中调整anchors定义为新增的小目标层补充一组小尺寸anchoranchors: - [3, 12, 15, 42, 40, 127] # P2 小目标 - [56, 186, 100, 262, 151, 340] # P3 # P4、P5 按原配置延续yaml改动只是第一步models/yolo.py里Detect层的输出分支数、anchors分组都要与yaml对齐同时训练时要让anchor自动聚类重新适配标注框分布。实践中的做法是先跑一次 k-means anchor 聚类把聚出的anchor写回配置。验证P2层是否真正生效看训练开始的网络结构打印detect分支数量应该变成4或5只看yaml文件往往会误导。P2层的代价是显存。640分辨率、batch 16的训练加P2后显存占用可能涨50%。显存不够时两个替代方案--img 960配合非正方形图的--rect模式按原比例拼接或者把backbone的宽度系数降下来用网络变浅换取更高输入分辨率。3.2 嵌入Coordinate Attention对细长条带比CBAM更友好在特征提取的深层插入注意力机制是YOLOv5改进的常见做法。CBAM虽然流行但它的空间注意力用了全局池化对细长目标会把方向性信息平均掉。Coordinate AttentionCA把空间注意力分解为宽度和高度两个方向分别编码正好匹配裂缝「窄而长」的形态而且参数量增加不多在Jetson这类边缘设备上也能接受。插入位置一般选在backbone最后一层C3模块之后让注意力图在最高语义层上重新校准特征响应。CA模块的核心逻辑如下关键参数是通道压缩系数reductionclass CoordinateAttention(nn.Module): def __init__(self, inp, oup, reduction32): super().__init__() self.pool_h nn.AdaptiveAvgPool2d((None, 1)) self.pool_w nn.AdaptiveAvgPool2d((1, None)) mip max(8, inp // reduction) self.conv1 nn.Conv2d(inp, mip, 1, 1, 0) self.bn1 nn.BatchNorm2d(mip) self.act nn.Hardswish() self.conv_h nn.Conv2d(mip, oup, 1, 1, 0) self.conv_w nn.Conv2d(mip, oup, 1, 1, 0) def forward(self, x): # 两路池化 - 拼接 - conv - split # 分别生成 h 方向和 w 方向的注意力权重 return x * attnreduction默认32在YOLOv5s这种较窄网络上偏大通道被压得太狠注意力特征表达不足建议改成16或8。另一个坑是CA模块对特征图尺寸的奇偶性敏感输入尺寸为奇数时池化结果无法整除训练会直接报错所以训练分辨率统一用偶数。3.3 损失函数与后处理CIoU不是终点YOLOv5默认的回归损失是CIoU。CIoU对宽高比差异大的框有惩罚但裂缝框的宽高比极值化CIoU的角度惩罚项会失效。实践中把损失换成SIoU或WIoU的版本并不少见SIoU对边界框回归的方向做了显式约束框的收敛路径更短WIoU通过动态样本权重降低低质量标注的影响适合裂缝标注质量参差的场景。后处理环节的NMS阈值也值得调整。YOLOv5的iou_thres默认0.45对裂缝这种一条长裂缝拆成多段标注的检测场景检测框之间高度重叠默认阈值会把相邻段的框当成重复框滤掉导致一条裂缝只检出一个小段。建议把NMS的iou_thres上调到0.5以上让相邻段的框同时保留最后再按长度合并。推理阈值conf_thres验证时用0.25实机推理可以降到0.1到0.15召回率会有明显提升代价是带入少量误报这个需要结合实际路段场景定底线。4. yolov5训练自己的数据集从环境配置到超参数调优4.1 yolov5环境配置的关键版本组合yolov5环境配置的问题大半出在CUDA、PyTorch和Python版本的组合上。社区使用最广的稳定组合是Python 3.8、PyTorch 1.13 CUDA 11.7或者PyTorch 2.0 CUDA 11.8。不需要追新PyTorch 2.1以上在部分老显卡上反而有算子兼容问题。yolov5源码直接从官方GitHub仓库获取进入目录后安装依赖conda create -n yolov5 python3.8 conda activate yolov5 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt装完先别急着跑大训练用coco128数据集跑一个3个epoch的冒烟测试确认数据加载、反向传播、日志输出全链路正常。这一步跳过的话后面训练到一半才发现环境问题排错成本更高。常见的Illegal instruction (core dumped)错误大多是CPU指令集不匹配需要重新编译安装对应版本的PyTorch。4.2 yolov5训练自己的数据集一条完整训练命令数据就绪、环境跑通之后训练命令的完整写法如下python train.py \ --data crack.yaml \ --cfg models/yolov5s_crack.yaml \ --weights yolov5s.pt \ --batch-size 8 \ --epochs 200 \ --img 640 \ --hyp hyp.scratch-low.yaml \ --device 0 \ --name crack_run--weights yolov5s.pt用官方COCO预训练权重做迁移学习对裂缝检测的提升非常明显因为COCO里包含了道路、车辆等纹理特征浅层特征可以直接复用。--img要和第2章定的目标分辨率一致提高分辨率时显存不够就减半batch不要同时拉满。--name crack_run指定输出目录名训练日志和权重都会存在runs/train/crack_run下每次实验换个名字对比起来不用翻文件夹。训练过程中观察日志的P、R、mAP0.5三个指标时不要只看mAP。裂缝检测里一个典型场景是mAP0.5很高但P值很低说明模型把大量坑洼和水渍当成了裂缝。对养护决策来说高误报比漏报更麻烦因为复核成本完全被误报吃掉。P和R都到0.75以上再谈精度优化。4.3 yolov5超参数中真正值得调的三个hyp.scratch-low.yaml里有几十个超参数在裂缝场景下真正值得动的没几个。大部分参数调来调去只是震荡以下几个对结果影响最直接参数默认值裂缝场景建议影响lr00.010.005 ~ 0.008裂缝样本少大学习率容易震荡lrf0.010.01保持默认即可hsv_h0.0150.02 ~ 0.03提升阴影下的泛化能力anchor_t4.03.0 ~ 4.0影响细长锚框的稳定性fl_gamma0.00.5 ~ 1.0缓解裂缝样本少的问题lr0是最敏感的一项。裂缝数据集通常只有几百张图正样本稀疏lr0按默认0.01跑loss经常前几十轮不下降。调到0.005之后曲线明显平滑。fl_gamma是focal loss的gamma参数从0.5开始试它把训练重心往难分的细小裂缝样本上偏移代价是训练时间增加大约15%但它对裂缝这种类别极不平衡的目标效果比调什么loss权重都直观。训练结束后优先看results.png里的三张曲线train loss是否单调下降、val mAP是否同步抬头、P和R是否收敛稳定。如果val mAP反复震荡而train loss持续下降说明数据增强太大或学习率偏高先把学习率降30%不要盲目加epoch加了也白加。5. 从验证指标到轻量化部署的落地技巧5.1 大图先切片SAHI对裂缝漏检的改善高速道路的采集图经常是8000像素级别的超宽图像整图直接过模型小裂缝在下采样过程中就消失了。常规做法是用 SAHI 做切片推理把大图切成带重叠的patch分别推理再映射回原图坐标对裂缝这种小目标通常能带来几个百分点的召回提升。from sahi.model import Yolov5DetectionModel from sahi.predict import get_sliced_prediction model Yolov5DetectionModel( model_pathcrack.pt, confidence_threshold0.3, devicecuda, category_mapping{0: crack}, ) result get_sliced_prediction( road.jpg, model, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2, )slice_height和slice_width建议与训练时的--img保持一致重叠率在0.1到0.3之间防止裂缝恰好被切在patch边界导致漏检。切片推理的代价是总耗时翻倍适合离线巡检和病害普查不适合秒级实时检测。5.2 推理引擎切换TensorRT FP16下看指标变化训练好的权重转TensorRT引擎直接用官方导出脚本python export.py --weights crack.pt \ --include engine \ --device 0 \ --imgsz 640 \ --halfFP16量化后显存占用能明显下降在Jetson Nano这类边缘设备上部署yolov5时单帧推理时延会缩短到能实际使用的范围。但量化后必须用验证集对比一遍FP32和FP16的mAP如果下滑超过0.5%先检查NMS阈值FP16精度下相邻框的置信度排序可能发生变化适当上调conf_thres通常能稳住。5.3 阈值与复核队列部署后仍要有人工兜底部署阶段最容易踩的坑是把conf_thres设得太高一个误报都不想要结果细小裂缝全被过滤了。我的做法是把置信度分成两段0.5以上的直接进入维修工单0.3到0.5的落入待复核队列用人工或二次模型确认。路面裂缝误报的复核成本远低于漏报后的养护延误成本。在边缘设备上部署YOLOv5时优化目标不应是单帧速度而是同样的误报率下能跑出多少召回率这个阈值策略比任何模型结构改动都值得先做。本文还有配套的精品资源点击获取