尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

YOLOv5道路交通标识识别:从数据标注到部署的完整实战

YOLOv5道路交通标识识别:从数据标注到部署的完整实战 简介基于YOLOv5算法实现的道路交通标识识别系统是一套面向高校毕业设计、期末大作业与课程设计的完整源码项目代码注释详细从数据准备、模型训练到界面部署均有清晰覆盖初学者按说明简单配置即可运行适合深度学习、人工智能方向的学生用于实战练手或直接作为答辩作品。压缩包共266个文件约423MB核心组成包括53个Python源码、59个YAML配置、10个PT权重、55张JPG及26张PNG图像样本另有Shell脚本、Dockerfile等辅助内容便于复现训练与推理流程。包内还保留了TensorBoard训练事件日志与多次CSV结果能够辅助理解模型调优过程目前已有50人学习浏览。整套代码经过严格调试界面美观、操作便捷具备较高完整性与可扩展性可有效支撑交通标识识别系统的方案设计与功能落地是完成高分毕设的实用选择。1. YOLOv5 道路交通标识识别一套能直接答辩的源码与数据集闭环答辩前别人还在卷积原理图上打转你已经能把限速 40、禁止左转、注意行人这些交通标识从视频里一帧帧框出来——这就是基于 YOLOv5 的道路交通标识识别系统源码数据集的价值从数据标注、模型训练到推理验证的完整闭环自带训练日志、results.csv 和 Dockerfile正好打在毕设「有实现、有数据、有验证」的评分点上。它适合做毕设、期末大作业或课程设计、想在一个周末内跑通并讲清原理的学生也适合用 YOLOv5 练手目标检测的从业者。你要做的不是从零写网络而是把环境配好、数据对齐、超参数调明白。下面按原理、环境、训练、排错、验证的顺序展开。2. 看懂 YOLOv5 网络与运行环境从 CSPDarknet 到 conda 依赖落地2.1 YOLOv5 网络结构为什么交通标识识别选它YOLOv5 不是单个网络而是一套完整的检测方案由三块拼起来CSPDarknet 骨干网络负责提取图像特征PANet 路径聚合网络把不同尺度的特征融合最后的 Detect 头在三种尺寸的特征图上输出预测框。以 640x640 输入为例模型会分别在 80x80、40x40、20x20 三张特征图上做预测每个网格配 3 个 anchor总共 8400 个候选框再经过 NMS 去掉重叠框才是最终输出。三张特征图分别对应小、中、大目标——这个设计是交通标识识别能跑通的关键路面上的限速牌、警告牌在画面里往往只占几十个像素正好落在 80x80 那张小目标特征图上。选 YOLOv5 而不是更早的 YOLOv3 或两阶段的 Faster R-CNN理由有两个。第一YOLO 系列一次前向就同时完成分类和定位GTX 1060 级别的显卡跑 640 输入能到 40 FPS 以上做视频流实时检测绰绰有余答辩演示不会卡成幻灯片第二Faster R-CNN 在小目标上略占优势但训练和推理都慢一个量级对时间紧的毕设项目不划算。YOLOv5 的源码入口也拆得清楚train.py 训练、detect.py 推理、export.py 导出导师问到哪一步都能翻出对应文件讲。YOLOv5 按网络宽度和深度分成 n、s、m、l、x 五个规格毕设场景我建议先跑 s 建立基线不够再上 m而不是一上来就开 l 或 x——后者在 8G 显存的笔记本上基本训练不起来。各规格的取舍大致如下规格显存需求640 输入推理速度适用场景yolov5s4G 以上快毕设首选先跑通流程yolov5m6G 以上中数据量大、要冲高 mAPyolov5l / x8G 以上慢不推荐毕设场景使用还有一个常被忽略的前提这套源码里的权重是基于 COCO 预训练出来的拿到交通标识数据集后做的是迁移学习微调不是从零训练。torch.load 加载预训练权重时YOLOv5 会自动跳过类别数不匹配的检测头COCO 是 80 类你的数据集只有几类只保留骨干和颈部特征。如果启动日志里没有看到 Transferred 330/349 items 这类信息先检查权重路径是不是写错了。2.2 conda 环境搭建与 CUDA 验证装错 torch 的代价源码包里的 requirements.txt 和 setup.cfg 是环境配置的两个入口。requirements.txt 列出全部 Python 依赖setup.cfg 是 pip 可编辑安装的配置执行 pip install -e . 之后项目内模块可以直接被 import写自定义推理脚本时不用到处复制 utils 目录。Dockerfile 我把它当「环境后悔药」用它把 conda、PyTorch、依赖安装全部固化成镜像构建脚本答辩前要换到另一台机器演示一条 docker build 就能重建同样的环境省去现场装依赖翻车的尴尬。我的习惯是先用 conda 建独立环境这一步能避免把系统 Python 搞乱也方便随时删掉重来# 创建 Python 3.8 环境YOLOv5 官方支持 3.8-3.103.8 兼容性最稳 conda create -n yolov5 python3.8 conda activate yolov5 # 先装 PyTorch再装其它依赖顺序不能反 pip install torch1.13.1 torchvision0.14.1 --index-url https://download.pytorch.org/whl/cu117 pip install -r requirements.txt # 可编辑安装让项目内模块可以直接被 import pip install -e .先装 torch 再装 requirements 的顺序是有讲究的torch 和 torchvision 的版本必须严格匹配而 opencv、pandas、tensorboard 这些不挑 PyTorch 版本先装了它们再回头换 torch 版本可能出现 ABI 不兼容的诡异报错。requirements.txt 里值得留意的包有 opencv-python图像读写、pandas解析 results.csv、tensorboard训练可视化、pyyaml解析 data.yaml先按原样装一遍跑通后再动版本。装完别急着训练先验证 CUDA 是否真的可用。我见过太多毕设翻车案例torch 装成了 CPU 版训练一个 epoch 要 20 分钟还以为是数据集太大。import torch print(torch.__version__) # 期望输出 1.13.1 之类 print(torch.cuda.is_available()) # 必须是 True否则后续全白搭 print(torch.cuda.get_device_name(0)) # 输出你的显卡型号is_available() 为 False大概率是 torch 与显卡驱动不匹配去 PyTorch 官网用版本匹配表重新生成安装命令为 True 但 get_device_name 报错检查 conda 环境里是不是混入了多套 CUDA 工具链。如果手上没有独立显卡可以先用 CPU 版本把流程跑通Dockerfile 里也提供了服务器训练方案只是 epoch 数和 batch 要相应调小。提示本地有显卡就直接走 conda 流程需要借服务器训练的优先用 Dockerfile 构建镜像保证机器上只有一套 CUDA 工具链。环境验证通过后我建议先用仓库自带的 coco128 小数据集跑一次 5 epoch 的冒烟测试确认整条链路是通的。这一步能把「环境问题」和「数据集问题」隔离开——很多新手直接拿自己的数据开训报错了根本分不清是 torch 没装对还是标注格式写错白白浪费一晚上。冒烟测试的判别标准很简单能正常打印每个 epoch 的 mAP训练不中断日志目录里 events.out.tfevents 正常生成就算过关。最后把 pip list 导出一份 requirements-lock.txt 存档换机器时按锁文件重装比每次手动排查缺什么包靠谱得多。3. 数据集对齐与模型训练yaml 配置、超参数和 results.csv 的正确读法3.1 数据集结构与 YOLO 标注格式先可视化再训练YOLOv5 的训练数据是「图片 同名 txt 标签」的组合。images 目录放 jpg/pnglabels 目录放同名的 txt每一行代表一个目标第一个数字是类别 id从 0 开始后面四个数字是归一化后的中心点 x、中心点 y、宽、高取值范围 0~1。这套交通标识数据集里的类别按 id 从小到大排列类别名与 id 的对应关系写在 data.yaml 里。拿到的源码包里还有 events.out.tfevents 和 results.csv。前者是 TensorBoard 训练日志后者是每个 epoch 的指标记录这两样东西在答辩时能直接证明「模型是亲手训练出来的」而不是下载个权重糊弄事。我的建议是把这套日志留好后面画训练曲线、写实验对比章节都用得上。拿到数据集的第一件事不是开训而是把标注可视化出来确认标注没有错位。这个检查五分钟就能做完能省掉后面至少一小时的无效训练import cv2 def draw_label(image_path, label_path, class_names): img cv2.imread(image_path) with open(label_path, r) as f: for line in f.readlines(): parts line.strip().split() cls, cx, cy, w, h int(parts[0]), *map(float, parts[1:]) # 归一化坐标必须乘回图片宽高新手最容易在这步出错 x1 int((cx - w / 2) * img.shape[1]) y1 int((cy - h / 2) * img.shape[0]) x2 int((cx w / 2) * img.shape[1]) y2 int((cy h / 2) * img.shape[0]) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, class_names[cls], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) return img sample draw_label(datasets/images/train/00001.jpg, datasets/labels/train/00001.txt, [speed_limit, prohibition, warning, guide]) cv2.imwrite(check_sample.jpg, sample)这段脚本把 txt 里的归一化坐标换算回像素坐标并画框。换算时一定要用中心点加减宽高的一半而不是直接拿 cx、cy 当左上角画出来的框如果整体偏移或上下颠倒说明标签和图片不是同一套来源趁早重新对齐。如果图片本身有 EXIF 旋转信息OpenCV 读出来和手机预览方向不一致这也是框错位的常见原因批量用 cv2 重写图片把旋转信息清掉即可。3.2 data.yaml 与训练命令超参数的边界在哪里训练前先改 data.yaml这是把数据集路径和类别数告诉 YOLOv5 的唯一入口# 路径建议写相对路径换机器不用改 train: ./datasets/images/train val: ./datasets/images/val nc: 4 # 类别数按实际标注类别改 names: [speed_limit, prohibition, warning, guide] # 与标签 id 一一对应nc 和 names 必须和标签里的 id 完全对应。类别顺序错了训练过程不会报错但推理时框的类别名会张冠李戴属于最隐蔽的坑。路径我建议一律用相对路径绝对路径一旦换机器就要改答辩现场最容易在这上面崩。训练命令是整套源码的核心入口官方 train.py 已经封装好你只需要理解几个关键参数python train.py \ --data data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 200 \ --hyp data/hyps/hyp.scratch-low.yaml \ --project runs/train \ --name traffic_sign--weights 先试 yolov5s.pt显存 6G 以下跑不动 m 和 l--img 640 是速度与精度的平衡点想提升小目标召回可以试 960但推理速度会明显下降--batch 受显存限制8G 显存跑 640 输入时 batch 16 是安全线--epochs 我给毕设场景的建议是 150-200太低 mAP 没收敛太高纯属烧时间和电费。如果数据量只有几百张同时把 --hyp 换成 hyp.scratch-low.yaml 更稳。这份配置把初始学习率压在 0.01、数据增强幅度调小防止小数据集上过拟合或增强失真数据量过千、想冲更高 mAP 时再换 hyp.scratch-high.yaml。超参数不是越大越好增强太狠对小目标数据集反而有害标牌被裁掉一半标注框也跟着失真。3.3 训练日志与结果评估results.csv 与 TensorBoard训练开始后用 TensorBoard 盯整体趋势就够了不用每五分钟刷一次tensorboard --logdir runs/train/traffic_sign --port 6006浏览器打开 localhost:6006重点看 Box Loss、mAP0.5 和 Precision。mAP0.5 超过 0.85 说明模型基本可用如果 loss 前 20 个 epoch 一直在 0.05 以上徘徊多半是学习率或数据集有问题直接中断调参别等 200 个 epoch 跑完。训练结束后runs/train/traffic_sign 目录下会生成 results.csv每一行一个 epoch。用它画 mAP 曲线答辩 PPT 里放这张图比放代码有说服力得多import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/train/traffic_sign/results.csv) # 列名在不同 YOLOv5 版本里有差异先打印确认 print(df.columns) plt.plot(df[epoch], df[metrics/mAP0.5], labelmAP0.5) plt.title(Traffic Sign Detection Training Curve) plt.xlabel(epoch) plt.ylabel(mAP) plt.legend() plt.savefig(map_curve_compare.png, dpi150)results.csv 的列名在旧版叫 mAP_0.5新版叫 metrics/mAP0.5读之前先用 df.columns 打印确认。各项指标的判断经验大致如下列名新版含义经验标准train/box_loss边框回归损失持续下降最终 0.03 以下metrics/precision精确率0.85 以上metrics/recall召回率0.80 以上metrics/mAP0.5简单 mAP0.85 以上基本可用metrics/mAP0.5:0.95严格 mAP比 0.5 低 10-15 个点属正常mAP0.5:0.95 对交通标识这类小目标偏严格低 10-15 个点是正常现象别看到 0.6 就以为模型废了。真正要警惕的是 recall 和 precision 差距过大recall 远低于 precision 说明漏检多往增强小目标方向调precision 远低于 recall 说明误检多把置信度阈值往上提。4. 避坑指南训练与部署阶段最常遇到的五个问题训练和部署这套交通标识识别系统真正花时间的地方不在代码而在环境、数据和参数这三块。下面这五个问题是我在多个检测项目里反复遇见的坑每条按现象、原因、解决的顺序写你可以直接对照排查。4.1 训练阶段的三个翻车现场坑位一loss 不降反升现象train/box_loss 前 50 个 epoch 从 0.04 涨到 0.06mAP 一直是 0precision 和 recall 也始终在 0 附近不动日志看起来一切正常但模型完全没有在学。原因最常见的是学习率和数据增强不匹配。hyp.scratch-high.yaml 的增强幅度很大几百张的小数据集会被增强样本带偏模型在失真的样本上反复震荡另一个可能是预训练权重没加载上骨干从随机初始化开始训练loss 自然压不下来。判断方法很直接看启动日志里有没有 Transferred 330/349 items 这一行。解决换成 hyp.scratch-low.yaml或在命令行加 --lr0 0.001 --lrf 0.01让学习率从 0.001 开始、末期衰减到 0.00001。改完重启训练正常 20 个 epoch 内 loss 会掉头向下。如果 20 个 epoch 后还是平的回数据可视化那一步检查是不是标注框本身就有问题。坑位二mAP 高但真实视频漏检严重现象验证集 mAP0.5 到了 0.9一测真实道路视频30 米外的限速牌完全没框出来画面里只检出近处的大标志。原因交通标识是典型小目标。1920x1080 原图里 30 像素的标牌缩到 640 输入后只剩 10 像素特征图上的响应很微弱数据增强里的随机裁剪缩放还会进一步把目标压小模型根本没机会在小尺度上学到稳定的特征。解决把 --img 从 640 提到 960这个改动对小目标的收益立竿见影同时改 hyp 里的 scale 参数从默认 0.5 调小到 0.3避免增强时把标注框缩到看不见。更直接的办法是往训练集里补充小目标样本——把原图切块只保留包含小标牌的子图单独放一个目录加大采样权重这招比盲目加数据量有效得多。改完重新训练对比两次实验在同一段视频上的检测框数量比看 mAP 数字更直观。坑位三CUDA out of memory现象train.py 跑完第一个 batch 直接报 CUDA out of memory进程退出之前没存任何 checkpoint等于白等。原因显存占用和 batch size、输入尺寸、模型宽度三者强相关不是线性增长而是接近立方关系。yolov5s 配 640 输入8G 显存跑 batch 16 是极限再往上必炸。解决先用 nvidia-smi 看显存总量和当前占用再用 --batch 8、--workers 2 跑 5 个 epoch 观察占用曲线稳定了再逐步往上加。想保持 batch 16 就把 --img 降到 480精度小幅下降但训练稳定。另外关掉浏览器硬件加速、实时预览这类吃显存的后台程序也能挤出 1-2G 显存。教训是第一次训练永远别用默认 batch 32先用小 batch 探显存余量。4.2 部署与推理阶段的踩坑记录坑位四中文路径导致读写失败现象推理时 OpenCV 报错读不到图片或者 data.yaml 里写的路径明明存在却一直 FileNotFoundError训练到一半进程静默退出。原因OpenCV 和 PyTorch DataLoader 对 Windows 中文路径支持不完整路径编码不一致时不会报具体错误而是静默返回 None后面所有操作跟着炸。解决最省事的是数据集和项目根目录全部用英文路径不要出现「桌面/新建文件夹」这类的路径。原始数据已带中文的用批量改名工具把非 ASCII 字符去掉花十分钟一劳永逸。Linux 服务器上如果涉及挂载路径同样保持纯 ASCII避免 SSH 终端编码不一致导致的问题。坑位五GPU 利用率上不去推理忽快忽慢现象detect.py 跑视频每帧耗时 20-80ms 剧烈波动GPU 利用率只有 30%风扇声倒是不小。原因CPU 端的图片解码和缩放成了瓶颈GPU 一直在等数据DataLoader 的 worker 数没配图片读取是串行的每一帧都要等上一帧处理完才解码。解决推理时加 --workers 4输入先 resize 到 640 再喂模型内存够的话把视频帧提前解码缓存。要定位瓶颈可以分别测「只解码不推理」和「只推理不解码」两段的耗时谁占比大就优化谁这是排查性能问题最朴素也最有效的办法。毕设演示还有个取巧方案导出成 ONNX 后用 onnxruntime 推理CPU 上也能接近 GPU 的速度具体做法在下一章。5. 验证与导出的实用技巧置信度扫描和 ONNX 导出把结果做实模型训练完最后的验证环节直接决定答辩分数。detect.py 是官方推理脚本两个参数必须亲手调--conf-thres 置信度阈值和 --iou-thres NMS 阈值。这两个值怎么配其实带点玄学但有一套可复现的扫参方法。python detect.py \ --weights runs/train/traffic_sign/weights/best.pt \ --source test_video.mp4 \ --conf-thres 0.35 \ --iou-thres 0.45 \ --save-txt --save-conf首轮验证先用 0.25 的置信度确认「能不能检出」确认不漏检后再逐步往上提阈值压误检。对交通标识来说误检比漏检更伤——把「禁止驶入」框成「限速 40」答辩演示上非常难看。我一般跑三组 conf-thres0.25、0.35、0.5对比同一段视频的输出选误检最少且不漏关键目标的那组。--iou-thres 0.45 是 NMS 去重阈值交通标识互相挨得近连续两个限速牌阈值太低会把相邻同类的框合并成一个太高又可能重复框同一个目标0.4-0.5 是比较稳的范围。把 best.pt 导出成 ONNX 是被低估的加分点。导出成功不仅推理变快还能证明你理解模型部署链路这是导师最常追问的扩展点python export.py --weights runs/train/traffic_sign/weights/best.pt \ --include onnx --opset 12导出成功后生成 best.onnx用 onnxruntime 做一次推理确认输出形状是 1×25200×(5nc)。25200 是 640 输入下三个尺度网格总数 8400 乘 3 个 anchor 的结果nc 是类别数能把这个数字自己说清楚答辩时非常加分。如果毕设要求带界面把 detect 逻辑封装成函数再用 PyQt 或 Gradio 包一层即可核心检测部分不用改。从那以后我每次拿到一个检测项目都强制自己走一遍「可视化标注→训练日志确认→置信度扫描→模型导出」四步流程数据格式没看明白之前绝不开训。这一套走完模型能不能用、边界在哪心里基本有数也不怕临时换机器演示。希望帮到你。本文还有配套的精品资源点击获取
返回列表