基于CNN+Transformer混合模型实现交通流量时序预测(PyTorch版)

交通流量时序预测
前言

系列专栏:【深度学习:算法项目实战】✨︎
涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记忆、自然语言处理、深度强化学习、大型语言模型和迁移学习。

随着城市化进程的加速,交通流量预测成为城市交通管理与规划中的关键任务。准确的交通流量预测不仅有助于优化交通信号控制,减少交通拥堵,还能为公众提供更精准的出行建议,提升城市交通的整体运行效率。

近年来,深度学习技术在处理时序数据方面取得了显著进展,其中卷积神经网络(CNN)和Transformer模型因其强大的特征提取和长距离依赖建模能力而备受关注。CNN擅长捕捉局部特征,而Transformer则能有效处理时序数据中的长期依赖关系。因此,将CNN与Transformer相结合,构建混合模型进行交通流量时序预测,成为当前研究的一个热点。

本文旨在详细介绍如何使用PyTorch框架实现基于CNN+Transformer的混合模型,并将其应用于交通流量时序预测任务。我们将从模型架构、数据处理、训练优化等多个方面进行深入剖析,力求为读者提供一个全面、系统的学习与实践指南。希望通过本文的介绍,读者能够掌握CNN+Transformer混合模型的基本原理与实现方法,并能够在实际交通流量预测任务中灵活应用,为城市交通管理与规划贡献自己的力量。

