尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

基于Traffic-Net的轻量级交通拥堵识别:从数据准备到ONNX部署

发布时间:2026/9/26 5:12:06

资讯中心
01
ARTICLE

基于Traffic-Net的轻量级交通拥堵识别:从数据准备到ONNX部署

基于Traffic-Net的轻量级交通拥堵识别:从数据准备到ONNX部署
简介基于Traffic-Net的交通拥堵程度识别源码与配套数据集打包下载面向人工智能、计算机等相关专业的课程设计、毕业设计及入门进阶学习者。项目以Python深度学习实现提供完整可运行的训练代码可用于交通场景图像分类或拥堵等级识别等实验任务也适合在此基础上做二次开发。压缩包共10个文件主要包括Python脚本模型训练与预测、JSON配置文件模型结构与参数、Markdown/TXT说明文档使用说明与常见错误记录整体仅6KB结构精简便于快速部署与调试。目前已有49人学习下载。解压后即可对照文档运行资源还附带了排错提示可帮助使用者规避环境配置中的常见问题对于希望深入理解Traffic-Net网络设计或完成课设报告的同学这是一份低门槛、高参考价值的起步资料。1. Traffic-Net 做什么给路口摄像头一张截图说出堵不堵交通拥堵识别最容易被做成一个“看起来很壮丽”的工程接几十路摄像头、上智能分析平台、做大屏可视化。真到落地那天问题全冒出来——边缘盒子算力不够、夜间和雨雪天误报率飙升、标注数据得一张张框汽车。Traffic-Net 的定位恰好是把这件事缩到最小它不检测车辆也不跟踪轨迹只对整张路口截图做分类输出“畅通、缓行、拥堵、严重拥堵”四个等级。你需要的不是重型服务器而是一张低分辨率的 JPEG 帧和一个几十 MB 的模型权重。适合谁想用轻量级 CNN 跑通“摄像头图像 → 拥堵等级”这条链路的人不管是做毕设、做园区闸口改造还是给已有监控系统加一个道路状态输出。放在本文的场景里你拿到的就是一个可训练源码包加一批分类好的交通图像数据集能在本地机器上复现出完整的训练闭环。2. 网络结构为什么这样搭轻量不是省事是边缘端逼出来的先用一句话把这个包里的核心立住Traffic-Net 是为了“单张图分类”设计的轻量卷积网络不是检测器。很多人一提到交通识别就转头去跑 YOLOv5、YOLOv8 训练自己的数据集画框、做目标检测再自己算拥堵指数。这就是第一个弯路——检测只是手段拥堵等级才是业务结果而 Traffic-Net 直接预测结果建模成本低得多也更容易在低算力设备上跑起来。2.1 主干结构卷积 深度可分离卷积 池化为什么不用现成 MobileNet 直接跑Traffic-Net 的主干是典型的“堆卷积块 下采样”结构。输入统一缩放成 224×224×3前两层用普通 3×3 卷积快速把空间尺寸降下来中段用深度可分离卷积减少参数量最后接全局平均池化不再接全连接层。全局平均池化是这套结构里最关键的一手它把最后一个特征图直接压成一个长度等于类别数的向量省掉了全连接层里动辄上百万的权重矩阵。对比直接用 MobileNetV2 这类现成网络Traffic-Net 的优势不在精度而在可控。MobileNetV2 输入尺寸和通道数绑得比较死改输入分辨率要动全局池化后的结构而 Traffic-Net 的结构里你可以把最后一层特征图从 7×7 换成 14×14池化后照样输出四个数精度和速度自己平衡。对一张 224×224 的路口图常见做法是保持 8 倍下采样也就是最后特征图 28×28整个模型的参数量控制在 2M 左右比 MobileNetV2 的 3.4M 还少一截更关键的是它没有需要单独调宽度的超参数结构简单训练时的玄学问题少。我一般会用 ResNet18 当迁移学习的基底做对比实验但最终部署还是会回到 Traffic-Net。ResNet18 的瓶颈在第一个 7×7 大卷积上它非常吃显存你把它扔到显存只有 4G 的旧显卡上batch 只能开到 16训练效率很难看。Traffic-Net 的第一层就是 3×3 卷积显存占用平滑很多batch 开到 64 也没有压力。2.2 训练策略与迁移学习是加载 ImageNet 权重还是从零训练这是每个拿到源码包的人都要做的决定。Traffic-Net 在 ImageNet 上没有一个出厂自带的预训练权重因为它是针对交通场景自研的小网络。但你不必因此放弃迁移学习常见操作是取 ResNet18 的前几层卷积权重把通道数匹配的部分拷过来余下随机初始化。你的数据集如果只有几千张图这个操作能明显稳住前几个 epoch 的 loss 曲线如果图超过两万张从零训练反而更稳因为模型的输入分布监控视角、低照度、雨雾和 ImageNet 的日常物体分布差得太远预训练特征在早期反而帮倒忙。如果你嫌拷权重麻烦直接把 Traffic-Net 的深度加深也是一条路。源码包里的网络结构文件通常只包含基础版本你复现的时候可以在第三个卷积块后面再叠一个同样结构的 block通道数翻倍参数量会增加一半但对夜间场景的适应能力會好不少。这个取舍后面会细讲。3. 把原始视频变成数据集帧截图、csv 打标签和目录划分拿到源码包之后直接解压后第一件事不是跑训练而是先看清数据集长什么样。包里是一个按类别分好的图片文件夹加一份 CSV 标签表每行记录“图片文件名, 等级标签, 拍摄时间, 道路编号”。这个格式和你自己从监控录像里做数据是完全一致的所以这一章直接按“从零准备数据集”来讲比单纯介绍包里有什么更有用。3.1 从监控视频抽帧采样率与“同一条路不同时段”的取舍先把原始视频变成候选图片。常见做法是用 FFmpeg 按间隔抽帧命令就三行mkdir -p frames ffmpeg -i road01.mp4 -vf fps1/10 -q:v 2 frames/road01_%03d.jpg说明一下这里的两个点fps1/10 表示每 10 秒抽一帧你可以按 1/30 或 1/5 去调整。10 秒一帧对拥堵识别够用因为拥堵状态是分钟级的5 秒一帧只会让相邻帧高度相似白白增加数据冗余。q:v 2 是 JPEG 质量参数数字越小质量越高建议固定 2别用默认值默认值在画面里有大量车辆纹理时会压出明显色块影响后面的模型收敛。抽帧之后千万别急着全部打标。先每段视频抽 20 帧出来看一遍确认画面里有没有黑屏、断电重启、球机转动到天空这些无效画面。无效帧在数据集里占比一旦超过 5%训练出来的模型在真实路口会频繁跳变。这一步是后面所有标注工作的后悔药。3.2 标签写入 csv 与训练集、验证集、测试集划分打标环节最可靠的做法不是一张张看名字改而是先把抽好的帧导入一份 CSV人工只标“等级”列filename,level,time,road_id road01_001.jpg,0,2024-11-20 08:15:00,R01 road01_002.jpg,1,2024-11-20 08:15:10,R01 road01_003.jpg,2,2024-11-20 08:15:20,R01level 的取值建议固定为 0畅通、1缓行、2拥堵、3严重拥堵。不要用文字标签训练代码里做字符串到索引的映射会多一层出错的可能直接存数字。划分训练集时按时间切不要按文件随机切。比如同一个路口的早高峰视频前面 8 分钟进训练集、后面 2 分钟进验证集这样验证集才真正模拟了“模型没见过的时刻”的分布。随机切分在时间序列数据上是自欺欺人因为相邻帧几乎一模一样验证集分数会虚高。from sklearn.model_selection import train_test_split df pd.read_csv(labels.csv) # 按时间排序后按比例切防止随机切分导致的数据泄漏 train_df, val_df train_test_split( df.sort_values(time), test_size0.15, shuffleFalse, stratifyNone )这段代码里 stratify 刻意留空是有原因的。交通拥堵数据天然类别不均衡畅通帧通常占大头如果按类别比例强制抽样到训练集和验证集会让某个严重拥堵时刻的连续帧被拆得七零八落验证集里全是训练集里同一段画面的前后帧。正确做法是先按一段连续时间作为整体去分保证同一个时间窗口的视频帧只出现在一侧。3.3 数据增强的度随机裁剪、翻转与色彩扰动数据增强是这个小数据集项目里最值得投入时间的一步。对 Traffic-Net 这种小网络来说没有增强撑不住真实场景的多样性。下面是我常用的增强管道基于 PyTorch 的 torchvision 实现import torchvision.transforms as T train_transform T.Compose([ T.RandomResizedCrop(224, scale(0.7, 1.0)), T.RandomHorizontalFlip(p0.5), T.ColorJitter(brightness0.3, contrast0.3, saturation0.2, hue0.05), T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])RandomResizedCrop 的 scale 参数要解释一下。对交通路口画面如果你裁剪到 0.5很可能把画面中的一条车道完整裁掉模型反而学到了局部特征对整体拥堵判断不利。0.7 是经验值既能做尺度扰动又不至于破掉路口的空间关系。ColorJitter 亮度扰动 0.3 在白天数据上效果明显但如果你发现夜间帧训练时验证集 loss 不降这个值要降到 0.1 以下否则夜间低照度特征会被增强管道洗掉。验证集不要加任何随机增强只用 Resize(224) 和 Normalize否则你看到的验证指标里混合了增强噪声无法定位模型真实能力。4. 用 Traffic-Net 训练一个拥堵等级模型PyTorch 代码与参数数据准备妥当进入训练环节。不同源码包的组织方式差别不小但核心都是“读数据 → 建模型 → 训练循环 → 存 checkpoint”下面按这个主线给出一份可以直接替换的骨架代码你拿到任何一份 Traffic-Net 源码包都能用这套骨架把它跑起来。4.1 数据加载器txt 标签映射与归一化先把标签从 CSV 变成 PyTorch 能直接读的 Dataset。源码包里常用的是 ImageFolder 式目录结构也就是 train/0、train/1、train/2、train/3 这样的子目录但 CSV 里带了时间信息直接用 ImageFolder 会把时间信息丢掉。我更推荐自己写一个轻量 Dataset 子类把 time 字段一并读进来后面做时间维度分析时不用重新对齐from torch.utils.data import Dataset from PIL import Image class TrafficDataset(Dataset): def __init__(self, df, img_dir, transformNone): self.df df.reset_index(dropTrue) self.img_dir img_dir self.transform transform def __len__(self): return len(self.df) def __getitem__(self, idx): row self.df.iloc[idx] img Image.open(f{self.img_dir}/{row[filename]}).convert(RGB) if self.transform: img self.transform(img) return img, int(row[level])这里有个容易翻车的位置就是convert(RGB)。有的监控帧是灰度图有的带 alpha 通道如果你不强行转 RGB到模型里通道数会不一致训练时直接崩。这类问题只在训练到一半的时候冒出来报错信息还特别隐蔽所以提前在这行挡掉。4.2 训练循环loss、优化器、学习率调度与 checkpointTraffic-Net 是四分类任务损失函数直接选交叉熵。优化器选用 Adam 误打误撞能训出来但如果你想让结果更稳、对学习率不那么敏感SGD 加 momentum 才是常见落地做法import torch import torch.nn as nn model TrafficNet(num_classes4) criterion nn.CrossEntropyLoss() optimizer torch.optim.SGD( model.parameters(), lr0.01, momentum0.9, weight_decay1e-4 ) scheduler torch.optim.lr_scheduler.CosineAnnealingLR( optimizer, T_max30, eta_min1e-5 ) best_acc 0.0 for epoch in range(30): model.train() train_loss 0.0 for imgs, labels in train_loader: imgs, labels imgs.to(device), labels.to(device) optimizer.zero_grad() outputs model(imgs) loss criterion(outputs, labels) loss.backward() optimizer.step() train_loss loss.item() scheduler.step() val_acc evaluate(model, val_loader, device) if val_acc best_acc: best_acc val_acc torch.save({ epoch: epoch, model_state_dict: model.state_dict(), optimizer_state_dict: optimizer.state_dict(), best_acc: best_acc, }, traffic_net_best.pth) print(fEpoch {epoch:02d}, Loss: {train_loss/len(train_loader):.4f}, Val Acc: {val_acc:.4f})代码里两个设计直接关系到你能不能顺利训完。第一个是 CosineAnnealingLRT_max 为 30意味着学习率在 30 个 epoch 内从 0.01 余弦降到 1e-5。对交通拥堵这种类别差异不算尖锐的任务学习率不降下来最后几个 epoch 的验证集准确率会反复横跳。第二个是每轮都在验证集上跑一次并保存最优权重不要等全部训完才保存不然中途断电你前面十个 epoch 的白训了。checkpoint 里记得同时存优化器状态断点续训时如果不恢复优化器学习率调度会乱套。4.3 三个必须说明的训练参数batch size、学习率与 epoch 的联动batch size、学习率、epoch 三者不是独立参数而是一组联动值。源码包里如果给了默认参数通常对应的是“一张普通游戏显卡”的配置。你对这三个参数做调整时记住下面这几条对应关系batch size 设为 32 或 64 都合理但要注意学习率要跟着 batch size 线性缩放。你从 batch 64 降到 batch 32学习率也从 0.01 降到 0.005否则小 batch 下的梯度噪声大loss 曲线会像心电图。epoch 数量上Traffic-Net 不是那种需要几百轮的大模型核心特征是模型小、收敛快30 轮左右验证集就基本稳定如果你发现第 20 轮之后验证集准确率原地不动不要盲目加 epoch先去看学习率是不是已经降到 eta_min如果是直接改 T_max 而不是加轮数。weight_decay1e-4 是为防止小数据集上的过拟合但如果你训练数据只有两三千张把 weight_decay 调到 5e-4 会更好Traffic-Net 的卷积核数量少正则太弱会在第 10 轮以后明显看到训练 loss 和验证 loss 开始分道扬镳。5. 训练避坑记录5 个翻车现场和补救办法这部分是实际训练中反复遇到、且源码包自带的 README 里基本不会写的问题。每一条都是“现象 → 原因 → 解决”的真实流程你可以直接把对应检查手段当默认排错清单。5.1 翻车现场文件按名称排序后第 10 天永远排在前面第一坑出现在抽帧后文件排序上。用sorted(os.listdir(frames))对 road01_001.jpg、road01_002.jpg … road01_010.jpg 排序得到的结果是 road01_001、road01_002、road01_010字符串排序把 010 排到了 002 前面。如果你的 CSV 是用文件名拼接生成的前几张图和后面标签就对不上训练时看着 loss 在降实际学的全是错位对应。解决抽帧时文件名直接补零到三位以上或者读列表后按数字部分重新排序。用sorted(frames, keylambda x: int(re.search(r(\d), x).group()))处理最稳不要相信视觉上的顺序。5.2 翻车现场训练 loss 下降但验证 loss 反弹这个现象最经典表现为第二周训练时 loss 曲线一路向下验证集 loss 却从第 8 轮开始往上走。原因是数据量有限时Traffic-Net 的浅层特征在第 8 轮左右开始记住训练集里特定路口的纹理比如某个路口独有的路面标志、栏杆颜色。解决分两步。第一步先加验证集多样性把连续时间帧的划分边界往前提让验证集包含另一个路口的画面第二步配合 4.3 的 weight_decay 调大。如果调完第二轮验证集还反弹就回到 3.3 的增强管道把 RandomResizedCrop 的 scale 下限降低到 0.6强迫模型看更多局部特征。不要一上来就换更深的网络Traffic-Net 在几千张数据上不是欠拟合是过拟合。5.3 翻车现场夜间帧把模型带崩夜间监控画面整体偏暗车辆只亮出一对车灯轮廓拥堵和缓行在视觉上的差距远小于白天。你要是把白天夜间数据混在一起直接训验证结果白天 90% 夜夜 60%整体指标不好不坏但一部署到实际场景就现原形。解决训练集里单独建一个 time_period 列标记“白天/夜间”训练时按 0.7/0.3 的比例采样而不是按原始帧数比例。代码上简单实现就是给 Dataset 加一个采样权重。如果夜间数据实在不够用 3.3 里的 ColorJitter 把亮度扰动调到 0.05 以下然后对夜间帧做直方图均衡化预处理比在模型里加注意力模块更实际。5.4 翻车现场模型永远预测“畅通”这是类别不平衡的典型症状训练数据里畅通帧占 80%模型学到的捷径就是全部输出畅通整体准确率还高达 79%。验证集准确率同样虚高看起来一切正常。解决不用改动模型结构直接在损失函数里加类别权重。nn.CrossEntropyLoss(weighttorch.tensor([1.0, 2.0, 4.0, 6.0]))是个可参考的起点权重比按训练集各类别占比的倒数做平滑。注意权重别拉太狠严重拥堵的权重超过 8 之后模型会反过来把所有缓行都判成严重拥堵误报比漏报更难看。调整后同时把评估指标从准确率换成每类召回率的均值才能看清真实效果。5.5 翻车现场测试集准确率不错部署到摄像头就翻车测试集里 90%接到真实路口实时画面上就乱跳。原因通常是测试集和真实画面存在分辨率差异——测试集是直接从视频里截的帧部署时走的却是 RTSP 流解码后的画面后者经过缩放、隔行处理甚至 H.265 压缩纹理细节已经变了。另一大来源是角度测试集里一个固定机位部署机位偏了 10 度模型没见过。解决先在本地录制一条模拟 RTSP 流用部署代码跑一遍把输出逐帧存下来对比。如果识别结果频繁在畅通和缓行之间跳变就在模型输出后加一个长度为 15 帧的中值滤波取 15 帧内出现次数最多的类别作为最终结果。这类后处理写在部署代码里比重新训练简单管用得多。6. 验证与部署用混淆矩阵验收再决定要不要导出 ONNX训练结束后最后一公里是验证与部署。没有谁能单靠 val_acc 就确定一个模型能上线尤其是拥堵等级这种本身就存在模糊边界的分类任务。6.1 分类任务验收top-1 准确率和 Kappa 系数一起看对四分类任务我建议同时打印 top-1 准确率和 Cohen’s Kappa 系数。top-1 只反映整体正确率而 Kappa 衡量的是“除去随机一致后的一致性”对于类别不平衡的拥堵数据Kappa 掉到 0.6 以下说明模型虽然准确率有 85%但内部是在瞎猜。计算方式不复杂from sklearn.metrics import cohen_kappa_score preds_all [] labels_all [] model.eval() with torch.no_grad(): for imgs, labels in val_loader: outputs model(imgs.to(device)) preds outputs.argmax(dim1).cpu().numpy() preds_all.extend(preds) labels_all.extend(labels.numpy()) kappa cohen_kappa_score(labels_all, preds_all, weightsquadratic)weightsquadratic 会让“把严重拥堵判成畅通”的惩罚远大于“把严重拥堵判成拥堵”这符合业务直觉。交通拥堵等级是顺序尺度相近类别之间的误判可以容忍跨越度大的误判必须罚重。Kappa 值在 0.7 以上就具备灰度上线条件0.8 以上可以直接部署。6.2 导出 ONNX 并做一次性推理Traffic-Net 训练完怎么部署取决于目标硬件。最常见的做法是导出 ONNX 格式给推理框架用PyTorch 自带导出逻辑import torch.onnx model.eval() dummy_input torch.randn(1, 3, 224, 224) torch.onnx.export( model, dummy_input, traffic_net.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch}, output: {0: batch}}, opset_version11 )dynamic_axes 允许推理时 batch 不固定方便你做单帧推理。ONNX 导出后先不要直接丢上生产用 onnxruntime 在本地跑一张夜间验证帧与 PyTorch 输出做对比两者 logits 的差值应在 1e-4 级以内超出这个量级基本是某个算子在导出时被替换成了精度更低的版本。这个检查能帮你省掉在边缘盒子上来回烧固件的时间。6.3 那个迁移学习习惯每份新数据先扫一遍脏样本最后说一个我保留至今的训练习惯不管拿到什么数据集第一轮训练只跑 3 个 epoch然后找出验证集里置信度最高但预测错误的那 20 张图逐个放大看。这 20 张图通常能暴露 80% 的标签错误——比如“严重拥堵”帧里其实是车祸现场临时停车“畅通”帧里是红灯等待的静止车队。Traffic-Net 权重小、训练快这个扫脏样本的流程成本很低却比调十轮参数有用得多。实际跑过几个城市的交通数据之后我的感受是模型结构从来不是拥堵识别的主要瓶颈数据的时段覆盖度和标签质量才是。如果你把这一整个流程在本地完整跑通会发现自己对“模型为什么翻车”的判断力提升比模型本身的精度提升还值。希望这篇笔记能帮你少走一段弯路把 Traffic-Net 真正用起来。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。