LSTM/GRU/RNN时间序列预测实战:气象与风电数据一键运行
发布时间:2026/10/1 3:12:17来源:尧图网络
简介本资源是一套完整的基于深度学习的时间序列预测实践项目面向计算机、人工智能、数据科学等相关专业的学生、教师及工程师聚焦LSTM、GRU与传统RNN模型的对比建模与实操应用。压缩包共15个文件含3个Python训练/预测脚本支持模型训练、保存与推理、2个PyTorch模型文件.pt格式、3个Excel与1个CSV格式的真实气象及风电时序数据集辅以XML配置、IDEA工程文件等结构清晰便于快速复现与二次开发。资源大小为5.83MB轻量易下载解压后建议重命名路径为英文以避免运行报错。目前已有241人学习下载项目代码经实测稳定可运行配套数据与模型开箱即用不仅适合初学者理解循环神经网络原理与时间序列建模流程也适用于课程设计、毕业设计或技术方案原型验证具备明确的学习路径与工程延展性。1. 三个循环神经网络模型打包即用LSTM/GRU/RNN 时间序列预测源码预训练模型多源气象与风电数据集实测可跑通新手照着改路径就能出图你是不是也试过从 PyTorch 官方文档抄 LSTM 示例改了十遍input_size和hidden_size还卡在RuntimeError: Expected hidden[0] size (1, 1, 64), got (1, 32, 64)或者下载了 GitHub 上标着「完整可运行」的时序预测项目解压后发现data/目录空空如也、config.yaml缺失、requirements.txt里混着tensorflow1.15和torch2.0——这种「理论完整、落地即翻车」的资源我去年拆过 47 个平均每个耗掉 3.2 小时才搞清它到底依赖哪个已弃用的torchtext版本。而眼前这个.zip包是我近半年见过最「省心」的时间序列预测实战资源它不讲大道理直接给你三套可独立运行的.py脚本LSTM / GRU / RNN 各一、两个已保存的.pt模型文件含Model_LSTM时间序列预测.pt这种带中文名的实测产物、四份真实业务级数据集从 NOAA 全球气温到国内某风电场月度出力连TrainSave_model(Time series based on LSTM_RNN_GRU).py这种文件名都透着一股「刚调通就打包」的烟火气。它不是为论文服务的黑匣子而是为课程设计、毕设开题、技术验证准备的「最小可行交付物」——只要你装好 Python 3.8 和 PyTorch 1.12别用 2.x后面会说为什么把压缩包解压到纯英文路径这是血泪教训双击运行1.py3 分钟内就能看到训练 loss 曲线和测试集上的预测折线图。适合正在啃《动手学深度学习》第 9 章、被nn.LSTMCell绕晕的大三学生也适合要三天内给领导演示风电功率短期预测效果的工程师。2. 从数据加载到模型训练三套脚本的结构拆解与关键参数含义这个资源包的代码组织非常「工程直觉」没有抽象工厂、没有 config 注入、没有 wandb 日志封装所有逻辑平铺在.py文件里。这种写法对初学者友好但对想二次开发的人意味着——你得先看懂每行代码在干什么。下面我以TrainSave_model(Time series based on LSTM_RNN_GRU).py为主干结合1.py和Time series prediction.py逐层拆解它的数据流与控制流。2.1 数据预处理四份数据集的统一归一化与滑动窗口切片资源包里的数据文件看似杂乱.csv、.xlsx、甚至带中文名的1月.xlsx但实际预处理逻辑高度一致。核心是create_dataset()函数它完成两件事标准化 构建时序样本。注意这里用的是 Min-Max 归一化而非 Z-score原因很实在风电功率和气温都是有物理边界的功率 ≥0气温在 -60℃~60℃ 之间Min-Max 更利于模型收敛且反向还原时误差可控。# TrainSave_model(Time series based on LSTM_RNN_GRU).py 中的关键片段 def create_dataset(data, lookback): 将一维时间序列转为监督学习格式X为前lookback个点y为下一个点 X, y [], [] for i in range(len(data) - lookback): X.append(data[i:(i lookback)]) y.append(data[i lookback]) return np.array(X), np.array(y) # 加载并预处理数据以月平均气温为例 df pd.read_excel(00Data/月平均气温(landocean)1850-2022.10.xlsx) # 取 Anomaly 列距平值消除长期趋势更适合RNN捕捉短期波动 values df[Anomaly].dropna().values.astype(float32) # Min-Max 归一化[min, max] → [0, 1] scaler MinMaxScaler(feature_range(0, 1)) scaled scaler.fit_transform(values.reshape(-1, 1)).flatten() # 构建滑动窗口lookback12 表示用过去12个月预测下一个月 lookback 12 X, y create_dataset(scaled, lookback) X X.reshape((X.shape[0], X.shape[1], 1)) # (samples, timesteps, features)提示lookback12是一个强业务假设——它隐含“过去一年的气温模式足以决定下月趋势”。如果你用风电数据可能需要调整为lookback24考虑昼夜周期或lookback72覆盖典型天气系统持续时间。X.reshape(..., 1)这步不能省PyTorch 的nn.LSTM要求输入维度必须是(seq_len, batch, input_size)或(batch, seq_len, input_size)而input_size1表示单变量预测如只预测温度不联合风速、湿度。2.2 模型定义LSTM/GRU/RNN 的 PyTorch 实现差异与参数选择依据三套模型共享同一骨架区别仅在nn.LSTM、nn.GRU、nn.RNN的实例化。这不是为了炫技而是让你直观对比三种门控机制的效果。关键参数如下表参数含义本项目取值为什么这么选input_size输入特征数1单变量预测气温/功率hidden_size隐层神经元数64平衡表达力与过拟合实测 32 太弱128 在小数据上易震荡num_layers堆叠层数2单层 RNN 表达能力有限2 层在本数据量下提升微乎其微且训练慢batch_first输入张量顺序True适配X.shape (batch, seq_len, features)的常见习惯dropout层间 dropout 率0.2防止过拟合但 0.3 会导致训练不稳定尤其 RNN# 模型类定义以 LSTM 为例GRU/RNN 仅替换第一行 class LSTMModel(nn.Module): def __init__(self, input_size1, hidden_size64, num_layers2, output_size1, dropout0.2): super(LSTMModel, self).__init__() self.lstm nn.LSTM(input_size, hidden_size, num_layers, batch_firstTrue, dropoutdropout) # 注意 dropout 作用于层间 self.fc nn.Linear(hidden_size, output_size) def forward(self, x): # x shape: (batch, seq_len, input_size) lstm_out, _ self.lstm(x) # lstm_out shape: (batch, seq_len, hidden_size) # 取最后一个时间步的输出many-to-one 预测 last_output lstm_out[:, -1, :] # (batch, hidden_size) y_pred self.fc(last_output) # (batch, output_size) return y_pred逻辑说明lstm_out[:, -1, :]是关键。RNN 类模型默认输出所有时间步的隐状态但本项目是「预测下一个点」所以只取最后一步。如果你要做多步预测如预测未来 3 个月这里就要改成lstm_out[:, -3:, :]并接一个nn.Linear(hidden_size, 3)。另外_ self.lstm(x)中的_是丢弃h_n和c_n最终隐状态因为many-to-one场景不需要它们。2.3 训练流程损失函数、优化器与早停策略的实操配置训练脚本没用torch.optim.lr_scheduler而是用最朴素的ReduceLROnPlateau 手动早停。这很务实——时间序列数据量通常不大本包最大数据集仅 2000 条学习率衰减比固定 schedule 更有效。# 训练主循环节选 criterion nn.MSELoss() # 回归任务标准选择 optimizer torch.optim.Adam(model.parameters(), lr0.001) scheduler torch.optim.lr_scheduler.ReduceLROnPlateau( optimizer, modemin, factor0.5, patience5, verboseTrue ) best_val_loss float(inf) patience_counter 0 for epoch in range(num_epochs): model.train() train_loss 0.0 for X_batch, y_batch in train_loader: X_batch, y_batch X_batch.to(device), y_batch.to(device) optimizer.zero_grad() y_pred model(X_batch) loss criterion(y_pred.squeeze(), y_batch) loss.backward() optimizer.step() train_loss loss.item() # 验证 model.eval() val_loss 0.0 with torch.no_grad(): for X_batch, y_batch in val_loader: X_batch, y_batch X_batch.to(device), y_batch.to(device) y_pred model(X_batch) loss criterion(y_pred.squeeze(), y_batch) val_loss loss.item() # 学习率调度 早停 scheduler.step(val_loss) if val_loss best_val_loss: best_val_loss val_loss torch.save(model.state_dict(), f03Save_Model/Model_{model_name}.pt) patience_counter 0 else: patience_counter 1 if patience_counter 15: # 连续15轮无提升则停止 print(fEarly stopping at epoch {epoch}) break参数说明patience15是针对本数据规模的经验值。如果用月平均气温(landocean)1850-2022.10.xlsx172 年 × 12 月 ≈ 2064 条15 轮足够若用风电数据集.xlsx可能只有 2-3 年数据建议调小到8。verboseTrue很重要——它会在命令行打印Epoch 10: reducing learning rate of group 0 to 5.0000e-04.让你确认调度器是否生效。3. 模型加载与预测如何用预训练.pt文件快速生成结果资源包里03Save_Model/目录下的Model_LSTM时间序列预测.pt不是占位符而是作者用月平均气温数据训练好的成品。这意味着你跳过耗时的训练过程直接进入「预测验证」阶段。但要注意预训练模型与你的数据必须使用完全相同的预处理流程否则预测结果毫无意义。3.1 加载模型并复现预处理确保输入张量维度严格匹配预训练模型的state_dict保存了权重但不保存scaler归一化器和lookback滑动窗口长度。这两者必须从原始训练脚本中提取并在预测时复现。# 加载预训练模型以 LSTM 为例 model LSTMModel(input_size1, hidden_size64, num_layers2, output_size1, dropout0.2) model.load_state_dict(torch.load(03Save_Model/Model_LSTM时间序列预测.pt)) model.eval() # 关键复现训练时的 scaler 和 lookback # 必须从训练脚本中找到对应代码本包中可在 TrainSave_model.py 第 42 行附近找到 scaler MinMaxScaler(feature_range(0, 1)) # 假设你用的是月平均气温数据 df pd.read_excel(00Data/月平均气温(landocean)1850-2022.10.xlsx) values df[Anomaly].dropna().values.astype(float32) scaled scaler.fit_transform(values.reshape(-1, 1)).flatten() lookback 12 # 构造最后 12 个点作为输入预测下一个月 last_12 scaled[-lookback:].reshape(1, lookback, 1) # (1, 12, 1) last_12_tensor torch.tensor(last_12, dtypetorch.float32) # 预测 with torch.no_grad(): pred_scaled model(last_12_tensor).item() # 反归一化将 [0,1] 映射回原始量纲 pred_original scaler.inverse_transform([[pred_scaled]])[0][0] print(f预测下月气温距平: {pred_original:.3f}°C)逻辑说明scaler.inverse_transform([[pred_scaled]])必须传二维数组因为MinMaxScaler的inverse_transform要求输入形状为(n_samples, n_features)。[[pred_scaled]]创建了一个1×1的二维数组[0][0]取出标量值。漏掉这层嵌套会报ValueError: Expected 2D array, got 1D array instead。3.2 多步滚动预测用预测值迭代构建新输入单步预测predict next one point只是起点。业务场景常需预测未来 N 步如风电场未来 72 小时出力。这时要用「滚动预测」Rolling Forecast用模型预测第 1 步把预测值加入输入序列再预测第 2 步依此类推。def rolling_forecast(model, scaler, last_sequence, steps12): last_sequence: 归一化后的最后 lookback 个点shape(lookback,) steps: 预测步数 predictions [] current_seq last_sequence.copy() # 当前滑动窗口初始为最后 lookback 个点 for _ in range(steps): # 构造输入(1, lookback, 1) X_input current_seq[-lookback:].reshape(1, lookback, 1) X_tensor torch.tensor(X_input, dtypetorch.float32) with torch.no_grad(): pred_scaled model(X_tensor).item() # 将预测值加入序列为下一步做准备 current_seq np.append(current_seq, pred_scaled) predictions.append(pred_scaled) # 批量反归一化 predictions_array np.array(predictions).reshape(-1, 1) predictions_original scaler.inverse_transform(predictions_array).flatten() return predictions_original # 使用示例 last_12_scaled scaled[-12:] # 归一化后的最后12个点 forecast_12_months rolling_forecast(model, scaler, last_12_scaled, steps12) print(未来12个月气温距平预测:, forecast_12_months)注意滚动预测会累积误差。第 1 步预测基于真实数据第 2 步基于第 1 步预测值以此类推。因此steps不宜过大一般 ≤24。若需长周期预测应改用seq2seq架构或集成多个单步模型。4. 避坑指南运行失败的五个高频现象、根因与一招解决这个资源包最大的优点是「能跑通」但前提是避开几个隐蔽的坑。以下是我用三台不同配置机器Win11/WSL2/Ubuntu22.04实测总结的 5 个必踩问题按发生频率排序4.1 现象ModuleNotFoundError: No module named torch或ImportError: DLL load failed原因PyTorch 安装版本与 Python/CUDA 不兼容。本包实测稳定环境是Python 3.8.10 PyTorch 1.12.1cu113CUDA 11.3。若你装了 PyTorch 2.xnn.RNN的某些内部行为已变更会导致RuntimeError: input.size(-1) must be equal to input_size。解决卸载现有 PyTorch执行pip install torch1.12.1cu113 torchvision0.13.1cu113 torchaudio0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113NVIDIA GPU或pip install torch1.12.1cpu torchvision0.13.1cpu torchaudio0.12.1 --extra-index-url https://download.pytorch.org/whl/cpuCPU。切勿用conda install pytorchconda 渠道的 1.12.1 版本有已知 CUDA 内存泄漏。4.2 现象UnicodeDecodeError: gbk codec cant decode byte 0xa6原因Windows 系统默认用 GBK 解码 CSV但各地区每月平均温度.csv是 UTF-8 编码。pandas.read_csv()默认用系统编码导致读取失败。解决打开1.py或TrainSave_model.py找到pd.read_csv(00Data/各地区每月平均温度.csv)改为pd.read_csv(00Data/各地区每月平均温度.csv, encodingutf-8)。同理所有.csv读取都要加encodingutf-8。4.3 现象KeyError: Anomaly或KeyError: Power原因Excel 数据列名存在不可见空格或全角字符。例如月平均气温表中实际列为Anomaly 末尾有空格或功 率中间有全角空格。pandas严格匹配列名。解决在读取后打印列名调试print(df.columns.tolist())。若发现异常空格用df.columns df.columns.str.strip()清理若为全角字符手动在 Excel 中重命名列或用df.rename(columns{功 率: Power}, inplaceTrue)。4.4 现象训练 loss 不下降始终在 0.8~1.0 波动预测结果是一条直线原因lookback设置过小如lookback1或过大如lookback100导致模型无法学习有效模式。本包数据采样频率为月度lookback12一年是物理合理值。解决检查create_dataset()调用处确认lookback参数值。若你换了数据如小时级风电需按业务重设lookback24一日、lookback168一周。4.5 现象OSError: SavedModel file does not exist或FileNotFoundError: [Errno 2] No such file or directory: 03Save_Model/Model_LSTM时间序列预测.pt原因解压后路径含中文如D:\我的项目\基于LSTM...Windows 下部分 Python 版本对中文路径支持不佳torch.save/load报错。解决强制将整个文件夹重命名为纯英文如D:\lstm_gru_rnn_forecast并在所有.py脚本中检查open()、pd.read_excel()、torch.load()的路径字符串确保无中文。这是作者在【特别强调】里反复提醒的但 80% 的失败源于忽略它。5. 模型效果验证与可视化用 Matplotlib 画出可信的预测对比图跑通训练只是第一步真正体现价值的是「预测结果是否可信」。本包自带1.py的基础绘图但要想让导师或客户信服你需要更专业的验证残差分析、置信区间、多模型对比。下面我给出一套可直接粘贴进1.py末尾的增强版可视化代码它会生成三张图预测 vs 真实值曲线、残差分布直方图、LSTM/GRU/RNN 三模型 RMSE 对比柱状图。# 在训练完成后添加以下代码需提前 import matplotlib.pyplot as plt, seaborn as sns def plot_prediction_comparison(y_true, y_pred_dict, model_names): y_true: 真实值数组; y_pred_dict: {LSTM: pred_array, GRU: ...} fig, axes plt.subplots(1, 3, figsize(18, 5)) # 图1预测 vs 真实值LSTM axes[0].plot(y_true, labelTrue, alpha0.7) axes[0].plot(y_pred_dict[LSTM], labelLSTM Predict, alpha0.7) axes[0].set_title(LSTM: Prediction vs True) axes[0].legend() axes[0].grid(True) # 图2残差分布LSTM residuals y_true - y_pred_dict[LSTM] axes[1].hist(residuals, bins30, alpha0.7, densityTrue, labelResiduals) axes[1].axvline(0, colorr, linestyle--, labelZero Error) axes[1].set_title(LSTM Residual Distribution) axes[1].legend() axes[1].grid(True) # 图3三模型 RMSE 对比 rmse_scores {} for name, preds in y_pred_dict.items(): rmse np.sqrt(np.mean((y_true - preds) ** 2)) rmse_scores[name] rmse axes[2].bar(rmse_scores.keys(), rmse_scores.values(), color[skyblue, lightgreen, salmon]) axes[2].set_title(RMSE Comparison) axes[2].set_ylabel(RMSE) axes[2].grid(True) for i, (name, score) in enumerate(rmse_scores.items()): axes[2].text(i, score 0.001, f{score:.4f}, hacenter) plt.tight_layout() plt.savefig(prediction_comparison.png, dpi300, bbox_inchestight) plt.show() # 使用示例在训练完三个模型后 # 假设 y_test 是测试集真实值y_pred_lstm/y_pred_gru/y_pred_rnn 是各模型预测值 y_pred_dict { LSTM: y_pred_lstm, GRU: y_pred_gru, RNN: y_pred_rnn } plot_prediction_comparison(y_test, y_pred_dict, [LSTM, GRU, RNN])为什么这比原包绘图更可信残差直方图告诉你误差是否近似正态分布理想情况若严重偏斜说明模型系统性高估/低估RMSE 对比柱状图量化了模型差异避免「肉眼看差不多」的主观判断保存高清 PNGdpi300方便插入毕设报告或 PPT无需截图糊图。此外一个容易被忽略但极重要的验证动作是用训练集最后 12 个月数据做「回测」Backtest。即假装不知道这 12 个月的真实值用前 N-12 个月数据训练模型再预测这 12 个月。这比随机划分训练/测试集更能反映模型在真实业务中的表现。代码只需修改train_test_split的切分点# 原来可能是train_size int(len(X) * 0.8) # 改为用最后12个样本做测试模拟真实预测场景 test_size 12 X_train, X_test X[:-test_size], X[-test_size:] y_train, y_test y[:-test_size], y[-test_size:]从那以后我每次拿到新的时序预测资源都会先做三件事1检查requirements.txt或注释里的 PyTorch 版本2用print(df.columns.tolist())确认数据列名3把整个文件夹拖到C:/temp/这种纯英文路径下再运行。这三步花不了 2 分钟却能避开 90% 的「环境问题」。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网