YOLOV5交通标志识别检测:数据集、代码与模型实战指南
发布时间:2026/9/28 8:09:57 锦皓数字建站

简介这是一份面向毕业设计、期末大作业及课程设计场景的YOLOv5交通标志识别检测资源包覆盖数据集、可运行代码与预训练模型适合需要快速搭建目标检测项目的学生或初学者。资源包共266个文件压缩后约423MB其中包含Python脚本、YAML配置文件、JPG/JPEG图片样本、PNG图标、PT模型权重及训练日志等代码附有详细注释目录结构清晰便于直接部署与二次开发。当前已有112人学习下载项目经过严格调试功能完整且界面友好具备较高的实际应用价值。使用者下载后可按注释理解检测流程借助自带数据集与权重完成模型训练、验证和推理演示能够直接支撑答辩展示或作业提交。1. 为什么“YOLOV5交通标志识别检测数据集代码模型”是毕业设计里的省心之选每年到毕业设计中期检查前后总有人来问我“交通标志识别用什么方案最稳”。我的回答一直没变过别自己从零写检测器直接用 YOLOV5 的项目骨架、一套整理好的交通标志数据集、训练好的权重文件把精力花在数据清洗、参数调整和结果分析上。这套“YOLOV5交通标志识别检测数据集代码模型”组合本质上是把目标检测的完整链路打包好数据集负责喂料代码负责训练和推理模型权重负责让新手跳过三天三夜的训练等待。它能解决的是从零搭建环境到跑出检测框、再到写毕业论文的全过程痛点适合做毕业设计、课程大作业也适合那些想把深度学习检测塞进嵌入式演示但时间不够的人。它的价值不在算法多前沿而在把工程链路压缩到一星期内跑通。2. 先把环境与数据弄明白数据集结构和 YOLOV5 项目的对应关系2.1 交通标志数据集长什么样标签格式与目录布局拿到手的第一件事不是急着训练而是把数据集目录结构看清楚。常见做法是这套数据已经按 YOLO 格式整理好了也就是每张图片对应一个同名.txt标签文件文件里每行是“类别ID 中心点x 中心点y 框宽 框高”坐标值全部做了归一化范围在0到1之间。目录一般长这样traffic_sign_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ └── ... │ └── val/ │ ├── 000101.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ └── ... │ └── val/ │ ├── 000101.txt │ └── ... ├── data.yaml └── classes.txtdata.yaml是 YOLOV5 训练时直接读取的配置文件classes.txt是类别清单这两者必须保持一致。很多翻车案例都出在data.yaml写的类别名和classes.txt顺序对不上导致训练时类别映射错乱。建议拿到数据后先写一段五分钟的校验脚本检查图片和标签是否一一对应、标签里有没有越界坐标、类别ID是否超出nc数量。这一步能在训练前拦住90%的“loss 不下降”和“mAP 为 0”的诡异问题import os img_dir traffic_sign_dataset/images/train label_dir traffic_sign_dataset/labels/train for img_name in os.listdir(img_dir): label_name img_name.rsplit(., 1)[0] .txt label_path os.path.join(label_dir, label_name) if not os.path.exists(label_path): print(f缺标签: {img_name}) continue with open(label_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(f格式错误: {label_name}: {line}) continue _, cx, cy, w, h parts if not all(0 float(x) 1 for x in (cx, cy, w, h)): print(f坐标越界: {label_name}: {line})这段代码做的是最基础的完整性检查遍历训练图片目录找缺失的标签文件同时检查每行坐标是否都在0到1的合法范围内。逻辑很简单但非常重要——交通标志数据集里经常混入从不同来源爬来的图片标注工具不同有的把坐标存成了像素值有的标签文件是空的这些都会直接导致训练崩溃或指标异常。2.2 用 conda 把 YOLOV5 环境装好CUDA、torch 与显存取舍环境配置是这个项目里第一个劝退点。我自己踩过的坑是直接用pip install torch装到 CPU 版训练到一半发现慢得离谱白等了两小时。正确做法是先创建独立的 conda 环境再根据显卡型号选择对应 CUDA 版本的 PyTorch。conda create -n yolov5 python3.8 -y conda activate yolov5 # 先看显卡驱动支持的 CUDA 版本 nvidia-smi # 以 CUDA 11.8 为例安装对应 torch 和 torchvision pip install torch2.0.1 torchvision0.15.1 --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txtnvidia-smi输出的右上角是驱动支持的最高 CUDA 版本安装的 PyTorch CUDA 版本不能高于它。用--index-url指定安装源是为了避免 pip 默认装成 CPU 版。requirements.txt是 YOLOV5 项目自带的依赖清单里面有 numpy、opencv-python、matplotlib 这些基础库直接用 pip 安装即可。装完后用python -c import torch; print(torch.cuda.is_available())验证输出True才算环境合格。如果显卡显存只有 4G 甚至更小我一般不建议硬上 YOLOV5s 的默认配置而是把batch-size调到 4 或 2同时把--workers降到 0避免数据加载进程抢占显存。要是连 2G 都不到就别折腾本地训练了直接把训练放到云 GPU 上跑本地只做推理。2.3 数据划分训练/验证集分配要避开的一个坑很多现成数据集已经划分好了训练集和验证集但有一部分只给了全部图片需要自己划分。常见的划分比例是 8:1:1训练:验证:测试或者更随意一点 9:1。这里最容易翻车的是对图片做随机划分时没有考虑同一场景的连续帧可能同时出现在训练集和验证集里导致验证指标虚高。import os import random from shutil import copy2 random.seed(42) img_dir traffic_sign_dataset/images/all label_dir traffic_sign_dataset/labels/all out_dir traffic_sign_dataset os.makedirs(f{out_dir}/images/train, exist_okTrue) os.makedirs(f{out_dir}/images/val, exist_okTrue) os.makedirs(f{out_dir}/labels/train, exist_okTrue) os.makedirs(f{out_dir}/labels/val, exist_okTrue) imgs [f for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(imgs) split_idx int(len(imgs) * 0.9) for i, img in enumerate(imgs): subset train if i split_idx else val label img.rsplit(., 1)[0] .txt copy2(os.path.join(img_dir, img), f{out_dir}/images/{subset}/{img}) copy2(os.path.join(label_dir, label), f{out_dir}/labels/{subset}/{label}) print(f{img} - {subset})这段脚本的核心在于random.seed(42)固定随机种子保证每次运行划分结果一致方便复现实验。90% 的图片进训练集10% 进验证集。注意复制的是图片和标签两个文件如果漏了标签文件YOLOV5 训练时会报“找不到对应标签”的警告那张图会被直接跳过。3. 把模型训练起来从默认参数到能答辩的结果3.1 修改数据配置文件data.yaml 里的三个关键字段环境装好、数据校验通过后第一步是改data.yaml。这个文件是 YOLOV5 训练的数据入口里面有三个字段必须改对path数据集根目录、train训练图片相对路径、val验证图片相对路径以及nc类别数和names类别名列表。# data.yaml path: C:/Users/your_name/traffic_sign_dataset # 换成你的绝对路径避免相对路径找不到 train: images/train val: images/val nc: 4 # 按实际类别数改 names: 0: speed_limit 1: stop 2: traffic_light 3: crosswalk绝对路径在这一步最省事。YOLOV5 对相对路径的解析逻辑在不同版本里有些差异写成绝对路径可以少踩一个坑。nc必须和标签文件里的最大类别 ID 匹配比如标签里出现了3但nc3训练会直接报索引越界。names的顺序要和classes.txt保持一致因为推理时输出的类别名就靠这个映射。3.2 选哪个预训练权重s/m/l 在交通标志任务上的取舍YOLOV5 官方提供了yolov5s.pt、yolov5m.pt、yolov5l.pt三个常用预训练权重它们只有网络宽度和深度不同使用方式完全一样。选择标准不是越大越好而是看你的硬件和任务复杂度。交通标志检测属于中等难度目标检测目标通常不大但类别数量少常见数据集就十几种背景相对固定道路场景。这种情况下yolov5s完全够用训练速度快显存占用低。yolov5m在某些小目标上的召回会稍微好一点但训练时间几乎翻倍。yolov5l除非你要在答辩时强调“高精度大模型”否则不推荐——训练时长和显存开销会让毕业设计失去意义。一个取巧做法是用yolov5s.pt训练一轮再用训练好的权重作为--weights继续训练也就是二次迁移。这种方式能缩短训练周期尤其适合数据量只有几千张的中小规模数据集。3.3 训练命令与超参数batch-size、epochs、imgsz 怎么定训练命令本身不复杂复杂的是参数选择。我给一个可以直接抄的模板python train.py \ --data data.yaml \ --weights yolov5s.pt \ --batch-size 16 \ --epochs 100 \ --img 640 \ --workers 4 \ --device 0 \ --project runs/train \ --name traffic_sign_experiment--batch-size 16是显存 8G 的稳妥值显存小就降到 8 或 4。--epochs 100在数据集几千张的情况下够用了再多容易过拟合。--img 640是输入分辨率交通标志在整张图中的占比通常只有 5% 到 10%如果条件允许可以调到 960小目标检测效果会明显提升但显存占用和训练时间会同步增加。--workers 4是数据加载线程数Windows 下如果报错就改成 0。训练日志里最需要关注的是val mAP0.5这个指标。前 20 个 epoch 它可能会在低位震荡这是正常的如果 50 个 epoch 后还在 0.1 以下基本可以断定数据集有问题或超参数不适合别傻等 100 个 epoch 跑完。另外开启--cache参数可以把图片缓存到内存里加速训练前提是内存足够大16G 以上。数据集有几万张图时每次从磁盘读图片的 IO 开销会占到训练总时间的 30% 以上--cache能把这部分省掉代价是一开始要等几分钟做缓存。4. 训练到部署的五个翻车点避坑与常见问题排查4.1 标注框和类别对不齐loss 正常但 mAP 为 0现象训练正常推进loss 曲线也在下降但验证集的 mAP0.5 一直为 0偶尔出现异常值。原因最常见的是data.yaml里nc数量和标签文件里的类别 ID 不匹配。比如标签里有一种类别 ID 是 5但nc4模型预测时只输出 4 个类别ID 为 5 的目标永远无法被正确匹配。另一种情况是names顺序和实际类别不对应导致指标计算时类别映射错位。解决先按 2.1 节的校验脚本跑一遍把所有标签的类别 ID 提取出来求最大值和nc-1比较。如果不匹配要么改nc要么写脚本把所有标签文件里的类别 ID 重新映射。4.2 小目标漏检交通标志占比太小imgsz 和 anchors 要调现象训练完在测试图上跑远处的交通标志检测不到近处的正常或者小标志的 confidence 普遍低于 0.3被非极大值抑制滤掉。原因原图 1920x1080 下一个 40x40 像素的交通标志经过 640x640 缩放后只剩约 13x13 像素接近 8 倍下采样后的特征图网格尺寸特征信息几乎丢失。YOLOV5 默认的 anchors 也偏大对这种小目标召回率天然不足。解决把--img从 640 提升到 960 或 1280小目标的像素占比会按比例提升同时开启--multi-scale让模型在训练时随机变换输入尺寸增强对不同尺度目标的适应能力。如果训练后还是漏检再考虑用--evolve重新进化 anchors但这个操作比较耗时非必要不推荐。4.3 显存不够低显存跑模型的梯度累积方案现象训练时直接报CUDA out of memory或者跑到十几个 batch 后显存溢出。原因batch-size太大或者输入分辨率太高。8G 显存跑--img 640 --batch-size 16勉强可行跑--img 1280即使 batch-size 降到 4 也会爆。解决YOLOV5 支持梯度累积通过--batch-size 4 --accumulate 4实现等效的 batch-size 16 效果。代价是训练速度略慢但对显存的要求大幅降低。另外把--workers 0加上数据加载线程有时候也会额外吃显存。注意梯度累积只影响训练时优化器更新权重的频率不影响验证阶段的前向计算。验证时如果爆显存要把--batch-size调低或直接设为 1。4.4 CPU 推理慢模型导出后输出结果不对现象训练好的.pt文件在 CPU 上跑一张图要两三秒无法接受导出成 ONNX 后用 OpenCV 推理检测框完全错乱。原因CPU 推理慢是正常的PyTorch 的模型没有经过优化。导出 ONNX 后结果不对大概率是输入预处理没做对齐——YOLOV5 训练时做了 letterbox 填充保持宽高比的前提下缩放并填充灰色边推理时也要做同样的操作否则坐标偏移全乱了。解决推理前用letterbox函数把原图缩放到 640x640自动补边推理完成后把检测框坐标映射回原图尺寸。操作步骤见第 5 章。4.5 中文路径和特殊字符导致的读取失败现象训练一切配置正确但一启动就报FileNotFoundError或UnicodeDecodeError。原因Windows 下数据集路径带中文或空格PyTorch 的 DataLoader 在 Windows 多进程模式下对非 ASCII 路径支持不佳导致图片读取失败。解决把整个项目和数据集的路径全部改为纯英文不要放在“桌面”这种路径下。如果实在要保留中文目录就把--workers 0开启单进程读取可以绕过这个限制但训练速度会慢一些。这是最常见的 Windows 环境坑我一般在配置环节就提醒学生提前处理。5. 把模型用起来导出、推理与做一个小型演示界面5.1 用 torch.hub 在本地跑通推理的完整流程训练完成后第一个验证动作是用 YOLOV5 自带的detect.py跑一张测试图但这只是验证模型可用性。真正要写到论文里、或者做成演示系统的是用torch.hub加载本地权重做推理import torch import cv2 from PIL import Image model torch.hub.load( yolov5, # 本地 YOLOV5 仓库路径 custom, pathruns/train/traffic_sign_experiment/weights/best.pt, sourcelocal ) model.conf 0.35 # 置信度阈值 model.iou 0.45 # NMS 的 IoU 阈值 img cv2.imread(test_images/stop_sign.jpg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) results model(img_rgb) results.show() results.print()torch.hub.load第一个参数是本地 YOLOV5 仓库的路径第二个参数custom表示加载自定义权重path指向训练保存的best.ptsourcelocal表示不从网上下载权重。conf和iou是推理阶段两个最常用的调控参数conf0.35意味着低于 35% 置信度的检测框会被丢弃iou0.45控制重叠区域的去重力度数值越低重叠的框越容易被合并。交通标志检测场景下conf设在 0.3 到 0.45 之间比较合适——太低会冒出一堆误检框太高会把远处的小目标全滤掉。5.2 导出 ONNXopset 与动态尺寸的取舍.pt文件只能在 PyTorch 环境里跑想脱离深度学习框架做推理就得导成 ONNX 格式。YOLOV5 仓库提供了现成的导出脚本python export.py \ --weights runs/train/traffic_sign_experiment/weights/best.pt \ --include onnx \ --opset 12--opset 12是兼容性比较好的版本号ONNX Runtime 对它的支持很成熟。如果后续要在 Windows 的老机器上用 CPU 推理opset 12比opset 13更稳。导出后建议用 ONNX Runtime 验证一下import onnxruntime as ort import numpy as np session ort.InferenceSession(best.onnx) input_name session.get_inputs()[0].name # 输入必须是 [1,3,640,640] 的 float32 张量 dummy_input np.random.randn(1, 3, 640, 640).astype(np.float32) outputs session.run(None, {input_name: dummy_input}) print(outputs[0].shape) # 期望 (1, 25200, 85) 左右输出形状的第二维是 25200对应 640x640 输入下三个尺度特征图的预测总和85 是 4 个框坐标 1 个置信度 80 个类别概率。如果你的数据集类别数是 4这个值是 459也就是输出会是(1, 25200, 9)。这个检查能确认导出是否成功。5.3 用 OpenCV 调用 ONNX 做实时视频检测导出 ONNX 的意义在于可以用轻量级推理引擎部署到普通 CPU 机器上甚至写一个实时视频检测程序。下面是一个用 OpenCV 读取摄像头、用 ONNX Runtime 做推理的最小实现框架import cv2 import onnxruntime as ort import numpy as np session ort.InferenceSession(best.onnx) input_name session.get_inputs()[0].name cap cv2.VideoCapture(0) def letterbox(img, size640): h, w img.shape[:2] scale min(size / w, size / h) nw, nh int(w * scale), int(h * scale) resized cv2.resize(img, (nw, nh)) canvas np.full((size, size, 3), 114, dtypenp.uint8) canvas[(size - nh) // 2:(size - nh) // 2 nh, (size - nw) // 2:(size - nw) // 2 nw] resized return canvas, scale, (size - nw) // 2, (size - nh) // 2 while True: ret, frame cap.read() if not ret: break input_img, scale, pad_x, pad_y letterbox(frame, 640) blob input_img[:, :, ::-1].transpose(2, 0, 1)[None] / 255.0 blob blob.astype(np.float32) outputs session.run(None, {input_name: blob})[0] # 解析 outputs去掉低于 conf 阈值的框映射回原图坐标 # 这部分按 YOLOV5 decode 逻辑处理 for det in outputs[0]: conf det[4] if conf 0.35: continue x1, y1 int((det[0] - pad_x) / scale), int((det[1] - pad_y) / scale) x2, y2 int((det[2] - pad_x) / scale), int((det[3] - pad_y) / scale) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imshow(traffic sign detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()letterbox函数是这里的关键它把任意尺寸的输入帧等比缩放到 640x640并在边缘补灰色像素。推理完成后坐标映射的公式(det[0] - pad_x) / scale把填充后的坐标还原到原图坐标系这一步丢了检测框就会全部漂移。注意输入张量做了[:, :, ::-1]操作这是把 BGR 转成 RGB和训练时的预处理对齐。6. 答辩前最值得做的一件事用测试集批量验证并生成指标报告很多人在训练完、demo 跑通后就以为完工了但答辩老师最常问的是“你这个模型精度到底有多少”。与其嘴上说“效果挺好的”不如跑一遍批量验证把 Precision、Recall、mAP0.5、mAP0.5:0.95 四个指标打出来贴在论文里。YOLOV5 的val.py已经把这个过程封装好了python val.py \ --data data.yaml \ --weights runs/train/traffic_sign_experiment/weights/best.pt \ --img 640 \ --batch-size 8 \ --conf-thres 0.35 \ --iou-thres 0.45跑完之后runs/val/exp目录里会有confusion_matrix.png、PR_curve.png、F1_curve.png等图表这些图直接放进毕业论文里就能撑起一个章节。其中混淆矩阵能直观看到哪些类别之间互相误检——比如“限速标志”和“解除限速标志”外观相似如果混淆矩阵里这两类的交叉点颜色很深说明模型在这对类别上区分度不够可以考虑增加对应类别的训练样本数量。进阶验证建议拉一段未参与训练的实拍视频跑批量推理逐帧保存检测结果做成一段带检测框的视频作为演示素材。时间轴上有连续帧的检测框抖动能看出模型的稳定性也能侧面验证有没有过拟合到训练集的特定场景。最后提一句我自己的习惯所有实验结果都归档到命名带日期的目录里答辩前一周再重新跑一次完整验证流程确保论文里的指标是最后这个权重跑出来的而不是中途某个半成品实验的数字。这个习惯救过我很多次希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。