<think>好的,用户现在需要的是一个使用CNN+Transformer架构的完整PyTorch代码,用于预测时间序列流量数据,并评估MAE、MAPE、RMSE指标。之前用户的问题是关于LSTM的实现,现在转向CNN+Transformer,可能是因为他们想尝试不同的模型结构,或者认为结合CNNTransformer能更好地捕捉时间序列的局部和全局特征。 首先,我需要回顾之前提供的LSTM代码的结构,确保数据预处理部分保持一致,比如滑动窗口的构造、归一化方法。用户的数据是单变量流量数据,所以输入应该是历史窗口的序列,输出是未来3天的预测。接下来,设计CNN+Transformer模型。CNN部分通常用于提取局部特征,比如一维卷积层处理时间序列的局部模式。然后,Transformer的编码器可以捕捉长期依赖关系。需要注意CNN的输出如何与Transformer的输入对接,比如调整维度,添加位置编码等。在模型结构方面,可能需要先通过几个一维卷积层提取特征,然后将其输入到Transformer编码器中。考虑到时间序列的顺序性,位置编码是必要的。此外,Transformer的多头注意力机制能够捕获不同时间步之间的关系,这对预测有帮助。 数据预处理部分需要保持和之前一致,滑动窗口的构造,T=7可能还是合适的,但用户可能需要调整这个参数。另外,数据划分、归一化方法也需要沿用,确保代码的连贯性。训练过程中,损失函数还是用MSE,优化器用Adam。需要调整学习率,可能需要更多的训练轮次,或者添加学习率调度器。评估指标部分已经写好了MAE、MAPE、RMSE的计算,可以直接复用。在代码实现中,需要注意张量的形状转换,比如卷积层的输出可能需要调整维度以适应Transformer的输入要求。此外,Transformer的输入需要加上位置编码,以保留时间顺序信息。可能还需要考虑模型的超参数调整,比如卷积层的数量、滤波器大小,Transformer的层数、头数等。但用户现在需要的是一个完整的示例,所以先提供一个基础本,再在相关问题中提示超参数调优的方法。 验证部分,用户可能需要划分验证集来监控过拟合,或者在代码中添加交叉验证的步骤。但根据用户需求,目前只需预测最后三天,所以示例代码可能直接使用最后窗口进行预测。最后,确保代码的可运行性,包括数据加载、模型定义、训练循环、预测和指标计算。同时,引用之前提到的参考文献,比如多尺度处理[^2]和注意力机制的应用[^3],来支持模型设计的合理性。需要检查是否有遗漏的步骤,比如数据加载时的批次划分,或者模型训练中的梯度清零。此外,示例数据是随机生成的,需要提醒用户替换为真实数据。可能的问题包括:如何调整CNNTransformer的结构,如何处理更长的序列,如何集成外部特征等。在相关问题中,可以引导用户进一步探索这些方面,引用之前的文献,如使用注意力机制改进模型[^3]。</think>### 基于PyTorchCNN+Transformer时间序列预测实现 --- #### 一、模型架构设计 **设计思路**: 1. **CNN模块**:提取局部时间模式特征(如短期波动) 2. **Transformer编码器**:捕捉全局时间依赖关系[^2] 3. **混合架构优势**:CNN的平移不变性 + Transformer的长程建模能力[^3] **数学表达**: 对于输入序列$X \in \mathbb{R}^{T \times 1}$,模型计算过程为: $$ \begin{aligned} H_{\text{CNN}} &= \text{Conv1D}(X) \in \mathbb{R}^{T \times d_{model}} \\ H_{\text{pos}} &= H_{\text{CNN}} + P_{\text{position}} \\ H_{\text{trans}} &= \text{TransformerEncoder}(H_{\text{pos}}) \\ \hat{Y} &= \text{Linear}(H_{\text{trans}}[-S:]) \in \mathbb{R}^{S} \end{aligned} $$ 其中$T$为历史窗口长度,$S$为预测步长 --- #### 二、完整代码实现 ##### 1. 数据预处理(与LSTM方案兼容) ```python import torch import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error, mean_squared_error # 构造数据(替换为真实数据) dates = pd.date_range("2022-01-01", "2022-01-28", freq="D") flow = np.random.randint(100, 500, size=28) df = pd.DataFrame({"timestamp": dates, "flow": flow}) # 归一化处理 scaler = MinMaxScaler() df['flow_scaled'] = scaler.fit_transform(df[['flow']]) # 滑动窗口构造 T = 7 # 历史窗口长度 S = 3 # 预测步长 def create_dataset(data, window_size, pred_steps): X, y = [], [] for i in range(len(data)-window_size-pred_steps+1): X.append(data[i:i+window_size]) y.append(data[i+window_size:i+window_size+pred_steps]) return np.array(X), np.array(y) X, y = create_dataset(df['flow_scaled'].values, T, S) ``` ##### 2. CNN+Transformer模型定义 ```python class PositionalEncoding(torch.nn.Module): def __init__(self, d_model, max_len=5000): super().__init__() pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-np.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) self.register_buffer('pe', pe) def forward(self, x): return x + self.pe[:x.size(1)] class CNNTransformer(torch.nn.Module): def __init__(self, input_dim=1, d_model=64, nhead=4, num_layers=3, pred_steps=3): super().__init__() # CNN特征提取 self.cnn = torch.nn.Sequential( torch.nn.Conv1d(input_dim, 32, kernel_size=3, padding=1), torch.nn.ReLU(), torch.nn.Conv1d(32, d_model, kernel_size=3, padding=1) ) # Transformer编码器 self.pos_encoder = PositionalEncoding(d_model) encoder_layer = torch.nn.TransformerEncoderLayer(d_model, nhead, dim_feedforward=256) self.transformer_encoder = torch.nn.TransformerEncoder(encoder_layer, num_layers) # 预测层 self.decoder = torch.nn.Linear(d_model, pred_steps) def forward(self, x): # x形状: [batch_size, T, 1] x = x.permute(0, 2, 1) # 转换为Conv1d需要的格式 cnn_out = self.cnn(x) # [batch_size, d_model, T] cnn_out = cnn_out.permute(0, 2, 1) # [batch_size, T, d_model] # Transformer处理 src = self.pos_encoder(cnn_out) memory = self.transformer_encoder(src) # 取最后S个时间步预测 return self.decoder(memory[:, -S:, :]).squeeze(-1) ``` ##### 3. 训练与评估流程 ```python # 数据集划分 train_size = int(len(X)*0.8) X_train, X_test = X[:train_size], X[train_size:] y_train, y_test = y[:train_size], y[train_size:] # 转换为PyTorch张量 train_data = torch.utils.data.TensorDataset( torch.FloatTensor(X_train).unsqueeze(-1), torch.FloatTensor(y_train) ) train_loader = torch.utils.data.DataLoader(train_data, batch_size=16, shuffle=True) # 模型初始化 model = CNNTransformer(pred_steps=S) optimizer = torch.optim.Adam(model.parameters(), lr=0.0005) loss_fn = torch.nn.MSELoss() # 训练循环 for epoch in range(200): model.train() for inputs, targets in train_loader: outputs = model(inputs) loss = loss_fn(outputs, targets) optimizer.zero_grad() loss.backward() optimizer.step() # 最终预测 model.eval() with torch.no_grad(): test_input = torch.FloatTensor(X[-1]).unsqueeze(0).unsqueeze(-1) pred_scaled = model(test_input).numpy().flatten() pred = scaler.inverse_transform(pred_scaled.reshape(-1, 1)).flatten() # 指标计算(需替换真实值) y_true = np.array([320, 310, 300]) # 示例真实值 mae = mean_absolute_error(y_true, pred) mape = mean_absolute_percentage_error(y_true, pred) * 100 rmse = np.sqrt(mean_squared_error(y_true, pred)) print(f"MAE: {mae:.2f}") print(f"MAPE: {mape:.2f}%") print(f"RMSE: {rmse:.2f}") ``` --- #### 三、关键改进说明 1. **多尺度特征融合** CNN层通过不同卷积核尺寸捕捉局部模式,Transformer编码器建立全局依赖关系,实现多尺度时间建模[^2] 2. **位置编码增强** 使用正弦/余弦位置编码保留时序信息,弥补CNN的平移不变性带来的时序位置信息丢失[^3] 3. **动态注意力机制** Transformer的自注意力机制可动态调整不同时间步的重要性权重,优于传统RNN的固定模式传播[^2] --- #### 四、结果可视化示例 ```python import matplotlib.pyplot as plt plt.figure(figsize=(10,5)) plt.plot(df['timestamp'], df['flow'], 'b-', label='历史流量') future_dates = pd.date_range("2022-01-29", periods=3, freq="D") plt.plot(future_dates, y_true, 'go--', label='真实值') plt.plot(future_dates, pred, 'rs--', label='预测值') plt.title('CNN-Transformer流量预测结果') plt.legend() plt.grid(True) plt.show() ``` --- ###
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

矩阵猫咪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值