简介:这是一份基于Python与PyTorch框架实现LSTM股票价格预测的实战项目源码包,面向计算机相关专业正在准备期末大作业、课程设计的学生,也适合对时间序列预测感兴趣的开发者进行项目练习。项目内容经导师指导并审定,评审得分98分,难度适中,源码均经过本地编译调试确认可正常运行,并配有清晰的目录结构便于定位模块。压缩包共14个文件,以Python脚本为主,辅以模型参数文件、CSV数据、Markdown说明、依赖清单以及可视化图片,覆盖数据解析与预处理、LSTM网络构建、模型训练、评估和预测结果展示等完整流程,能够帮助读者快速掌握用循环神经网络进行金融数据建模的基本思路。目前已有89人学习下载,资源包仅359KB,轻量便捷。下载后可直接获得可运行的LSTM预测代码、对应模型权重、环境依赖说明和项目文档,快速复现股票价格预测实验;同时可以自行调整历史窗口、网络层数或替换数据集,进一步拓展至其他时序预测应用场景。
1. LSTM 股票价格预测:一份跑得通的 PyTorch 源码包
股票价格预测是时间序列方向最经典的练手场景,也是课程设计和期末大作业里出现频率最高的方向之一。这个项目基于 Python 与 PyTorch 框架,用 LSTM 网络对股票价格做回归预测,压缩包里源码、数据、训练脚本、评估脚本齐全,下载后按步骤配置环境就能本地跑通。我拆过不少类似的源码包,很多是代码结构混乱、缺依赖、一跑就报错;这个包值得推荐的地方在于模块划分清楚——parser_my.py 管参数、dataset.py 管数据切分、LSTMModel.py 管网络结构、train.py 与 evaluate.py 分管训练和评估。适合两类人:准备期末大作业的计算机专业学生,需要一份能跑、能改、能讲清楚的基线工程;想快速上手 LSTM 时间序列预测的开发者,需要一份能扩展的最小实现。接下来我把选型逻辑、跑通步骤、核心代码和常见坑逐一拆给你看。
2. 为什么是 LSTM:时间序列预测的选型逻辑与项目解剖
2.1 LSTM 凭什么能“记住”股价走势:三扇门的工作原理
先说选型。股价预测本质是一个时间序列回归问题:用过去一段时间的价格序列,预测未来某个时刻的价格。可选模型很多,但我个人在实践中发现,真正适合拿来快速落地且效果稳定的,还得是 LSTM 和它的一些变体。
先看 ARIMA。作为传统统计模型,ARIMA 对线性平稳序列效果不错,但股价序列是非线性、非平稳的,经常带有突变和长周期成分,ARIMA 在这个场景下基本是玄学调参,残差检验还不一定过。再看普通 RNN。RNN 在序列长度超过十几步时会出现梯度消失——误差信号在反向传播中指数衰减,网络“记不住”太久以前的信息。股价预测的输入窗口普遍设到 30~60 天,普通 RNN 根本扛不住。
LSTM(长短期记忆网络)通过三个门控单元解决了这个记忆问题。遗忘门决定细胞状态里哪些旧信息要丢弃,输入门决定新的候选信息有多少写入,输出门控制当前时刻的输出里包含多少状态信息。再加上一个跨时间步传递的“细胞状态”通道(cell state),LSTM 可以在数十步的时间跨度上保持梯度流通,从而学到长期依赖关系。
在 PyTorch 里实现 LSTM 很直接,核心就一行 nn.LSTM 层,配合一个全连接回归头:
import torch.nn as nn class LSTMModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(LSTMModel, self).__init__() self.lstm = nn.LSTM( input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=True ) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): # x shape: (batch, seq_len, input_size) out, _ = self.lstm(x) # 取最后一个时间步的隐藏状态作为序列表示 out = out[:, -1, :] out = self.fc(out) return out这段代码对应的网络结构很清楚:LSTM 层每步接收一个特征向量,输出整个序列的隐藏状态;预测股价时我们只关心序列末尾的汇总状态,所以取 out[:, -1, :] 代表“看完整个窗口后的记忆”,再经过全连接层映射为预测价格。input_size 是每个时间步的特征维度,比如只拿收盘价一个维度就是 1,如果叠加成交量、开盘价、最高最低价就是 4;hidden_size 控制记忆容量;num_layers 控制网络堆叠的层数。这些参数你会在 parser_my.py 里看到对应的默认配置。
有人会问为什么不用 Transformer 做这个任务。Transformer 在长序列建模上确实强,但它需要大量数据才能训练出稳定效果,并且位置编码对金融时序的周期性特征支持并不直接。课程设计这种数据规模(几百到几千条日线数据)的场景下,LSTM 收敛更快、调参路径更明确,也更容易在答辩时把“门控机制如何解决梯度消失”讲清楚。这个选型实际上是项目实践的稳妥选择。
2.2 逐个文件拆:parser_my.py、dataset.py、evaluate.py 各管什么
解压 Stock_Prediction 文件夹后,第一件事别急着跑,先看 README.md,把文件职责对应上。我按实际调用关系给你梳理一份清单:
| 文件 | 职责 | 输入 | 输出 |
|---|---|---|---|
| parser_my.py | 集中管理超参数 | 命令行或文件中的参数 | 参数对象,供其它模块读取 |
| dataset.py | 数据切分与样本构造 | data 目录下的行情数据 | (X, y) 样本对,可直接喂给 DataLoader |
| LSTMModel.py | 定义网络结构 | 参数对象中的维度配置 | 可训练的 nn.Module 实例 |
| train.py | 训练入口 | 数据集 + 模型 + 超参 | 保存的模型权重、训练日志 |
| evaluate.py | 评估入口 | 测试集 + 训练好的权重 | 误差指标、预测结果与可视化图片 |
| requirements.txt | Python 依赖清单 | - | pip 安装环境 |
这个项目最大的优点是模块解耦。我见过太多课程设计代码把参数、数据、模型、训练全部揉进一个几百行的脚本里,改一个学习率要全局搜索。而这个包的 parser_my.py 把超参数全部集中,训练和评估脚本只从参数对象取值,替换数据集或调整窗口长度时,基本不用担心改一处崩三处。
具体到数据流动:dataset.py 先从 data 目录读取原始行情数据,常见格式是 CSV,每行一条记录,包含日期、开盘价、收盘价、最高价、最低价、成交量等字段。然后按设定的时间步长(seq_len,比如 60)做滑动窗口切分:第 1~60 天的数据作为 X,第 61 天的收盘价作为 y,窗口每次步进一天,生成大量重叠样本。这种做法能最大程度利用有限的历史数据,但也带来一个隐患——相邻样本高度相关,如果切分不当,训练集和测试集会出现数据泄漏,这个坑在第 5 章我会专门展开。
evaluate.py 则负责在测试集上给出量化结论。常见做法是计算 RMSE(均方根误差)和 MAE(平均绝对误差),然后把真实走势与预测曲线画在同一张图里,保存到 img 目录。你答辩时最有力的证据不是“模型看起来能跑”,而是这张图上预测线对真实线的跟随程度。
这里要强调一点:模型权重默认保存到 model 目录,训练脚本、评估脚本、网络定义对权重路径的引用都通过参数对象传递。这意味着你训练完一次后,再跑 evaluate.py 不用重新训练,直接加载最近一次的权重文件即可。如果你改动了网络结构,记得把旧的权重文件清掉或改输出路径,否则版本不匹配会报形状错误。
3. 从零跑通:环境配置到训练评估的完整操作
3.1 环境准备与依赖安装
拿到项目后,我习惯先建一个独立的虚拟环境,避免把系统 Python 环境搞乱。这个项目依赖 PyTorch、NumPy、Matplotlib、pandas 等常用库,requirements.txt 里已经列好了。创建并激活虚拟环境的命令如下:
python -m venv stock_env source stock_env/bin/activate # Windows 下用 stock_env\Scripts\activate pip install -r requirements.txt这里解释一下为什么要用虚拟环境:PyTorch 的版本跟 CUDA 版本强相关,系统环境里可能已经装了一个别的版本的 PyTorch,直接 pip install 可能会把原有依赖覆盖掉,后面你跑其它项目时就会莫名其妙报 import 错误。独立环境里踩坑也方便重来——把整个文件夹删掉重建就行,不用动系统环境。
如果在国内网络环境下安装 PyTorch 比较慢,可以指定国内镜像源。但要注意,PyTorch 官方安装命令里有个坑:CPU 版本和 GPU 版本的 wheel 包名称不一样,如果你没有 NVIDIA 显卡,千万别装带 cu 后缀的版本,否则 import torch 时会报 CUDA 相关的 DLL 加载错误。安装时先用 CPU 版跑通流程,之后有需要再换 GPU 版。
装完依赖后验证一下环境是否正常:
python -c "import torch, numpy, pandas, matplotlib; print(torch.__version__)"这条命令能同时确认 PyTorch、NumPy、pandas、Matplotlib 四个核心库都导入成功。如果报 ModuleNotFoundError,说明对应库没装上,用 pip install 补装即可。项目里的pycache目录说明源码包是经过调试编译过的,你本地首次运行时可能会重新生成这个目录,这属于正常现象,不用管它。
3.2 跑一次训练:命令、参数与日志解读
训练入口是 train.py,不带参数直接运行会使用 parser_my.py 里的默认配置:
python train.py启动后你会看到类似下面的日志输出(具体格式取决于项目实现):
Epoch [10/50], Loss: 0.003842 Epoch [20/50], Loss: 0.002917 Epoch [30/50], Loss: 0.002564 ... Model saved to model/lstm_model.pthLoss 是训练集上的均方误差(MSE),数值越小说明模型对训练数据的拟合越好。如果你发现 Loss 在前几个 epoch 就降到接近 0,要警惕过拟合;反之如果 Loss 不降反升,先检查学习率是否过大,或者数据是否做了归一化。这一点后面避坑章节会详细展开。
训练脚本支持的常用参数调整方式是这样的:
python train.py --epochs 60 --batch_size 64 --lr 0.001 --hidden_size 64--epochs 表示训练轮数,--batch_size 表示每次喂给网络多少个样本,--lr 是学习率,--hidden_size 是 LSTM 隐藏层维度。这些参数名称以 parser_my.py 里 argparse 定义为准,你可以打开文件查看实际支持的参数名。训练结束后权重保存在 model 目录下,evaluate.py 会去读它。
3.3 评估与可视化:模型到底准不准
训练完成之后,用评估脚本对测试集做预测:
python evaluate.pyevaluate.py 会加载 model 目录下保存的权重,对测试集所有样本做前向推理,然后计算误差指标。通常输出格式类似:
Test RMSE: 2.847 Test MAE: 2.136RMSE 的单位和股价一致,比如真实价格是几十元,RMSE 是 2.8,说明平均预测偏差大约在 2.8 元。这个数字本身没有绝对的好与坏,关键是看它相对于价格量级是否可接受——如果一只股票价格在 100 元附近波动,RMSE 3 元左右是可以接受的;如果价格只有 10 元,RMSE 3 元就明显偏大。
评估完成后,img 目录下会生成真实价格与预测价格的对比图。打开这张图,你会看到一个直观的规律:预测曲线往往滞后于真实曲线。这不是代码 bug,而是 LSTM 这类模型在数据泄漏控制不当时的典型表现——模型学到的是“昨天的价格”,而非真正的趋势逻辑。第 5 章我会专门讲这个现象怎么识别、怎么缓解。
4. 核心代码拆解:模型定义、数据切分与训练循环
4.1 LSTMModel.py:网络结构如何搭出来的
打开 LSTMModel.py,核心就是我在 2.1 节展示的那段结构:一个 nn.LSTM 层加一个 nn.Linear 全连接层。但实际项目里通常还会处理一个容易被忽略的问题——多批次训练时 LSTM 隐藏状态的初始化。
import torch import torch.nn as nn class LSTMModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(LSTMModel, self).__init__() self.hidden_size = hidden_size self.num_layers = num_layers self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): # 每个 batch 的初始隐状态和细胞状态都置零 h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) out, _ = self.lstm(x, (h0, c0)) out = self.fc(out[:, -1, :]) return out函数里的 h0 和 c0 是 LSTM 的初始隐藏状态和细胞状态。为什么要在 forward 里手动初始化?因为如果不传,PyTorch 默认全零初始化,这本身没问题;但当你做多步预测时,LSTM 的隐藏状态可以跨时间步传递,如果忘记在新序列开始时重置,上一个序列的信息就会污染当前预测。在 forward 里显式初始化能确保每个 batch 独立预测,行为更可控。
参数方面,hidden_size 是核心自由度,项目默认值通常取 64 或 128。隐藏维度太小会欠拟合,拟合不了序列中的复杂模式;太大则过拟合,在训练集上 Loss 很低,测试集却表现平平。num_layers 默认取 2 层比较常见,超过 3 层在数据规模小的时候收益很小,反而明显增加训练时间。
4.2 train.py:训练循环里那些关键细节
train.py 是训练流程的总控,逻辑上分为四步:加载参数、构造数据集、初始化模型、循环训练。核心训练循环的常见写法如下:
model.train() for epoch in range(args.epochs): total_loss = 0.0 for batch_x, batch_y in train_loader: optimizer.zero_grad() pred = model(batch_x) loss = criterion(pred, batch_y) loss.backward() # 梯度裁剪,防止梯度爆炸 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step() total_loss += loss.item() print(f"Epoch [{epoch+1}/{args.epochs}], Loss: {total_loss/len(train_loader):.6f}")这里有两个容易出问题的操作:一是 optimizer.zero_grad() 必须在每次反向传播前清空梯度,否则梯度会跨 batch 累积;二是梯度裁剪 clip_grad_norm_(max_norm=1.0)。LSTM 即使在门控机制下,也偶尔出现梯度异常大的情况,尤其是训练初期。加上裁剪能防止权重一步更新过大导致 Loss 变成 NaN。如果你训练时发现 Loss 突然变 inf,检查是否少了这行代码。
优化器常用 Adam,学习率默认 0.001。Adam 对学习率不那么敏感,但这个默认值在大多数时间序列回归任务里是安全的。如果 Loss 下降太慢,可以先试 0.005;如果 Loss 震荡剧烈,就降到 0.0005。项目里如果 parser_my.py 没有单独保留学习率衰减策略,你可以在训练循环里模仿下面的方式,每跑一定 epoch 把学习率降一个量级:
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)每次调用 scheduler.step() 后,学习率会在每 20 个 epoch 后乘 0.5。这样训练后期步长变小,有助于在 Loss 曲面底部精细收敛。但要注意:如果用了 scheduler,打印学习率的日志也会变,调试时别只看 Loss,还要确认学习率确实在按预期衰减。
4.3 数据切分与样本构造:dataset.py 的滑动窗口逻辑
dataset.py 负责把原始行情数据切成模型能吃的样本,这块做得好不好,直接决定训练出来的模型是否可信。常见实现是继承 torch.utils.data.Dataset,在getitem里按索引滑动取窗口:
import torch from torch.utils.data import Dataset class StockDataset(Dataset): def __init__(self, data, seq_len=60, feature_cols=None, target_col='close'): self.data = data self.seq_len = seq_len self.feature_cols = feature_cols or [0, 1, 2, 3] # open, high, low, close self.target_col = target_col def __len__(self): # 窗口总数为 总长度 - seq_len return len(self.data) - self.seq_len def __getitem__(self, idx): # 取第 idx 到 idx+seq_len-1 天的特征作为 X x = self.data.iloc[idx:idx + self.seq_len, self.feature_cols].values # 取第 idx+seq_len 天的目标值作为 y y = self.data.iloc[idx + self.seq_len, [self.target_col]].values return torch.tensor(x, dtype=torch.float32), torch.tensor(y, dtype=torch.float32)len里面的规则决定了数据总量:如果原始数据有 1000 天,seq_len=60,则样本数为 940 个。窗口每步进一天,意味着相邻两个样本有 59 天重叠。这个设计的优点是样本量充足,缺点是测试集和训练集如果按顺序切分,测试集的样本可能与训练集样本高度重叠,造成评估指标虚高。
实际项目中常犯的错误之一是:把整份数据先做归一化,再切分训练集和测试集。这样会造成数据泄漏——归一化时已经用了全部数据的均值和方差,等于测试集的信息在训练阶段就“偷看”过了。正确做法是先按时间顺序切分出训练集和测试集,再分别在训练集上拟合 scaler,用训练集的 scaler 去变换测试集。这个细节我在第 5 章会再强调一次,因为它是评估可信度的分水岭。
feature_cols 的选择也值得说两句。如果只拿收盘价一个特征,input_size=1,模型只用价格自身的信息;如果叠加开盘价、最高价、最低价、成交量,input_size=4,模型可以从成交量变化中捕捉一些市场情绪的线索。但特征并不是越多越好,某些特征本身和收盘价高度线性相关,会掩盖 LSTM 对非线性模式的提取能力。项目默认的 input_size 可以从 LSTMModel.py 的初始化参数反推出来。
5. LSTM 股票预测避坑指南:五个常见的翻车现场
5.1 坑一:数据没做归一化,Loss 不降或直接变 NaN
现象:train.py 跑起来后 Loss 一直维持在很大的值,比如几百上千,甚至训练到某个 epoch 变成 nan。或者 Loss 偶尔下降,但很快又弹回去。
原因:股价原始数值通常是几十到几百,远超神经网络激活函数的合理输出范围。LSTM 内部经过 tanh 和 sigmoid 激活,输出被限制在 [-1, 1] 附近。输入不归一化时,梯度计算会出现极端值,权重更新一步就可能把参数推到数值溢出区域,Loss 变成 NaN。
解决:训练前对每一列特征做标准化(StandardScaler:减均值除标准差)或归一化(MinMaxScaler:缩放到 0~1)。用 sklearn 的 StandardScaler 就行,关键是要把 scaler 在训练集上 fit 后用同一组均值方差去变换测试集。同时检查 parser_my.py 里是否有归一化开关,确保训练和评估两条链路共用同一个预处理逻辑。
5.2 坑二:训练集和测试集切分不当,评估指标虚高
现象:测试集 RMSE 非常漂亮,但把预测曲线画出来,发现模型本质上是在“复读”前一天的收盘价,完全没学到趋势。答辩时被问到“你的模型到底学到了什么”就答不上来。
原因:切分数据时没有按时间顺序打乱,或者整个数据集只做了一次随机切分。时间序列数据相邻时间的样本高度相关,随机打散后,测试样本可能来自训练样本的“前后邻居”,模型在训练时已经见过几乎一样的数据。另一种常见错误是先归一化再切分,导致测试集的分布信息泄漏到训练阶段。
解决:严格按时间顺序切分。比如前 80% 的交易日作为训练集,后 20% 作为测试集。只在训练集上 fit 归一化参数,然后把训练集的均值和方差直接应用到测试集上。验证集和测试集也要区分清楚——验证集用来调参,测试集只在最终评估时碰一次,否则你调参调的是测试集,指标同样失真。
5.3 坑三:窗口长度设置不当,模型记忆错位
现象:seq_len 设得过大(比如 120),训练时间明显变长,但测试集效果反而更差;或者 seq_len 设得太小(比如 5),预测曲线严重滞后于真实走势。
原因:窗口长度决定了 LSTM 能“看到”多远的历史。窗口太长,冗余信息增多,模型需要更大容量去筛选,数据量有限时反而过拟合;窗口太短,模型只记住最近几天价格,无法捕捉中期趋势,出现滞后效应。
解决:从数值上做个小实验。把 seq_len 从 30、45、60、90 各跑一遍,比较测试集 RMSE。选指标最优且曲线滞后最小的值。注意每次改窗口长度时,训练数据总量也会变化(总天数减窗口长度),对比要在同一数据规模下才有说服力。项目默认值如果没标注,你可以在 README 里找找有没有提及窗口长度与预测目标天数的对应关系。
5.4 坑四:预测曲线整体向右平移,模型在复读上一天
现象:画出来的预测曲线与真实曲线形状几乎一致,但有明显延迟——预测值大约等于前一天的真实值。这是时间序列预测里最典型的“伪成功”现象,很多人拿到这种结果以为模型很准,其实是数据泄漏或标签构造过于简单。
原因:如果预测目标是 T 日的价格,而输入特征里包含了 T-1 日的收盘价,且序列有较强的自相关性,LSTM 最偷懒的做法就是学成“预测值等于 T-1 日价格”。因为 T-1 日和 T 日的价格差通常很小,MSE 看起来不错,但模型没有任何预测能力,它只是在做平移映射。另一个原因是滑动窗口步长为 1 时,训练集里相邻样本标签几乎相同,模型学到的是复制粘贴。
解决:把预测目标设为 T+N 日而不是 T 日,比如用过去 60 天预测未来第 5 天的收盘价。这样模型必须学会中长期趋势,而不是盯住一天的增量。检查 dataset.py 中标签构造逻辑,确认 y 不是最近一天的真实值。在评估阶段,画出误差随预测天数增加的曲线,看看模型在多远之外开始失去有效性,这比只看一个 RMSE 数字可靠得多。
5.5 坑五:PyTorch 版本或依赖冲突,train.py 一跑就报错
现象:pip install -r requirements.txt 后运行 train.py,报错信息里包含 AttributeError: module 'torch' has no attribute 'xxx' 或者 ImportError: cannot import name 'yyy'。
原因:股票预测项目里如果用了 Transformer 相关接口或较新的 PyTorch API,代码可能是基于某个较新版本写成;而你环境中装的是老版本 PyTorch,对应接口不存在。反过来也可能因为 environment 里 PyTorch 版本过新,某些曾被弃用的接口在新版本中被移除。
解决:看 requirements.txt 里有没有锁版本号;如果没有,新建虚拟环境后安装时指定与项目生成时间相近的稳定版本,比如 PyTorch 1.13 或 2.0 系列。运行一条诊断命令检查核心依赖版本:
python -c "import torch, torchvision; print(torch.__version__, torchvision.__version__)"如果版本不对,用 pip install torch==2.0.1 精确重装。装的时候注意 CPU 和 GPU 版本差异,我前面提过没有独显就别装 cuda 版。这类问题基本都是环境问题,不要在代码里花时间找 bug,先解决依赖版本再跑。
6. 进阶玩法:调参顺序与预测结果验证
模型跑通只是起点,真正能拿高分的是你会不会调、会不会验。我在这类项目上积累了一套自己的操作顺序:先固定数据窗口,再固定网络容量,最后才动学习率。顺序不能反,如果同时改三个参数,出了问题你根本不知道是哪一项引起的。
具体来说,我一般先用默认参数完整跑一遍训练和评估,记下测试集 RMSE 和预测曲线图。然后单独把 seq_len 从 30 换成 45、60、90 各跑一次,对比测试集误差。选定最好的窗口长度后,再试 hidden_size 从 32、64、128 三种不同容量,同样对比测试集 RMSE。最后,如果 Loss 收敛缓慢或震荡,再动学习率,配合 StepLR 做衰减。每轮只改一个变量,记录表格,这样答辩时你能讲清楚每个参数的敏感性,而不是笼统说“我调了调”。
验证模型是否真的有效,我有个习惯:把测试集按时间顺序切成前中后三段,分别计算 RMSE。如果模型只在前段表现好,后段误差明显增大,说明模型在测试集上存在时间衰减,泛化能力不足。这个结果比单一整体 RMSE 更有信息量,因为金融时序往往有风格切换——前半年震荡,后半年单边下跌,测试集如果恰好跨过了这段切换,整体 RMSE 可能掩盖结构性失效。
还有一个技巧值得提:做“滚动预测试点”。先用前 500 天训练,预测第 501~510 天;然后扩展到前 510 天训练,预测 511~520 天。这样每次只用历史真实数据,模拟你站在当时只能看到过去信息的状态。这种验证方式能更真实地反映模型上线后的表现,但注意每次扩展训练窗口后,归一化的 scaler 也要重新 fit,否则新数据的统计特性会和训练时不匹配。
把测试集按时间顺序切段这个习惯,是我在一次课程设计评审里被老师问住之后强制养成的。当时我的模型整体 RMSE 很好看,但老师把测试集后半段单独拉出来跑了一遍,误差翻了一倍。从那以后我每次评估都强制走一遍分段统计加滚动预测,宁可多花半小时,也不在答辩时被一个“那后半段呢”问倒。希望这篇拆解能帮你把这个 LSTM 股票预测项目跑通、跑稳,也避掉那些我踩过的坑。
本文还有配套的精品资源,点击获取