ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GWO-Transformer-BiLSTM混合模型的时间序列预测与Matlab实现

GWO-Transformer-BiLSTM混合模型的时间序列预测与Matlab实现 时间序列预测这两年特别有意思传统统计模型还没吃透LSTM刚成为标配Transformer已经杀进来了。但真用久了你会发现单拿Transformer做时间序列并不稳数据量不够时容易乱拟单拿LSTM学长期依赖又吃力更别说整个网络的超参数——学习率、隐藏神经元数、注意力头数每个都可能让最终结果差出一大截。所以这几年很多人开始往混合模型方向走GWO灰狼优化算法负责自动寻参、BiLSTM负责提取局部时序特征、Transformer负责抓全局依赖最后在Matlab环境里做一套完整的性能仿真验证。这条技术路线在电力负荷预测、风速预测、交通流量预测这些场景里都有不错的落地效果。这篇内容我会先把模型组合的设计思路讲透再把GWO、Transformer、BiLSTM三个模块的原理拆开揉碎接着给出完整可行的Matlab仿真流程和网络结构设计方案最后把我实际调试过程中踩过的坑、排查思路一并整理出来。无论你是做毕业设计、发小论文还是刚把方向转到深度学习时间序列预测的工程师照着这套思路走都能省不少时间。1. 模型组合的设计思路为什么是“GWO Transformer BiLSTM”1.1 单一模型在时间序列预测中的短板先聊一个很多人刚接触这个方向时都会问的问题LSTM都出来这么多年了直接堆LSTM不就行了为什么还要把Transformer和GWO扯进来我自己的体会是时间序列数据里同时存在两种依赖关系——短期的局部依赖和长期的全局依赖。LSTM和BiLSTM这类循环结构擅长捕捉短期的时序变化比如前几个时刻的数值对当前时刻有明显影响但对那种跨越大半个序列周期的长程依赖循环结构存在信息遗忘问题尤其序列长度超过几百步时即使加attention也很难彻底解决。Transformer的出现正好补齐了这个缺口它通过自注意力机制让每个位置直接和序列中所有其他位置建立关联全局依赖的建模能力比循环结构强得多。但Transformer也不是没有代价。它对数据量要求高时间序列数据普遍规模不大纯Transformer很容易过拟合、训练不稳。另外如果输入序列本身包含明显的趋势项和局部波动Transformer对这类低频变化和高频细节的混合信号处理起来不如循环结构细腻。1.2 三个模块怎么分工协作这套模型的设计理念是“各管一段协同工作”。BiLSTM作为底层特征提取器从原始输入序列里提取每个时间步附近的双向上下文特征Transformer接在BiLSTM后面对这些特征序列再做全局建模捕捉跨时间步的长程依赖关系而GWO灰狼优化算法承担的是“调参员”角色负责寻找Transformer和BiLSTM的最优超参数组合——包括学习率、隐藏层神经元数、注意力头数、Dropout系数、正则化强度等。我见过不少人把GWO简单理解为“参数搜索工具”这个定位没错但有点低估它的价值。深度网络对超参数非常敏感同一个网络结构学习率设成0.01和0.001结果可能一个发散一个收敛缓慢但效果不错。人工调参效率太低而且多维超参数之间往往存在耦合关系——比如学习率调大时可能需要同步增加Dropout来防过拟合贝叶斯优化虽然也能用但在混合离散和连续超参数的处理上不如元启发式算法灵活。1.3 这种组合的适用场景与边界这套结构主要面向中等长度、有周期性或趋势性、信噪比不太低的时间序列。比如以15分钟为采样间隔的电力负荷数据、逐小时的风速数据、日频的股票行情序列效果都还不错。但如果你做的是超高维的金融毫秒级高频数据或者数据量还不到几千条那这套模型就要谨慎使用容易出现过拟合和训练时间过长的问题。在Matlab里做这套仿真最大的优势是调试直观、工具箱完善不需要像Python那样单独管理一堆依赖环境。我自己习惯把数据预处理、GWO优化、网络训练和结果可视化全部放在一套流程里跑Matlab的脚本化特点确实省了不少事。2. 三个核心算法的原理拆解2.1 GWO灰狼优化参数少、收敛快的群体智能算法GWO是Mirjalili等人在2014年提出的元启发式优化算法核心思想是模拟灰狼种群的社会等级和狩猎行为。整个狼群分成四个层级alpha狼最优解、beta狼次优解、delta狼第三优解和omega狼其余候选解。狩猎行为包括三个步骤包围猎物、追捕猎物、攻击猎物。灰狼包围猎物的数学表达是D |C * X_p(t) - X(t)| X(t1) X_p(t) - A * D这里的X_p是猎物位置当前最优解X是灰狼位置A和C是系数向量。关键就在系数A的设计上——A 2a * r1 - a其中a在迭代过程中从2线性递减到0r1是[0,1]区间随机数。当|A|1时狼群扩大搜索范围做全局探索当|A|1时狼群收缩包围圈向猎物靠近做局部开发。这个机制相当于自动完成了“先粗搜、后精搜”的平衡所以GWO的收敛速度在元启发式算法里是出了名的快。灰狼的位置更新由alpha、beta、delta三只头狼共同引导D_alpha |C1 * X_alpha - X| D_beta |C2 * X_beta - X| D_delta |C3 * X_delta - X|分别计算出三只头狼对当前灰狼的“拉动”方向加权平均后得到新的位置。这个设计保证了种群不会只盯着当前最优解还能兼顾次优区域的搜索有效降低了陷入局部最优的风险。GWO最吸引人的地方在于需要调整的参数只有两个种群规模和最大迭代次数。不像PSO需要调惯性权重、学习因子也不像遗传算法需要处理交叉率和变异率。在Matlab里实现GWO全程不需要额外工具箱手写一个脚本就够用这也是它适合作为超参数优化器的原因之一。2.2 Transformer的自注意力机制从序列中捕捉全局依赖Transformer是2017年Google团队在《Attention Is All You Need》中提出的架构核心是自注意力Self-Attention机制。自注意力的输入是一个序列的向量表示通过三个可学习权重矩阵W_Q、W_K、W_V分别生成Query、Key、Value三个向量。对于序列中每个位置i它的Query会和所有位置的Key做点积再除以根号下维度d_k做缩放经过softmax得到注意力权重最后对Value加权求和Attention(Q, K, V) softmax(Q * K^T / sqrt(d_k)) * V缩放这一步很多人容易忽略。如果Q和K的维度很大点积结果会变得非常大导致softmax函数进入饱和区梯度几乎为0训练没法进行。除以sqrt(d_k)后点积结果保持在合理量级梯度能正常回传。多头注意力就是在Self-Attention的基础上把Q、K、V投影到H组不同的子空间里分别计算注意力后再拼接、线性变换。每个头可以从不同角度学习序列中不同位置的依赖关系比如一个头关注短期局部模式另一个头关注周期性长程依赖优势就是信息视角更丰富。Transformer还有一个容易被忽略的部分是位置编码。因为Self-Attention本身不带任何顺序信息——序列打乱后计算结果完全一样——所以必须用位置编码把每个时间步的位置信息注入到输入中。原始论文用的是两种频率的三角函数位置编码现在的实现里也常用可学习位置编码。这两种方式在时间序列预测场景下都有应用我自己更倾向使用可学习位置编码数据量不大时可学习位置编码更容易配合整体网络训练到位。2.3 BiLSTM的双向结构兼顾前后文的时间特征LSTM通过在隐状态中引入门控机制来解决RNN的梯度消失和长期记忆问题三个门——遗忘门、输入门、输出门——分别控制历史信息丢弃、新信息写入和当前状态输出。BiLSTM在LSTM的基础上做了一次“反转”一条LSTM按时间正序读取序列另一条按时间反序读取序列最后把两个方向的隐状态拼接起来作为该时间步的输出。为什么要双向很多时间序列预测任务里当前时刻的状态不仅和过去有关也和未来一段时间的趋势有关。比如电力负荷预测中某天上午10点的负荷不仅受过去几小时负荷变化趋势影响也和“即将到来的午间负荷上升”这一未来趋势相关联。当然这在实际预测中看似有点“作弊”但在序列到序列的训练模式中BiLSTM拿到的是整个输入窗口内的双向上下文信息对窗口内部的特征提取非常有效。把BiLSTM接在Transformer前面等于是让网络先做一层“近邻特征提炼”再来做全局依赖建模。这样处理之后Transformer看到的输入特征不再是原始序列而是已经带有双向上下文信息的中间表示注意力计算的效果往往比直接吃原始序列更好。3. 模型架构与整体流程设计3.1 数据输入与预处理要点在搭建模型之前数据预处理必须先做好。时间序列预测常用的数据转换方式是“滑动窗口法”设定一个回看窗口长度lookback用前L个时刻的观测值预测后面第L1到LH个时刻的值单步预测时H1。数据归一化上我强烈建议使用z-score标准化而不是简单的Min-Max归一化。一方面z-score对离群值的鲁棒性更好另一方面Transformer训练中对输入的绝对尺度不敏感但对方差敏感z-score处理后的数据更容易让训练稳定下来。具体做法是mu mean(trainData, omitnan); sigma std(trainData, omitnan); trainNorm (trainData - mu) ./ sigma; valNorm (valData - mu) ./ sigma; testNorm (testData - mu) ./ sigma;注意这里有一个非常关键的细节归一化参数只能从训练集上计算再应用到验证集和测试集上。如果直接用全量数据的均值方差做归一化会泄露测试集的信息导致验证结果虚高。这个问题我在后面常见问题部分会再展开。数据集划分上常用比例是训练集70%、验证集15%、测试集15%。如果数据本身存在明显的周期性划分时要尽量避免训练集和测试集来自不同周期分布比如只取夏季数据训练却拿冬季数据测试这样模型性能会被严重低估。比较稳妥的做法是先按时间顺序划分再检查各集合的均值和标准差是否在可接受范围内。3.2 Transformer-BiLSTM网络结构设计网络结构采用“输入层 → BiLSTM层 → Transformer编码器层 → 全连接输出层”的串联结构。BiLSTM层负责局部特征提取Transformer编码器层负责全局依赖建模全连接层映射到预测值。具体到每一层的参数我的建议是输入维度由lookback窗口长度和数据特征维度决定比如输入12个时间步、每个时间步有1个特征则输入维度是12x1。BiLSTM层设1到2层比较合适多了容易过拟合每层隐藏单元数量设置在32到128之间。Transformer编码器设为1到2层如果数据量不大2层以上的Transformer几乎必然过拟合。注意力头数建议设为4或8头数太少建模能力不足头数太多会增加计算量且容易冗余。一个实测中比较实用的经验是BiLSTM的隐藏单元数可以适当大一点因为双向结构带来的参数量虽然翻倍但对短期模式的提取能力提升明显而Transformer的维度d_model可以设置与BiLSTM输出维度一致避免中间做大幅维度变换引入信息损失。残差连接和层归一化保留Transformer原版结构Dropout设置在0.1到0.3之间。如果发现验证集损失在训练过程中出现震荡或不降反升优先考虑调大Dropout或降低隐藏层维度。3.3 GWO优化目标超参数编码与适应度函数设计GWO的每个灰狼个体代表一组候选超参数组合。需要优化的超参数通常包括BiLSTM隐藏层神经元数、Transformer的d_model、注意力头数、Dropout比率、学习率、L2正则化系数。其中注意力头数是离散型整数变量学习率和L2正则化系数是连续的且量级跨越大常见在1e-4到1e-2之间GWO在处理这种混合类型的优化变量时需要对离散变量做取整处理对连续变量最好做对数缩放。灰狼位置的编码方式如下% x [hidden_num, d_model, num_heads, dropout, learning_rate, l2_reg] x [64, 32, 4, 0.2, 0.001, 0.0001]; % 实际优化时建议对连续变量取对数 x(5) log10(x(5)); % 学习率映射到对数量级 x(6) log10(x(6)); % L2系数映射到对数量级适应度函数的设置直接决定优化效果。我建议用小规模验证集上的均方根误差RMSE作为适应度值而不是在完整训练集上反复跑因为GWO每轮迭代都要评估整个种群的每只狼计算量非常大。实际操作中可以只取训练集的后20%作为快速验证集或者在一个有代表性的数据子集上评估能节省大量训练时间。我见过有些论文把训练过程中的损失函数值当作适应度这其实是不太合理的。训练损失只能反映模型在训练集上的拟合程度不能反映泛化能力。用验证集上的RMSE或MAE才能更真实地反映该组超参数的预测性能。4. Matlab仿真实现全流程4.1 环境准备与数据加载Matlab版本建议使用R2021a以上原因是深度网络设计器对Transformer相关层的支持更完善。需要安装Deep Learning Toolbox另外建议配好Statistics and Machine Learning Toolbox做数据统计分析并行计算工具箱不是必须的但如果数据量较大或者GWO种群规模较大多核并行训练能节省大量时间。数据加载上我习惯把所有数据整理成一个标准格式每一行是一个时刻的观测值每一列是一个特征维度。用一个简单的脚本就能把Excel或CSV数据导入并处理成滑动窗口样本function [X, Y] makeSlidingWindows(data, lookback, horizon) numSamples size(data, 1) - lookback - horizon 1; X zeros(numSamples, lookback, size(data, 2)); Y zeros(numSamples, horizon); for i 1:numSamples X(i, :, :) data(i : i lookback - 1, :); Y(i, :) data(i lookback : i lookback horizon - 1, 1); end end这个函数里lookback是回看窗口长度horizon是预测步数。如果做单步预测horizon设为1即可做多步预测时horizon大于1。注意这里的X第一维是样本数第二维是时间步第三维是特征数量这个维度顺序要和后续网络输入层的格式对应起来。4.2 GWO优化算法的Matlab实现GWO的核心代码并不复杂遵循算法原理就能实现。我给出关键部分的框架function [bestSolution, bestFitness, convergenceCurve] GWO(objFunc, dim, lb, ub, SearchAgentsNo, MaxIter) % 初始化狼群位置 Positions repmat(lb, SearchAgentsNo, 1) rand(SearchAgentsNo, dim) .* repmat((ub - lb), SearchAgentsNo, 1); Alpha_pos zeros(1, dim); Alpha_score inf; Beta_pos zeros(1, dim); Beta_score inf; Delta_pos zeros(1, dim); Delta_score inf; for iter 1:MaxIter % 逐个评估每只灰狼的适应度 for i 1:SearchAgentsNo Flag4ub Positions(i, :) ub; Flag4lb Positions(i, :) lb; Positions(i, :) (Positions(i, :) .* (~(Flag4ub Flag4lb))) ub .* Flag4ub lb .* Flag4lb; fitness objFunc(Positions(i, :)); % 更新alpha、beta、delta if fitness Alpha_score Delta_score Beta_score; Delta_pos Beta_pos; Beta_score Alpha_score; Beta_pos Alpha_pos; Alpha_score fitness; Alpha_pos Positions(i, :); elseif fitness Beta_score Delta_score Beta_score; Delta_pos Beta_pos; Beta_score fitness; Beta_pos Positions(i, :); elseif fitness Delta_score Delta_score fitness; Delta_pos Positions(i, :); end end % 线性衰减系数a a 2 - iter * (2 / MaxIter); for i 1:SearchAgentsNo for j 1:dim r1 rand(); r2 rand(); A1 2 * a * r1 - a; C1 2 * r2; D_alpha abs(C1 * Alpha_pos(j) - Positions(i, j)); X1 Alpha_pos(j) - A1 * D_alpha; r1 rand(); r2 rand(); A2 2 * a * r1 - a; C2 2 * r2; D_beta abs(C2 * Beta_pos(j) - Positions(i, j)); X2 Beta_pos(j) - A2 * D_beta; r1 rand(); r2 rand(); A3 2 * a * r1 - a; C3 2 * r2; D_delta abs(C3 * Delta_pos(j) - Positions(i, j)); X3 Delta_pos(j) - A3 * D_delta; Positions(i, j) (X1 X2 X3) / 3; end end convergenceCurve(iter) Alpha_score; end bestSolution Alpha_pos; bestFitness Alpha_score; end这段代码有几个点值得注意。位置越界处理我用的方法是“超边界的直接拉到边界上”这是最基础也最稳妥的处理方式比随机重新初始化更稳定。适应度评估时传入的objFunc函数句柄需要接受一组超参数向量内部完成训练并返回验证集误差。如果你有并行计算工具箱可以在for i 1:SearchAgentsNo这里改成parfor会快很多。还有一个实践经验GWO初始种群位置在解空间内随机分布这个随机性对最终结果有影响。建议固定随机种子rng(42)这种以便实验可复现否则同一个数据集跑两遍可能得到完全不同的最优超参数论文和报告里最好写明固定种子。4.3 Transformer-BiLSTM网络搭建与训练在Matlab中搭建这种混合网络我推荐使用dlnetwork对象配合自定义训练循环比直接使用trainNetwork要灵活得多。原因主要有两点一是trainNetwork对自定义层的支持不够灵活Transformer需要定义注意力层而标准工具箱对这类层的支持不完善二是GWO优化超参数时经常需要修改网络结构使用dlnetwork可以在脚本里动态构建网络并重新初始化不需要反复打开网络设计器。下面是一个基于dlnetwork构建Transformer编码器模块的核心思路。Matlab中用自定义层实现自注意力是可行的具体做法是创建一个继承自nnet.layer.Layer的类在predict函数里实现缩放点积注意力。这里我给出一个简化的多头注意力层核心代码classdef multiHeadAttentionLayer nnet.layer.Layer properties NumHeads KeyChannels end methods function layer multiHeadAttentionLayer(numHeads, keyChannels, name) layer.Name name; layer.NumHeads numHeads; layer.KeyChannels keyChannels; end function Z predict(layer, X) % X输入维度: [featureDim, numTimeSteps, numSamples] [featureDim, seqLen, batchSize] size(X); headDim featureDim / layer.NumHeads; % 线性投影并分割多头 Q fullyconnectForAttention(X, layer, query); K fullyconnectForAttention(X, layer, key); V fullyconnectForAttention(X, layer, value); % reshape为多头格式 % Q: [headDim, numHeads, seqLen, batchSize] % 缩放点积注意力 scores pagemtimes(permute(Q, [1 3 2 4]), ... permute(K, [1 3 2 4])); % 具体维度需调整 scores scores / sqrt(layer.KeyChannels); weights softmax(scores, 2); Z pagemtimes(weights, V); % 拼接多头并输出 end end end注意这里只是示意实际使用时需要仔细处理维度转换。Matlab的dlarray对象做这种高维矩阵运算确实比其他语言繁琐建议先用小数据验证维度正确性再跑全流程。网络整体结构用layerGraph就能搭建。BiLSTM层的创建用bilstmLayer函数参数为隐藏单元数。连接方式上BiLSTM输出后加上一个layerNormalizationLayer再接Transformer相关的自定义层最后通过fullyConnectedLayer和regressionLayer输出预测值。训练时的损失函数用均方误差最直观。自定义训练循环的核心代码大致是这样的for epoch 1:maxEpochs [loss, gradients] dlfeval(modelLoss, network, XTrain, YTrain, params); [network, velocity] adamupdate(network, gradients, velocity, learnRate); end这里modelLoss函数内部调用network的前向传播计算预测值和真实值之间的均方误差。注意dlfeval会启用自动微分梯度计算不需要手写反向传播。Matlab的自动微分对自定义层有额外要求——在predict或forward函数里使用的算子必须全部支持自动微分否则会报错。4.4 性能评估与可视化训练完成后要在测试集上评估模型性能。常用的指标有三个均方根误差RMSE、平均绝对误差MAE、决定系数R2。Matlab里计算这些指标非常直接rmse sqrt(mean((yTest - yPred).^2)); mae mean(abs(yTest - yPred)); r2 1 - sum((yTest - yPred).^2) / sum((yTest - mean(yTest)).^2);除了数值指标可视化也是性能仿真的重要部分。我习惯画三张图第一张是训练和验证损失随迭代变化的曲线用来判断是否过拟合第二张是GWO收敛曲线展示适应度值随迭代次数的下降趋势第三张是测试集上预测值和真实值的对比曲线可视化展示预测精度。在Matlab中保存这些图时建议设置exportgraphics函数输出高分辨率图片论文用起来更方便。5. 常见问题排查与避坑记录5.1 GWO容易早熟或收敛过慢怎么处理使用GWO最常见的问题是早熟收敛即算法在迭代早期就停滞在一个较差的局部最优解上。排查时先看收敛曲线如果适应度值在迭代不到一半时就持平不动了大概率是种群多样性不足。应对方法有三个。第一在GWO位置更新公式中加入自适应惯性权重让灰狼在迭代过程中对头狼的跟随程度动态变化第二种群初始化时采用混沌映射替代纯随机初始化让初始解在解空间分布更均匀第三在位置更新后加入随机扰动——类似变异操作——当某只灰狼连续多代没有改进时以较小概率重新随机初始化它的部分维度。实测下来第三种方法最简单有效也不怎么影响收敛速度。反向的问题也常见GWO迭代到后期还没收敛说明收敛过慢。通常是搜索空间范围设置太大了。超参数上下界定义要合理比如学习率的搜索范围可以设为[1e-4, 1e-2]dropout在[0.1, 0.5]之间不要设置过于宽泛的搜索区间否则狼群大部分时间都在无意义区域游荡。5.2 Transformer训练不稳定或过拟合的排查思路Transformer训练不稳定最典型的表现是训练损失震荡严重甚至发散。第一优先检查学习率——Transformer对学习率极其敏感batch size较大时应相应调大学习率自适应优化器如Adam的初始学习率建议不超过1e-3。第二是检查数值稳定性层归一化放在残差连接之前还是之后Pre-LN还是Post-LN会影响训练稳定性时间序列预测场景下Pre-LN通常更稳定。过拟合问题在Transformer中也很常见突出的表现是训练损失持续下降但验证损失上升到一定阶段开始反弹。优先尝试增加Dropout比例、减小Transformer层数、减小d_model维度。如果还不行考虑引入早停机制验证损失连续10个epoch不再下降时保存历史最佳模型并中断训练。很多人在Matlab里做Transformer时会忽略一个细节——在embedding层后不加Dropout。对时间序列这种相对简单的数据embedding之后的Dropout可以设得比内部层更高一些0.2到0.3都不为过对抑制过拟合帮助很大。5.3 数据预处理与评估中的隐藏陷阱这里我重点说两个我踩过的坑。第一个是数据泄漏——归一化参数的估计直接使用全部数据。解决办法前面提过归一化参数只从训练集计算验证集和测试集复用同一组参数。很多人在论文中不写这个细节但从严谨角度讲这其实是决定结果可信度的关键步骤。第二个是多步预测时用错了评价方式。多步预测有两种实现策略滚动预测和直接预测。滚动预测是把上一步的预测值作为下一步的输入这种做法误差会随时间步累积越往后预测越差直接预测是模型一次输出多个未来时刻的值。GWO优化时适应度函数的设置要和最终应用一致——如果你最终是要做未来24小时的多步预测那适应度函数应该用多步预测的RMSE而不是只用第一步的预测误差。很多论文在这里偷懒导致实际部署效果远不如实验结果这类方法论问题要特别留意。另外还有一个容易被忽视的细节是滑动窗口的样本之间高度相关——相邻样本只差一个时间步。这会导致训练集和验证集之间存在信息重叠验证集的指标可能虚高。如果数据量允许可以把样本不重叠地划分比如每个样本起始点间隔等于lookback长度这样能有效降低样本相关性。5.4 Matlab实现中的性能优化技巧最后分享几个Matlab跑这套模型的实际提速技巧。第一个是尽量使用GPU训练。如果你的显卡显存足够至少6GBMatlab里使用gpuArray将数据转成GPU格式训练速度能提升5到10倍。没有GPU的机器上降低batch size有助于减少内存压力。第二个是用单精度训练。Matlab默认用双精度但在深度学习训练中单精度完全够用而且显存占用减半、计算速度翻倍。使用dlarray时可以通过Format参数指定数据格式配合cast调整精度。第三个是GWO并行评估。GWO每轮迭代中每个灰狼的训练任务相互独立完全可以用parfor替代for循环并行评估所有灰狼的适应度。第一次使用parfor时要初始化并行池有一定时间开销但后续每轮都能省下大量时间。如果机器核心数够多整个GWO寻参过程能缩短一半以上。我在实际跑这套模型时最后的体会是混合模型不是简单的“拼积木”每个模块都在特定层面发挥作用——BiLSTM管局部、Transformer管全局、GWO管超参寻优三者缺一不可。Matlab作为实现平台坑虽然比Python多比如自定义层的自动微分支持、GPU显存管理这些但胜在代码的调试可视化体验更好非常适合做消融对比实验和性能仿真。如果你打算在论文里用这套方法建议务必做三组对比实验纯BiLSTM、Transformer-BiLSTM不调参、GWO-Transformer-BiLSTM这样能充分说明每个模块的贡献。后续想继续扩展还可以尝试把GWO换成改进版混合算法或者加入变分模态分解先对原始序列做模态分解效果往往会有新的提升。
返回列表