RNN、LSTM、GRU小白入门:Windows一键运行时间序列预测
- RNN、LSTM、GRU小白入门:Windows一键运行时间序列预测
- 一、原始仓库讲了什么?
- 二、时间序列预测到底在做什么?
- 三、普通RNN是什么?
- 四、LSTM为什么增加三个门?
- 五、GRU与LSTM有什么区别?
- 六、为什么本文不用股票数据作为默认示例?
- 七、代码包如何防止乱码?
- 八、第一次运行
- 九、一键比较RNN、LSTM和GRU
- 十、核心模型代码
- 十一、为什么不能随机划分时间序列?
- 十二、早停和梯度裁剪有什么用?
- 十三、怎样使用自己的CSV?
- 十四、单步预测与多步预测有什么区别?
- 十五、怎样用于遥感和水文时间序列?
- 十六、常见错误
-
- [1. 找不到Python](#1. 找不到Python)
- [2. CUDA available为False](#2. CUDA available为False)
- [3. CSV找不到目标列](#3. CSV找不到目标列)
- [4. 数据行数太少](#4. 数据行数太少)
- [5. 预测变成一条平滑直线](#5. 预测变成一条平滑直线)
- 十七、RNN、LSTM和GRU谁最好?
- 十八、总结
RNN、LSTM、GRU小白入门:Windows一键运行时间序列预测
一句话读懂:
给模型过去36个时刻的数据,让它预测下一个时刻;分别使用RNN、LSTM和GRU训练,再用同一测试集比较预测曲线、RMSE、MAE和R²。本文不下载股票数据,不配置旧版TensorFlow,解压后双击脚本即可运行。
一、原始仓库讲了什么?
原始仓库围绕循环神经网络提供五类内容:
text
Basic RNN
Basic LSTM
股票/比特币价格预测
情感分析
音乐生成
其中股票示例使用Keras-TensorFlow,情感分析需要外部GloVe词向量,音乐生成需要music21和音乐数据。
需要注意:该仓库已于2025年6月3日归档,当前为只读状态。因此,本文保留其"从RNN到LSTM再到应用"的教学思路,但使用PyTorch重写最小可运行版本。
二、时间序列预测到底在做什么?
假设有一列连续观测:
text
10.2, 10.8, 11.1, 10.9, 11.5, ...
设置窗口长度为4后,训练样本可以整理为:
| 输入 | 目标 |
|---|---|
| 10.2, 10.8, 11.1, 10.9 | 11.5 |
| 10.8, 11.1, 10.9, 11.5 | 下一个值 |
本文默认使用过去36步预测下一步。
输入张量形状为:
text
[批次大小, 序列长度, 特征数量]
例如:
text
[64, 36, 1]
表示一次输入64个样本,每个样本包含36个时刻,每个时刻只有1个变量。
三、普通RNN是什么?
普通RNN会把当前输入和上一时刻隐藏状态组合起来:
text
当前输入 + 过去记忆 → 当前隐藏状态
它适合处理有顺序的数据,例如:
text
气温变化
降水序列
遥感指数时间序列
传感器读数
文本和语音
普通RNN结构简单,但序列很长时,早期信息可能难以保留,训练中还可能出现梯度消失或梯度爆炸。
四、LSTM为什么增加三个门?
LSTM全称:
text
Long Short-Term Memory
中文称为长短期记忆网络。
它在普通隐藏状态之外增加了细胞状态,并使用三个门控制信息:
| 门 | 小白理解 |
|---|---|
| 遗忘门 | 过去哪些信息可以删除 |
| 输入门 | 当前哪些信息需要写入 |
| 输出门 | 哪些记忆用于当前输出 |
可以把LSTM理解为一个带有"删除、写入、读取"开关的记忆本。
这不意味着LSTM一定比RNN准确。它只是为长期依赖提供了更合适的结构,最终效果仍取决于数据、窗口、参数和验证方式。
五、GRU与LSTM有什么区别?
GRU全称:
text
Gated Recurrent Unit
GRU通常使用更新门和重置门,没有单独的细胞状态,参数往往比同规模LSTM少。
简单比较:
| 模型 | 结构 | 常见特点 |
|---|---|---|
| RNN | 最简单 | 速度快,但长期记忆较弱 |
| LSTM | 三个门和细胞状态 | 长期依赖表达更完整 |
| GRU | 两个门 | 结构比LSTM简洁 |
不能只看模型名称判断谁最好,应该在同一数据划分上实测。
六、为什么本文不用股票数据作为默认示例?
股票示例看起来直观,但不适合当作第一个运行案例:
- 数据源可能改变接口或限制访问;
- 日期、缺失值和复权方式容易出错;
- 随机切分可能产生未来信息泄漏;
- 价格走势受新闻和制度变化影响;
- 一条漂亮预测曲线不代表具有交易价值。
因此,本文默认生成一条包含趋势、周期和噪声的时间序列。它不需要联网,而且每次都可复现。
七、代码包如何防止乱码?
压缩包内:
text
所有文件名使用英文
所有文件夹名使用英文
中文Markdown和TXT使用UTF-8 with BOM
可以直接使用Windows资源管理器、WinRAR或7-Zip解压。
八、第一次运行
安装Python 3.11或3.12,安装时勾选:
text
Add Python to PATH
有NVIDIA显卡,双击:
text
Install_NVIDIA_GPU.bat
没有NVIDIA显卡,双击:
text
Install_CPU.bat
脚本会自动:
text
创建.venv虚拟环境
安装PyTorch
安装NumPy、Pandas和Matplotlib
检查CPU或CUDA环境
训练最小LSTM
生成预测图
成功结果:
text
outputs/lstm_minimal/lstm_prediction.png
九、一键比较RNN、LSTM和GRU
双击:
text
Run_Compare_Models.bat
三个模型使用相同的:
text
训练数据
验证数据
测试数据
窗口长度
隐藏层大小
优化器
训练轮数上限
输出:
text
outputs/comparison/model_comparison.png
outputs/comparison/validation_loss.png
outputs/comparison/metrics.csv
outputs/comparison/test_predictions.csv
model_comparison.png显示真实值和三个模型的测试预测曲线。
metrics.csv包含:
| 指标 | 含义 |
|---|---|
| MAE | 平均绝对误差,越小越好 |
| RMSE | 对较大误差更敏感,越小越好 |
| R² | 越接近1通常越好 |
十、核心模型代码
python
class SequenceRegressor(nn.Module):
def __init__(self, cell_type="LSTM"):
super().__init__()
cells = {"RNN": nn.RNN, "LSTM": nn.LSTM, "GRU": nn.GRU}
self.recurrent = cells[cell_type](
input_size=1,
hidden_size=32,
batch_first=True,
)
self.head = nn.Linear(32, 1)
def forward(self, x):
sequence_output, _ = self.recurrent(x)
last_step = sequence_output[:, -1, :]
return self.head(last_step)
关键设置:
python
batch_first=True
因此输入顺序为:
text
[batch, sequence, feature]
sequence_output[:, -1, :]表示取每个样本最后一个时刻的隐藏特征,再通过全连接层输出下一个数值。
十一、为什么不能随机划分时间序列?
普通机器学习常使用随机训练测试划分,但时间序列具有先后顺序。
错误做法:
text
2025年数据进入训练集
2023年数据进入测试集
这等于让模型学习未来后再预测过去。
本文采用:
text
前70%:训练集
中间15%:验证集
最后15%:测试集
而且标准化的均值和标准差只使用训练集计算,验证集和测试集不会参与拟合。
十二、早停和梯度裁剪有什么用?
早停
训练损失继续下降,不代表未知数据效果继续提高。
代码监控验证损失;连续多轮没有改善时停止,并恢复验证集表现最好的模型。
梯度裁剪
循环网络处理长序列时可能出现梯度爆炸。
python
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
它会限制梯度总体大小,降低训练突然失控的概率。
十三、怎样使用自己的CSV?
CSV示例:
csv
date,value
2025-01-01,12.5
2025-01-02,13.1
2025-01-03,12.9
运行:
bat
.venv\Scripts\activate
python 03_Forecast_Your_CSV.py --csv your_data.csv --target value --time date
修改参数:
bat
python 03_Forecast_Your_CSV.py --csv your_data.csv --target value --time date --window 30 --epochs 100 --future 20
参数含义:
| 参数 | 含义 |
|---|---|
--csv |
CSV文件位置 |
--target |
需要预测的数值列 |
--time |
日期或时间列 |
--window |
使用过去多少步 |
--epochs |
最大训练轮数 |
--future |
向未来递归预测多少步 |
十四、单步预测与多步预测有什么区别?
测试集上的单步预测使用真实的过去观测:
text
真实过去36步 → 预测第37步
未来递归预测没有新的真实观测:
text
预测第1步 → 放回输入 → 预测第2步 → 继续
因此,多步递归预测的误差会累积。未来预测越长,通常越不稳定。
十五、怎样用于遥感和水文时间序列?
可以把单变量value替换为:
text
NDVI
土壤湿度
地表温度
逐日降水
河流水位
流量
洪水面积
土壤电导率
作物长势指数
但实际科研应用还要处理:
- 云和无效像元;
- 不规则观测时间;
- 多源传感器尺度差异;
- 季节性和长期趋势;
- 空间自相关;
- 外生变量;
- 极端事件样本不平衡;
- 跨区域泛化与独立事件验证。
单变量LSTM只利用目标自身历史,不能自动理解降水、地形、灌溉和水库调度等外部驱动。
十六、常见错误
1. 找不到Python
重新安装Python并勾选:
text
Add Python to PATH
2. CUDA available为False
可能安装了CPU版PyTorch,或者NVIDIA驱动过旧。
删除.venv文件夹,更新驱动后重新运行:
text
Install_NVIDIA_GPU.bat
3. CSV找不到目标列
查看CSV第一行,确保参数与列名完全一致,包括大小写。
4. 数据行数太少
窗口为36时,至少需要明显多于36行。数据过少时,训练、验证和测试都不可靠。
5. 预测变成一条平滑直线
常见原因:
- 模型欠拟合;
- 输入窗口不合适;
- 数据噪声太大;
- 特征不足;
- 多步递归误差累积;
- 训练和测试分布发生变化。
不要只通过增加训练轮数解决所有问题。
十七、RNN、LSTM和GRU谁最好?
没有固定答案。
- 短序列、规律简单时,RNN可能已经够用;
- 长期依赖明显时,LSTM可能更稳;
- 数据量有限或希望模型更轻时,GRU值得尝试;
- 数据存在强外部驱动时,三者都可能不够。
正确做法是固定数据划分和评价指标进行比较,而不是只展示训练集拟合图。
十八、总结
小白只需要:
text
第一步:安装Python
第二步:解压代码包
第三步:双击CPU或GPU安装脚本
第四步:双击Run_Compare_Models.bat
第五步:在outputs中查看曲线和指标
这套代码重点不是证明LSTM一定最好,而是让你真正理解:
text
时间序列怎样变成监督学习样本
RNN、LSTM、GRU怎样接收三维输入
怎样正确划分训练、验证和测试集
怎样评价预测结果
怎样换成自己的CSV