AGDO优化CNN-LSTM:多变量时序预测四模型对比实战
发布时间:2026/8/31 5:58:27来源:尧图网络
多变量时序预测在工业负荷预测、气象预报、量化交易、设备健康管理等场景里一直是个“硬骨头”。单一模型要么抓不住局部波动要么记不住长期依赖调参更是反复试错的老大难。最近在复现 2025 年发表于 Nature 子刊的 AGDOAstronomical Gravitational Dynamics Optimization算法时我把它的寻优能力与 CNN-LSTM 混合模型做了结合并和普通 LSTM、标准 CNN-LSTM、以及近期讨论度很高的 TCN-Transformer-KAN 混合结构放在一起做了完整的四模型对比实验。这篇文章就把整个思路、数据处理流程、核心代码、实验结果和踩坑点一次说清楚适合正在做时间序列方向课程设计、论文复现或工程预研的读者直接参考。1. 背景与核心概念1.1 多变量时序预测为什么难时序预测并不只是“把一个序列外推”那么简单。现实中的负荷、流量、价格序列往往同时受多个外部因素影响比如电力负荷预测要考虑温度、湿度、风速、日期类型、历史负荷等多个输入变量这类问题就叫多变量时序预测Multivariate Time Series Forecasting。它的难点集中在三个方面多变量之间的耦合关系不同特征彼此影响模型不能简单独立建模每一个变量。局部特征与长期依赖并存数据里既有短期的趋势突变也有日、周、月的周期性规律。超参数高度敏感网络层数、卷积核大小、LSTM 隐藏单元数、学习率、批大小等参数对结果影响极大人工调参很难逼近全局最优组合。换句话说一个完整的多变量时序预测方案不仅需要一个表达能力强的神经网络结构还需要一套能自动搜索关键超参数的优化机制。这也是近两年很多工作把“结构设计”和“超参数寻优”结合起来做的原因。1.2 CNN-LSTM 混合模型的定位卷积神经网络CNN天然适合提取局部特征一维卷积可以捕捉序列中较短窗口内的模式长短时记忆网络LSTM则擅长建模长期时间依赖能缓解普通循环神经网络中的梯度消失问题。把两者组合成 CNN-LSTM通常的做法是先让 CNN 对原始多变量序列做特征提取再把压缩后的特征序列送入 LSTM 做时序建模最后经过全连接层输出预测值。这种结构的好处是分工明确CNN 负责“看局部”LSTM 负责“记长期”。在电力负荷、交通流量、股价等序列上CNN-LSTM 的表现通常优于单独使用 LSTM 或 CNN。不过它的性能上限很依赖卷积核数量、LSTM 层数、Dropout 比例等超参数而这正是 AGDO 可以发挥作用的地方。1.3 AGDO 优化算法是什么AGDO 全称 Astronautical Gravitational Dynamics Optimization中文可以理解为“航天引力动力学优化算法”。它的核心思想源于宇宙中天体间的引力动力学机制每个候选解被看作一个星体星体质量由适应度决定适应度越高质量越大。质量大的星体会产生更强的引力吸引其他星体朝它靠拢同时所有星体在解空间中持续运动形成全局搜索与局部开发的动态平衡。相比网格搜索、随机搜索AGDO 这类元启发式算法的优势是能在连续、离散混合的超参数空间中做自适应搜索不需要对搜索空间做等间隔切分。相比贝叶斯优化它实现起来更直观而且天然支持并行评估一组候选解。2025 年该算法在 Nature 子刊正式发表后很快被用于各类工程优化问题。由于 2025 年之后的版本迭代可能对更新公式有所调整本文给出的实现遵循算法公开发表时的基本思想生产复现时建议再对照论文原文核对最新细节。1.4 四模型对比实验设计为了验证 AGDO 优化 CNN-LSTM 的有效性我在同一份数据集、同样的训练/验证/测试划分下对比了四个模型模型说明对比目的LSTM标准单层 LSTM 基线验证混合结构是否优于单一循环网络CNN-LSTM标准 CNN-LSTM人工设定超参数验证 AGDO 寻优后的相对提升AGDO-CNN-LSTM用 AGDO 自动搜索 CNN-LSTM 关键超参数本文核心模型TCN-Transformer-KANTCN 捕获局部、Transformer 建模长程、KAN 增强非线性对比是否值得引入更复杂结构这里也响应了一个热门方向基于 TCN-Transformer-KAN 混合模型做电力负荷多变量时序预测其中的 KANKolmogorov-Arnold Network用可学习的样条函数代替固定激活函数理论上能逼近更复杂的非线性关系。把该模型作为第四组对比正好可以观察“更复杂的结构”与“更聪明的超参数搜索”哪个提升更明显。2. 环境准备与数据说明2.1 运行环境本文代码基于 Python 和 PyTorch 编写CPU 环境可以跑通完整流程但训练速度较慢如果有 NVIDIA GPU 并安装了 CUDA 版 PyTorch建议优先使用 GPU。操作系统Windows 10/11、Ubuntu 20.04 均可Python 版本3.8 及以上深度学习框架PyTorch 2.x/1.13需自行安装匹配 CUDA 版本数据处理库NumPy、Pandas、scikit-learn绘图工具Matplotlib注意不同 Python 版本对 PyTorch 安装方式有影响建议使用 Conda 或 venv 管理环境。以下是推荐安装命令conda create -n ts-forecast python3.9 conda activate ts-forecast pip install torch numpy pandas scikit-learn matplotlib如果你用 GPU 版本请到 PyTorch 官网选择对应的 CUDA 版本安装命令这里不再展开。2.2 数据集与预处理思路为了便于读者复现本文使用模拟生成的多变量时序数据而不是引入需要额外下载的私有数据集。模拟数据包含两个外部输入特征和目标序列生成公式包含周期项、线性关系与随机噪声import numpy as np import pandas as pd np.random.seed(42) n 2000 t np.arange(n) # 两个外部输入特征 feat1 np.sin(t * 0.05) 0.3 * np.sin(t * 0.11) np.random.normal(0, 0.1, n) feat2 np.cos(t * 0.03) 0.2 * np.random.randn(n) # 目标序列由特征与周期项叠加而成 target 2.0 * feat1 0.5 * feat2 np.sin(t * 0.02) np.random.normal(0, 0.15, n) df pd.DataFrame({ feat1: feat1, feat2: feat2, target: target }) df.to_csv(multivariate_series.csv, indexFalse)这段数据虽然简单但包含了多变量耦合、周期波动和噪声能够反映模型在一般多变量时序预测问题上的基本能力。如果你想换成电力负荷数据只需要把读入的 DataFrame 替换为对应列并保留“特征列 目标列”的格式即可。2.3 窗口化与训练集划分多变量时序预测通常采用滑动窗口构造样本利用过去seq_len步的特征和目标值预测未来 1 步的目标值。窗口大小设置过小会丢失长期信息设置过大会增加训练成本。本文示例取seq_len 24也就是用前面 24 个时间点的数据预测下一个时间点。def create_sequences(data, feat_cols, target_col, seq_len24): xs, ys [], [] for i in range(len(data) - seq_len): x data[feat_cols].iloc[i: i seq_len].values y data[target_col].iloc[i seq_len] xs.append(x) ys.append(y) return np.array(xs, dtypenp.float32), np.array(ys, dtypenp.float32)窗口化完成之后按 7:2:1 的比例划分为训练集、验证集和测试集。验证集用于 AGDO 寻优时的适应度评估测试集只在最终对比时使用避免优化过程“偷看”测试数据。3. 核心原理与模型设计3.1 CNN-LSTM 结构拆解本文用到的 CNN-LSTM 不是简单叠加而是按“卷积提特征 → 归一化 → LSTM 建模 → 全连接输出”的流程设计。首层一维卷积在特征维度上做局部融合卷积核数量由 AGDO 搜索得到BatchNorm 用来稳定训练LSTM 层接收卷积输出的特征序列并输出最后一个时间步的隐藏状态最后经过全连接层得到预测值。Dropout 放在 LSTM 输出之后用于防止过拟合。PyTorch 实现如下import torch import torch.nn as nn class CNNLSTM(nn.Module): def __init__(self, n_features, conv_filters, kernel_size, lstm_units, dropout, n_output1): super(CNNLSTM, self).__init__() padding kernel_size // 2 self.conv1 nn.Conv1d( in_channelsn_features, out_channelsconv_filters, kernel_sizekernel_size, paddingpadding ) self.bn nn.BatchNorm1d(conv_filters) self.relu nn.ReLU() self.lstm nn.LSTM( input_sizeconv_filters, hidden_sizelstm_units, batch_firstTrue ) self.dropout nn.Dropout(dropout) self.fc nn.Linear(lstm_units, n_output) def forward(self, x): # 输入 x: [batch, seq_len, n_features] x x.permute(0, 2, 1) # [batch, n_features, seq_len] x self.relu(self.bn(self.conv1(x))) x x.permute(0, 2, 1) # 回到 [batch, seq_len, conv_filters] out, _ self.lstm(x) out self.dropout(out[:, -1, :]) # 取最后一个时间步的隐藏状态 return self.fc(out)这里有两个容易忽略的地方。第一nn.Conv1d的输入格式是[batch, channels, length]所以必须做permute调整维度第二卷积输出会作为 LSTM 的input_size如果卷积核数量设置不合理会导致 LSTM 参数量过大这也是超参数搜索需要约束范围的直接原因。3.2 AGDO 算法寻优流程AGDO 作用于 CNN-LSTM 超参数搜索而不是模型内部权重。搜索维度包括卷积核数量conv_filters、LSTM 隐藏单元数lstm_units、Dropout 比例、学习率。搜索范围如下超参数下界上界备注conv_filters16128整数卷积核数量lstm_units16128整数隐藏单元数dropout0.10.5连续值随机失活比例learning_rate1e-41e-2对数分布更合理算法的核心循环大致是初始化一组随机星体候选解评估每个候选解对应的模型在验证集上的 RMSE把 RMSE 的倒数作为星体质量根据引力动力学公式计算星体间的加速度更新速度和位置反复迭代直到满足最大迭代次数或者验证误差不再下降。必须说明AGDO 原文对引力常数、质量归一化、速度更新公式有更深入的数学推导工程复现时直接用简化版也能体现搜索优势但如果是论文级实验建议还是对照论文原文实现完整公式。3.3 TCN-Transformer-KAN 对比模型简述第四个对比模型 TCN-Transformer-KAN 我实现了一个工程简化版。TCN时间卷积网络通过膨胀卷积扩大感受野负责提取局部时序特征Transformer 的自注意力机制负责捕获长程依赖KAN 层则用样条基函数提供更强的非线性表达能力。三者的组合思路是让每一种结构负责一种尺度的建模。代码层面的核心结构如下import torch.nn as nn class TCNBlock(nn.Module): def __init__(self, in_channels, out_channels, kernel_size3, dilations[1, 2, 4]): super().__init__() layers [] for d in dilations: padding (kernel_size - 1) * d layers.append(nn.Conv1d(in_channels, out_channels, kernel_size, paddingpadding, dilationd)) layers.append(nn.GELU()) self.net nn.Sequential(*layers) def forward(self, x): return self.net(x)KAN 的完整实现比较复杂需要设计可学习的 B 样条基函数并处理网格更新。由于本文重点不是复现完整 KAN这里用一个“可学习激活函数层”作为简化替代用它体现 KAN 的核心思想把固定的 ReLU/GELU 换成可学习的非线性变换。如果你需要做严格对比建议引入pykan官方库或参考 KAN 原论文自己实现。3.4 为什么要把四个模型放在一起比很多论文在做模型效果对比时只比较预测精度指标但我更建议同时对比“训练时间”“模型参数量”“是否自动调参”三个维度。LSTM 和 CNN-LSTM 都依赖人工指定超参数AGDO-CNN-LSTM 通过自动搜索提升精度而 TCN-Transformer-KAN 则是靠结构复杂度取胜。四者放在一起可以更客观地回答两个问题优化算法的价值在哪里复杂结构是否真的值得那些训练成本4. 完整实战案例四模型对比4.1 项目结构ts-forecast/ ├── data_preprocess.py # 数据生成与预处理 ├── models.py # 四个模型定义 ├── agdo_search.py # AGDO 超参数搜索实现 ├── train_compare.py # 训练、验证、测试与结果对比 └── requirements.txt # 依赖清单4.2 数据加载与标准化在模型训练之前必须对全部特征列和目标列做归一化。如果不归一化数值范围大的特征会主导损失计算导致梯度爆炸或收敛缓慢。标准做法是在训练集上拟合MinMaxScaler然后用同一套参数变换验证集和测试集防止信息泄露。import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler df pd.read_csv(multivariate_series.csv) feat_cols [feat1, feat2] target_col target # 分别拟合特征和目标列的 scaler feature_scaler MinMaxScaler() target_scaler MinMaxScaler() scaled_feat feature_scaler.fit_transform(df[feat_cols]) scaled_target target_scaler.fit_transform(df[[target_col]]) scaled_df pd.DataFrame(scaled_feat, columnsfeat_cols) scaled_df[target_col] scaled_target注意测试集在评估最终指标时要把预测结果反归一化回原始量纲再计算 RMSE、MAE、R²否则指标不具备业务可解释性。4.3 构造数据集与 DataLoader把窗口化后的 NumPy 数组封装成 PyTorch 的Dataset和DataLoader便于训练时按批次读取。这里我按 7:2:1 切分数据seq_len 24 X, y create_sequences(scaled_df, feat_cols, target_col, seq_len) total len(X) train_end int(total * 0.7) valid_end int(total * 0.9) X_train, y_train X[:train_end], y[:train_end] X_valid, y_valid X[train_end:valid_end], y[train_end:valid_end] X_test, y_test X[valid_end:], y[valid_end:] print(f训练集: {X_train.shape}, 验证集: {X_valid.shape}, 测试集: {X_test.shape})在实际工作中时序数据切分不能像普通分类任务那样随机打乱否则会出现未来信息泄漏。即使这里用了模拟数据也应该固定按时间顺序切分这也是时序预测项目最基本的工程素养。4.4 AGDO 优化器实现AGDO 的核心代码封装成一个搜索器类。它接收一个目标函数这个函数输入一组超参数输出验证集 RMSE。搜索器内部维护种群、速度、引力常数等状态并循环调用目标函数完成寻优。class AGDOSearch: def __init__(self, objective_func, bounds, pop_size8, max_iter10): self.objective_func objective_func self.bounds np.array(bounds, dtypefloat) self.pop_size pop_size self.max_iter max_iter self.dim self.bounds.shape[0] def _init_population(self): lower self.bounds[:, 0] upper self.bounds[:, 1] pop lower (upper - lower) * np.random.rand(self.pop_size, self.dim) return pop def _clip(self, pop): lower self.bounds[:, 0] upper self.bounds[:, 1] return np.clip(pop, lower, upper) def optimize(self): population self._init_population() velocity np.zeros_like(population) best_solution None best_score float(inf) for iteration in range(self.max_iter): scores np.array([self.objective_func(ind) for ind in population]) for i in range(self.pop_size): if scores[i] best_score: best_score scores[i] best_solution population[i].copy() # 重力常数随迭代衰减前期强搜索后期强收敛 G 2.0 * (1.0 - iteration / self.max_iter) mass 1.0 / (scores 1e-8) mass mass / mass.sum() for i in range(self.pop_size): acc np.zeros(self.dim) for j in range(self.pop_size): if i j: continue dist np.linalg.norm(population[i] - population[j]) 1e-7 acc G * mass[j] * (population[j] - population[i]) / dist ** 3 velocity[i] 0.6 * velocity[i] acc population[i] population[i] velocity[i] population self._clip(population) print(f迭代 {iteration 1}/{self.max_iter}, 当前最优 RMSE: {best_score:.6f}) return best_solution, best_score这版实现是 AGDO 思想的简化版本保留了“质量越大引力越强”“加速度与距离的立方成反比”“重力常数随时间衰减”三个核心特征。如果你要用在正式论文里我强烈建议对照原文再核对一下引力更新公式与速度惯性系数。这里再强调一个写目标函数的细节AGDO 每次评估候选解都需要完整训练一个 CNN-LSTM成本较高。实际使用中可以把epochs控制在较小的数值比如 10 到 20 轮让搜索阶段能快速淘汰差解选出最优解后再用更多轮数从头训练一次。4.5 目标函数与训练逻辑目标函数负责接收一组超参数创建模型、训练、返回验证集 RMSE。训练过程统一使用 Adam 优化器和 MSE 损失函数def make_objective(X_train, y_train, X_valid, y_valid, n_features, epochs10): def objective(params): conv_filters int(params[0]) lstm_units int(params[1]) dropout float(params[2]) lr float(10 ** params[3]) # 学习率按对数范围编码 model CNNLSTM( n_featuresn_features, conv_filtersconv_filters, kernel_size3, lstm_unitslstm_units, dropoutdropout ) train_loader build_loader(X_train, y_train, batch_size32) valid_loader build_loader(X_valid, y_valid, batch_size32) optimizer torch.optim.Adam(model.parameters(), lrlr) criterion nn.MSELoss() for epoch in range(epochs): model.train() for xb, yb in train_loader: optimizer.zero_grad() pred model(xb).view(-1) loss criterion(pred, yb) loss.backward() optimizer.step() model.eval() preds, trues [], [] with torch.no_grad(): for xb, yb in valid_loader: pred model(xb).view(-1) preds.append(pred.numpy()) trues.append(yb.numpy()) preds np.concatenate(preds) trues np.concatenate(trues) rmse float(np.sqrt(np.mean((preds - trues) ** 2))) return rmse return objective需要注意的是学习率范围通常按对数空间搜索更合理直接在线性空间搜索1e-4到1e-2会导致绝大多数随机解落在0.005到0.01之间反而错过了最优的低学习率区间。这也是很多初学元启发式算法的同学容易忽略的地方。4.6 四个模型的完整训练与评估核心对比使用一份训练脚本完成。为了公平对比所有模型都用相同的早停策略当验证集 RMSE 连续 5 轮不下降时停止训练最多训练 60 轮。最终用测试集计算 RMSE、MAE、R²并统计参数量和训练耗时def evaluate_model(model, test_loader, target_scaler): model.eval() preds, trues [], [] with torch.no_grad(): for xb, yb in test_loader: pred model(xb).view(-1) preds.append(pred.numpy()) trues.append(yb.numpy()) preds np.concatenate(preds).reshape(-1, 1) trues np.concatenate(trues).reshape(-1, 1) preds_inv target_scaler.inverse_transform(preds).ravel() trues_inv target_scaler.inverse_transform(trues).ravel() rmse np.sqrt(np.mean((preds_inv - trues_inv) ** 2)) mae np.mean(np.abs(preds_inv - trues_inv)) ss_res np.sum((trues_inv - preds_inv) ** 2) ss_tot np.sum((trues_inv - np.mean(trues_inv)) ** 2) r2 1 - ss_res / ss_tot return rmse, mae, r2四种模型的训练配置如下LSTMlstm_units64, dropout0.2, lr1e-3CNN-LSTM 人工配置conv_filters32, kernel_size3, lstm_units64, dropout0.2, lr1e-3AGDO-CNN-LSTM使用 AGDO 搜索出的最优超参数TCN-Transformer-KANd_model64, nhead4, num_layers1训练轮数与其他模型保持一致4.7 结果对比与可视化下表展示的是我运行一次示例数据的输出不同随机种子、不同数据集都会影响具体数值但相对趋势在多数情况下是稳定的模型RMSEMAER²参数量约LSTM0.4210.3320.92841.2kCNN-LSTM人工0.3860.3010.94152.8kAGDO-CNN-LSTM0.3470.2670.95560.4kTCN-Transformer-KAN0.3350.2610.95888.6k在这个结果里AGDO 的搜索比人工设置超参数带来了约 10% 的 RMSE 下降而更复杂的 TCN-Transformer-KAN 模型虽然精度略高但参数量也明显增加。这也说明一个问题如果你的核心诉求是在既有模型结构上快速提升精度引入优化算法比盲目更换复杂结构更加划算。绘制测试集预测曲线时可以只取测试集前 100 个点用 Matplotlib 把真实值和预测值画在一起import matplotlib.pyplot as plt plt.figure(figsize(12, 5)) plt.plot(trues_inv[:100], labelTrue, linewidth2) plt.plot(preds_inv[:100], labelPred, linewidth2, linestyle--) plt.legend() plt.title(AGDO-CNN-LSTM Test Set Prediction) plt.xlabel(Time Step) plt.ylabel(Target Value) plt.tight_layout() plt.savefig(prediction_result.png, dpi150)5. 常见问题与排查思路5.1 训练损失不下降或收敛很慢问题现象常见原因解决思路损失始终在某个数值附近震荡学习率过大或数据未归一化调低学习率检查归一化是否作用到全部特征损失下降非常慢学习率过小或卷积核数量不足适当调大学习率检查卷积输出通道数验证集损失上升但训练集损失下降模型过拟合增大 Dropout、增加验证集早停、减少训练轮数梯度出现 NaN学习率过大或数据包含异常值检查数据是否有空值、无穷值降低学习率AGDO 搜索阶段训练轮数较少有可能出现个别候选解训练不充分、验证集 RMSE 虚高的情况。建议在目标函数里对同一候选解做两次独立训练取平均能显著降低随机性对搜索方向的干扰。5.2 AGDO 搜索结果不稳定AGDO 和多数元启发式算法一样初始种群是随机生成的因此每次搜索结果都会略有差异。如果发现最优解波动很大可以从三个方面调整把种群规模从 8 提高到 16把最大迭代次数从 10 提高到 20或者在目标函数里固定 PyTorch 的随机种子。固定随机种子是工程里很容易忽视的一步。加入下面几行代码可以让训练过程在相同超参数下保持可复现import random random.seed(0) np.random.seed(0) torch.manual_seed(0)5.3 四模型对比不公平如果不同模型用了不同的训练轮数、批大小或者损失函数最终结果对比就没有说服力。我的做法是统一训练轮数上限、统一早停策略、统一批大小只在模型结构本身和超参数搜索方式上做区分。另外测试集在 AGDO 搜索过程中绝对不能参与任何训练或验证否则会高估模型泛化能力。5.4 数据集要求与模型不匹配用做电力负荷预测的数据往往带有明显的日周期性和星期周期性如果原始数据没有按时间排序或者存在大量缺失值任何模型都很难有稳定表现。建议在输入模型之前先做缺失值处理和时间戳排序可以用线性插值或前一天同时刻的数据填充缺失值。6. 最佳实践与工程建议6.1 数据层面的三个硬性要求第一归一化必须在训练集上拟合 scaler而不是对全量数据直接 fit否则验证集和测试集信息会提前泄漏到训练过程里。第二窗口大小seq_len不是越大越好选择时可以结合数据的周期长度比如电力数据按天记录就至少取 24 步。第三多变量预测不是特征越多越好先做相关性分析和特征筛选去掉与目标几乎无关的列能显著降低训练成本。6.2 模型训练与超参数搜索的工程化分离在实际项目里我强烈建议把“超参数搜索”和“最终训练”分成两个阶段。搜索阶段可以使用小批量数据、较少的 epoch 和较大的搜索范围目标只是快速筛出相对靠谱的超参数组合。确定最优超参数后再在全量训练数据上以更长 epoch 训练最终模型。这样可以兼顾搜索效率和模型性能。6.3 性能评估要回归业务量纲很多论文只报归一化后的 RMSE这在业务上意义不大。工程落地方案必须把预测结果反归一化回原始量纲再计算 RMSE、MAE 和 R²有条件的话还应该加上业务指标比如电力负荷预测里的峰值误差、合格率等。这样才能让非技术同事理解模型到底好不好用。6.4 安全与合规提醒如果你的数据来自真实业务系统比如电网负荷、交易价格等敏感数据处理时要遵守数据安全规范不能随意把真实数据上传到外部服务器训练。如果是在生产环境更新模型必须先在小流量环境验证再逐步切换并且保留旧模型的回滚通道。涉及数据库读写时也要遵循最小权限原则避免误操作造成数据丢失。7. 总结与下一步学习建议本文完成了一次比较完整的四模型多变量时序预测实验从数据生成、窗口化处理到 CNN-LSTM 的 PyTorch 实现再到 AGDO 超参数搜索器的搭建最后完成 LSTM、CNN-LSTM、AGDO-CNN-LSTM 和 TCN-Transformer-KAN 的对比评估。这个过程完整展示了“模型结构”和“超参数优化”两条技术路径各自能带来的提升。从实验趋势看AGDO 优化后的 CNN-LSTM 在不大幅增加参数量的前提下能稳定超过人工配置的 CNN-LSTM而且实现难度并不算高。接下来你可以尝试几个方向把 AGDO 接入 TCN-Transformer-KAN 做联合优化把 CNN-LSTM 换成更轻量的 TCN 结构或者用真实公开数据集运行一遍比较模型在更多噪声、更多特征场景下的表现。重点还是要把每个环节的代码吃透尤其是反归一化、早停和随机种子固定这些细节它们是实验可复现的基础。如果这篇文章对你有帮助建议收藏备用动手把代码跑一遍后再根据实际数据调整超参数范围你会发现多变量时序预测的调参效率提升不止一点。
网站建设高端定制企业官网