首页 / 资讯中心 / 文章详情

智能优化算法优化深度极限学习机的回归预测与MATLAB实现

智能优化算法优化深度极限学习机的回归预测与MATLAB实现 ★ FEATURED ARTICLE
用智能优化算法去啃深度极限学习机DELM这种组合在预测模型领域其实是个很实在的套路。这个项目标题里的核心思路并不复杂先用深度极限学习机搭一个能处理非线性回归预测的深层网络骨架然后让灰狼优化GWO、多元宇宙优化MVO、风驱动优化WDO这些群体智能算法去自动搜索网络最关键的初始化参数最后在MATLAB里完成整套训练、预测和评估。说白了就是用元启发式算法去解决DELM随机初始化不稳定、容易陷入局部最优的问题。我整个项目做下来最直观的感受是这套方案比手动调参靠谱得多尤其是在数据维度高、样本量又不算大的回归预测任务里优化前后的预测精度差距经常是肉眼可见的。这篇文章就把我实际实现GWO-DELM、MVO-DELM、WDO-DELM三种模型的过程、踩过的坑和调参心得完整梳理一遍适合正在做预测模型研究、需要复现智能优化算法对比实验的开发者参考。1. 方案选型为什么是DELM为什么需要优化算法1.1 从ELM到DELM深度极限学习机到底改了什么极限学习机ELM这个名字听起来很学术但它的核心思想其实就一句话单隐层前馈神经网络的输入权重和偏置可以随机生成不需要像BP神经网络那样反复迭代调整只需要用最小二乘法求解输出权重即可。当年ELM之所以火就是因为它把神经网络训练从反复迭代、动不动就陷入局部最优变成了一步到位、几毫秒出结果。但是ELM有个硬伤单隐层的特征表达能力有限。面对高度非线性的回归预测任务单隐层ELM的拟合能力往往不够用于是出现了深度极限学习机Deep ELMDELM。DELM的思路是把这个单隐层结构堆叠起来一层一层做无监督的极限学习机自编码ELM-AE特征提取每一层把原始输入变换到更高阶的抽象特征空间最后再接一个回归输出层。这里有个容易被忽略的细节DELM虽然带了深度两个字但它本质上不是靠反向传播来训练的。它的每一层训练仍然是解析解——通过ELM-AE把上层输出变换成下层输入逐层预训练完成后再整体求解输出权重。这种逐层非迭代训练的方式让DELM同时拥有了深度网络的特征学习能力又保留了ELM训练速度快、不容易过拟合的优点。1.2 随机参数带来的痛点为什么必须引入优化算法DELM训练速度快是优势但这个优势背后藏着一个绕不开的问题每一层ELM-AE的输入权重和偏置都是随机生成的。随机意味着什么意味着你每次跑同样的数据集得到的模型效果可能差别很大。我做过一个对比实验同一个数据集同一个DELM网络结构只是随机种子不同跑了十次。最好的预测均方根误差RMSE和最差的之间能差出30%甚至更多。这对于做预测模型的人来说是没法接受的——你做科研、做工程交付总不能告诉别人我这个模型效果看运气。更麻烦的是如果你为了追求稳定性和精度去手动调节每层的随机权重范围、稀疏比例、激活函数参数那个组合空间大到根本调不过来。这时候群体智能优化算法就派上用场了——它们的本质作用是把DELM每层的初始化参数拼接成一个向量把这个向量当作优化问题的决策变量然后用适应度函数比如验证集上的RMSE或者均方误差作为目标函数让算法自动搜索出一组让预测效果最优的初始化参数。说白了这不是什么玄学就是把调参这个本来靠经验和运气的活儿变成了一个可量化、可搜索的数学优化问题。1.3 GWO、MVO、WDO三种算法的选型参考市面上元启发式算法非常之多为什么这个项目偏偏选了灰狼优化、多元宇宙优化、风驱动优化这三个我个人的理解是它们代表了三类完全不同机制的优化思路用来做对比实验非常有代表性灰狼优化Grey Wolf OptimizerGWO模拟灰狼种群的社会等级和狩猎行为核心在于包围—追捕—攻击三个动作。它最突出的优点是参数少、结构简单几乎不需要调整额外参数收敛速度也快适合作为基准优化器。多元宇宙优化Multi-Verse OptimizerMVO基于宇宙学中的白洞、黑洞、虫洞概念设计。它通过物质在宇宙间穿越的机制来平衡全局搜索与局部搜索在处理高维问题时表现比较稳不容易早熟。风驱动优化Wind-Driven OptimizationWDO从大气运动规律抽象出来的算法把每个粒子看成空气质点用气压差驱动粒子移动。它的特点是局部搜索能力很强在维度较高的参数空间里经常能找到更精细的解但相应地收敛速度会慢一些。这三种算法在搜索机制上差异明显做横向对比时能直观反映出不同搜索策略对DELM参数优化的影响差异这也是在论文里做对比实验时很常见的选择组合。实际使用中我不只测过这三种像粒子群优化PSO、鲸鱼优化WOA也试过相比之下GWO和MVO在中等规模参数空间20到50维内的综合表现最均衡。2. 三种优化算法的原理与MATLAB实现细节2.1 GWO灰狼优化等级制度驱动的快速收敛GWO是2014年提出的一种元启发式算法核心设计灵感来自灰狼群体的社会层级狼群里面有头狼alpha、副手beta、执行者delta和底层成员omega。狩猎时alpha、beta、delta三只狼引导整个群体向猎物最优解逼近omega成员则围绕这三只狼的位置更新自己的位置。在MATLAB里的实现框架其实很精炼。种群每个个体代表DELM的一组参数向量初始化后每次迭代都要做这几步% 核心更新公式示意 % X为种群位置A和C为系数向量X_alpha、X_beta、X_delta为三头引导狼的位置 D_alpha abs(C1 .* X_alpha - X); D_beta abs(C2 .* X_beta - X); D_delta abs(C3 .* X_delta - X); X1 X_alpha - A1 .* D_alpha; X2 X_beta - A2 .* D_beta; X3 X_delta - A3 .* D_delta; X_new (X1 X2 X3) / 3;系数A和C的设计是GWO的精髓A2a·r1-a其中a从2线性递减到0控制的是全局探索和局部开发的平衡C2·r2决定引导狼对当前位置的影响权重。这个机制不复杂但非常高效——它让种群前期在广阔空间里扫荡后期逐渐收缩到最优解附近做精细搜索。我在实际测试中的感受是GWO在DELM参数优化任务中收敛速度是三个算法里最快的通常迭代30到50次就能达到一个不错的精度水平。代价是它的最终收敛精度有时候不如MVO和WDO在高维、多峰的目标函数空间里存在陷入局部最优的可能。注意GWO虽然参数少但种群大小和迭代次数的设置仍然直接影响效果。我常用的配置是种群数30、迭代次数50这个量级在多数回归预测数据上已经够用。如果数据维度特别高可以适当把迭代次数提到80到100。2.2 MVO多元宇宙优化虫洞机制带来的全局搜索优势MVO的灵感比GWO要抽象一些——它模拟的是多个宇宙通过白洞、黑洞、虫洞交换物质的过程。在算法里每个宇宙对应一个候选解宇宙中的物质对应决策变量适应度函数值对应宇宙的膨胀率。MVO的核心机制可以拆成三个算子白洞-黑洞隧道探索阶段适应度好的宇宙把物质传递给差的宇宙、虫洞隧道开发阶段宇宙中的物质通过虫洞向最优宇宙移动、以及随着迭代动态调整的宇宙膨胀率。在MATLAB里虫洞隧道这一部分是最关键的更新逻辑% MVO虫洞机制的核心更新示意 for j 1:dim r1 rand(); r2 rand(); if r2 WEP % WEP为虫洞存在概率随迭代递增 if r1 0.5 % 物质向最优宇宙移动 X(i, j) Best_universe(j) TDR * ((UB(j)-LB(j)) * rand LB(j)); else % 物质偏离最优宇宙 X(i, j) Best_universe(j) - TDR * ((UB(j)-LB(j)) * rand LB(j)); end end end这里面的WEP虫洞存在概率和TDR行进距离率是两个随着迭代次数动态调整的关键参数WEP从0.2逐步升到1TDR从1逐步降到0。这个动态调整的作用是让算法在前中期保持较强的全局搜索能力后期逐步收窄搜索范围去精细化。我在用MVO优化DELM时发现它的优势场景非常明确——当DELM的隐层节点数比较多、参数维度上去之后GWO有时候会在迭代后期停滞而MVO凭借虫洞机制能跳出局部极值最终找到的RMSE数值往往更低。2.3 WDO风驱动优化空气动力学模型的高精度搜索WDO是三者里面最冷门的一个但它优化DELM的效果却经常是最好的。它的灵感来源是大气中空气质点从高压区向低压区运动的过程——每个空气质点被气压差力、科里奥利力、摩擦力等多个物理力共同影响最终形成一套位置更新方程。WDO和其他智能算法的最大区别在于它的速度更新公式不是仿生学的简单加减法而是有明确的物理含义空气质点的速度变化由气压梯度力驱动同时被摩擦力衰减、被科里奥利力偏转。这意味着WDO的搜索路径更像一条有惯性的连续轨迹而不是像GWO那样直接向引导狼位置聚合。WDO的核心更新方程如下% WDO速度位置更新示意 % 其中 pressure 是适应度相关的气压值alpha为摩擦力系数g为重力加速度 vel_new (1-alpha) * vel_old - g * x_old ... (RT * (1/pressure_max - 1/pressure_current)) * (ub-lb) .* rand ... c * other_dim_vel(randperm) ; x_new x_old vel_new;这里需要注意几个参数RT是气压常数alpha是摩擦力系数c是科里奥利力影响系数它们分别控制了搜索的活跃程度、衰减速度和方向多样性。WDO的局部开发能力非常强在DELM参数优化中经常能在最后几十次迭代里把RMSE再压下去一小截。不过WDO也有它的短板——参数数量比GWO和MVO都要多而且这些参数对结果比较敏感。用默认参数跑出来的效果往往不是最优的需要根据具体数据做一两次预实验来调整alpha和RT。2.4 三种优化算法的机制对比与选型建议我把这三种算法放在同一个DELM回归预测任务里跑了多组实验为了方便对比整理了一张参数和特性对照表算法核心搜索机制主要参数收敛速度最终精度适用场景GWO社会等级引导的包围狩犡种群数、迭代数快30-50次中等参数维度不高、需要快速出结果MVO白洞黑洞物质交换 虫洞跳转WEP、TDR中等50-80次较高高维参数、易早熟的复杂目标函数WDO气压驱动的空气动力学运动RT、alpha、c较慢80次以上高追求极致精度、可接受更长训练时间这个表不是绝对的实际效果和具体数据集强相关。我的经验是如果做对比实验需要三套模型结果都好看最稳妥的做法是每个算法都设置两组不同迭代次数一组统一50次做横向对比一组根据算法特性单独加大迭代次数追求最优值。3. MATLAB完整实操从数据预处理到模型训练评估3.1 数据准备与预处理预测模型的地基不管是GWO-DELM还是MVO-DELM第一步永远都是处理数据。这部分如果偷懒后面模型再优化效果也打折扣。我常用的数据格式是Excel表格每一行是一个样本最后一列是目标值其他列是输入特征。数据预处理有两条红线必须守住一是归一化必须在划分训练集测试集之后做二是测试集的归一化参数必须由训练集计算得到。原因其实很简单——测试集在真实场景里是未来数据你在训练阶段不应该提前知道它的最大值和最小值。如果直接用全体数据的最小最大缩放相当于让模型偷看了未来的信息范围测试结果会虚高。% 训练测试集划分与归一化 ratio 0.8; num_train floor(size(X, 1) * ratio); X_train X(1:num_train, :); y_train y(1:num_train, :); X_test X(num_train1:end, :); y_test y(num_train1:end, :); % 只基于训练集计算归一化参数 [X_train_norm, ps_input] mapminmax(X_train, 0, 1); [y_train_norm, ps_output] mapminmax(y_train, 0, 1); X_test_norm mapminmax(apply, X_test, ps_input);此外还有一个容易被忽视的操作——特征相关性筛查。我在做某个气象回归预测项目时原始数据里有三十多个候选特征其中好几个特征之间的皮尔逊相关系数超过了0.9。这种强相关特征会让优化算法在搜索时收到冗余信号白白增加维度。所以归一化之前先用corrcoef快速筛一遍相关性高的特征把它只保留其中一个后者用PCA做降维都是值得做的。3.2 DELM网络架构设计与参数编码DELM的架构设计核心是确定三件事层数、每层隐层节点数、以及输出层节点数。输出层节点数在单输出回归任务里就是1不用纠结。层数和节点数则需要和优化维度一起权衡——因为优化算法的搜索维度是由DELM的参数量决定的。这里要特别解释一下参数向量是怎么构造的。我的做法是把DELM每一层ELM-AE的输入权重矩阵全部展开成一维向量再拼接起来% 假设DELM有三层每层隐节点数为hidden1、hidden2、hidden3 % 输入节点数为input_size dim1 input_size * hidden1; % 第一层输入权重数量 dim2 hidden1 * hidden2; % 第二层输入权重数量 dim3 hidden2 * hidden3; % 第三层输入权重数量 total_dim dim1 dim2 dim3;这个total_dim就是优化算法的搜索维度。比如说输入特征有10个第一层节点20个第二层节点15个第三层节点10个那总维度就是200300150650维。这个维度对于元启发式算法来说已经不低了所以设计网络层数和节点数时不能贪多——每多一层、每多几十个节点都会显著放大优化搜索的难度。我自己常用的DELM结构是三层隐层节点数从输入维度出发逐层递减比如 [20, 15, 10] 这种格局。递增结构如 [10, 15, 20]我也试过但在多数回归数据集上递减结构的特征压缩效果更稳定训练时间也更短。3.3 优化算法的目标函数设计训练集还是验证集优化算法在搜索DELM参数时需要靠目标函数来评判每一组参数好不好。这一步是整个项目中最需要谨慎设计的地方——目标函数选错了后面全白搭。我见过不少初学者直接把训练集的拟合误差作为目标函数结果就是模型在训练集上精度极高测试集上一塌糊涂典型的过拟合。正确的做法是留出一部分验证集数据用模型在验证集上的预测误差作为目标函数。更稳妥的做法是采用K折交叉验证的误差平均值这样搜索出来的参数鲁棒性更好。function fitness delmFitness(param_vector, X_train, y_train) % 将参数向量还原为DELM每层的输入权重矩阵 % 训练DELM并计算验证集上的均方误差MSE作为适应度值 % 注意这里的X_train实际上是划分出来的训练子集验证集单独传入 fitness mse(net_output - y_val); end这里还有个细节因为DELM每一层输入权重被随机初始化所以即使你用优化算法找到了一组好的初始权重算法内部的随机性还是会带来一定抖动。我的应对方式是每次迭代对同一个参数向量重复训练两次取两次验证集误差的平均值作为适应度。虽然计算量翻倍但优化过程的稳定性明显提高找到的最优参数也更可信。3.4 训练流程与关键代码结构把整个流程串起来GWO-DELM的训练主循环大致可以分成三层结构外层是优化算法的迭代循环中层是对每个种群个体做一次完整的DELM训练评估内层是DELM的前向传播和输出权重求解。% 主循环伪代码结构 for iter 1:max_iter for i 1:pop_size % 1. 将种群个体位置解码为DELM各层输入权重 % 2. 逐层执行ELM-AE特征提取 % 3. 求解输出层权重最小二乘 % 4. 在验证集上计算预测误差作为个体适应度 fitness(i) evaluateDELM(pop(i, :)); end % 根据算法类型更新种群位置GWO/MVO/WDO各自实现 pop update_population(pop, fitness); endDELM的前向传播核心就是ELM-AE的逐层变换。ELM-AE的数学本质是把输入矩阵X经过随机映射得到隐藏层输出H然后要求解一个能重构X的输出权重矩阵也就是解一个最小二乘问题。MATLAB里用pinv伪逆可以直接求解非常高效function H elm_autoencoder(X, num_hidden, activation) % 随机生成输入权重W和偏置b W rand(size(X, 2), num_hidden) * 2 - 1; b rand(1, num_hidden) * 2 - 1; % 计算隐藏层输出 H X * W b; % 激活函数可选 sigmoid / tanh / relu switch activation case sigmoid H 1 ./ (1 exp(-H)); case tanh H tanh(H); case relu H max(0, H); end endDELM和传统自动编码器有个区别ELM-AE在编码过程中如果重构的目标和输入完全相同直接用恒等映射就能达到很好的重构效果这样学到的特征就没有意义了。所以实际使用中ELM-AE往往会在输入侧加入噪声扰动或者扔掉部分信息来强制学习更有泛化能力的特征。在MATLAB里实现时可以简化处理直接让隐藏层节点数小于输入维度起到压缩特征的作用。在输出层部分做法是先计算最后一层ELM-AE输出的特征矩阵F然后用伪逆求解回归输出权重betabeta pinv(F) * y_train_norm; % 测试阶段预测 Y_pred_norm F_test * beta; Y_pred mapminmax(reverse, Y_pred_norm, ps_output);3.5 结果评估与可视化模型训练完成之后评估部分不能只放一个误差数值就完事。我的习惯是同时输出四个指标RMSE、MAE、MAPE和R2。这四个指标从不同角度刻画了预测效果的优劣RMSE对大误差敏感MAE反映平均偏差绝对值MAPE体现百分比误差R2说明模型对目标变量方差的解释程度。% 指标计算 RMSE sqrt(mean((y_test - y_pred).^2)); MAE mean(abs(y_test - y_pred)); MAPE mean(abs((y_test - y_pred) ./ y_test)) * 100; R2 1 - sum((y_test - y_pred).^2) / sum((y_test - mean(y_test)).^2);除了数值指标我强烈建议把训练过程的收敛曲线画出来以及测试集的预测值与真实值对比图。收敛曲线能够直观看出优化算法在迭代过程中适应度下降的趋势如果在后期仍然有明显下降说明迭代次数还没跑够。预测对比图则能让审阅者一眼看出模型的拟合质量尤其是峰值处的预测能力。MATLAB画图这部分不复杂但有一个细节收敛曲线的纵轴如果横跨多个数量级用线性坐标看会显得前面一大段都是平的改成semilogy或者对适应度取log之后展示图像会清楚很多。4. 常见问题与调参经验实录4.1 优化算法收敛过早停滞怎么办这个问题我在跑MVO-DELM时第一次遇到适应度曲线迭代到二十多次就开始横盘后面三十多次迭代基本不下降。后来排查发现不是算法本身的问题而是我把种群规模和迭代次数设计得不匹配——维度高达数百维的参数空间里30个种群个体远远不够搜索覆盖面太窄算法很容易早熟。解决办法是把种群数从30提到50到60同时把参数搜索的上界从1.0扩大到2.0。因为DELM的输入权重如果限制在[-1, 1]区间表达空间太受约束放宽到[-2, 2]之后优化算法的搜索空间变大早熟现象明显减少。另外对GWO来说我还会检查是否代码里a的线性递减没有从2开始如果a初始化数值不对全局探索能力会被削弱这是实现时常见的低级错误。4.2 DELM隐层节点数过多导致维度爆炸有一次我把DELM设为四层每层节点数都是50以上结果输入宽度只有12列特征但优化参数维度却达到了近万。那一次训练耗时非常夸张而且最终精度并没有比三层结构高出多少。后来我做了几组实验结论是对于大多数中小规模回归数据集DELM层数在三层以内、每层节点数在5到30之间性价比是最高的。参数维度与优化算法性能之间的关联我自己的经验阈值是这样的优化维度范围推荐DELM结构推荐算法配置50维以内2层节点数[10, 5]种群数20迭代30次50-200维3层节点数[20, 15, 10]种群数30迭代50次200-500维3层节点数[30, 20, 10]种群数50迭代80次500维以上考虑减少节点数或增加随机失活约束种群数60迭代100次关于这个阈值背后的逻辑其实很简单优化算法的搜索能力是由种群规模和迭代次数决定的而参数维度决定了搜索空间的规模。两者必须匹配不然要么搜不满要么搜不完。4.3 训练集效果和测试集效果差异过大这就是典型的过拟合信号。DELM本身因为有逐层无监督预训练和对输出权重的最小二乘约束过拟合倾向比传统深度网络小一些但引入优化算法之后情况会发生变化——优化算法会在训练数据上精准地找到一组参数让验证集误差最小这时候如果验证集规模太小它实际上就是在对验证集过拟合。我踩过这个坑某次实验把训练集和验证集按9比1划分优化过程中适应度确实一路下降但测试集上一测结果很差。后来把划分改成更为均衡的比例比如8比2或者7比3并且注意到一个关键问题——目标函数里必须加入对输出权重范数的惩罚项也就是在计算适应度时使用带L2正则的最小二乘解而不是直接pinv。% 带L2正则的输出权重求解 C 0.1; % 正则系数 beta (F * F eye(size(F,2)) / C) \ (F * y_train_norm);这样改完之后测试集效果和训练集效果的差距明显缩小。正则系数C的选取我用的是快速网格搜索法分别试0.01、0.1、1、10四个值看验证集误差最小的是哪个再在其附近细化搜索。4.4 三种算法的参数敏感性对比在实际调参过程中我总结了一个整体的感受GWO对种群大小不太敏感对迭代次数上限比较敏感MVO对WEP和TDR的初值有要求但算法本身的动态调整机制能自动适应大部分场景WDO则需要针对具体数据调整RT和alpha不然容易发散或者陷入局部最优。小技巧分享WDO的alpha摩擦力系数不要设成0那样空气质点永远保持高速运动后期很难收敛也不要太大我试过alpha0.9的时候粒子几乎原地打转。对大多数DELM优化任务alpha在0.3到0.5之间RT在2到4之间是比较安全的起步范围。4.5 随机种子对结果的影响与复现技巧智能优化算法本质上是随机搜索算法所以每次运行结果不完全一致是正常的。但如果结果波动大到影响结论那就要注意两个控制点一是MATLAB全局随机种子二是DELM内部权重生成时使用的随机流。rng(42); % 固定全局随机种子保证实验结果可复现我的习惯是每个算法跑5次独立实验报告平均值和标准差。这样既体现了算法的稳定性也避免了一次运气好导致的结果虚高。用这个口径去对比GWO-DELM、MVO-DELM、WDO-DELM得到的结论才可信。在论文或者项目报告中应该注明随机种子和重复次数这一点在做横向对比时尤其重要。5. 实操心得与后续扩展建议整套项目做完之后说实话我对优化算法深度极限学习机这个组合的评价是实用价值高于代码复杂度。DELM的训练机制本来就很轻量不需要GPU、不需要跑几百轮反向传播优化算法虽然会增加一些迭代开销但总训练时间仍然远小于训练同等规模的传统深度网络。对于数据量几百到几千条、特征维度几十维的中小规模回归预测任务这套方案在精度和成本之间的平衡非常理想。如果说有什么经验是最值得分享的那就是不要把所有精力都花在优化算法本身上。数据预处理的质量、特征筛选的合理性、DELM网络结构的选择这些环节对最终预测效果的影响往往比换一个优化算法更大。我自己刚开始做的时候执着于对比GWO、MVO、WDO哪个收敛曲线更好看后来发现把时间花在特征工程上效果提升得更明显。项目后续的扩展空间也比较大。比如可以把优化算法换成最近几年新出的黏菌算法、麻雀搜索算法等扩展成一整套多算法对比框架也可以在DELM的每层之间加入Dropout策略进一步提升泛化性能甚至可以把单输出回归改成多输出回归或者分类任务只需要改动输出层的解码方式即可。只要基础框架搭得结实这些扩展都在可控成本之内。
阅读完成 · 觉得有帮助?
咨询建站