瞬态三角哈里斯鹰优化TTHHO优化RBF网络分类预测
我不是第一次对RBF网络“下手”但哈里斯鹰优化算法这东西确实值得单独写一篇。很多人一提到RBF网络觉得不过是个三层前馈网络中心用K-Means选一选宽度给个经验值权重用最小二乘求一下分类就完事了。真到动手跑分类预测才发现中心选在哪、宽度给多大结果差距能到十几二十个百分点。而HHO这类元启发式算法又常常被吐槽收敛慢、容易早熟。所以这篇就是用改进的瞬态三角哈里斯鹰优化算法TTHHO去优化RBF网络做一个完整的分类预测方案附带Matlab代码思路与对比实验适合正在做故障诊断、模式识别、分类预测研究的朋友参考。1. 先搞清楚要解决什么问题1.1 RBF网络为什么值得用径向基函数网络RBF的本质是用一组径向对称的基函数去逼近任意非线性映射。它的好处很实在结构简单隐含层激活函数局部响应训练速度快只要中心、宽度、权重选得合适分类精度不会输给多层感知机。而且在工程里RBF网络不容易出现反向传播那种梯度消失和局部极值堆叠的问题。它的训练过程可以拆成两段先定中心和宽度再解线性权重。这个性质是后面用优化算法改造它的基础。但RBF的“快”是建立在一个看似简单却非常麻烦的前提上的网络质量几乎完全依赖于隐含层中心节点和宽度参数的取值。中心放在样本密集的区域宽度太小会过拟合宽度太大会把不同类别的响应糊在一起。传统K-Means只能给出一个初始位置谈不上全局最优。这就是我为什么一开始就走“智能优化RBF”这条路的原因。1.2 RBF的优化核心中心、宽度、权重的三难问题展开说RBF网络需要确定的参数可以分成三类。第一类是隐含层中心向量C每个中心是输入空间里的一个点决定了基函数在哪个区域“响应”。第二类是宽度参数σ它控制径向基函数的有效半径。第三类是输出层权重W在中心和宽度确定之后权重可以通过线性最小二乘或者伪逆直接求解。前两类参数才是优化的关键也是最难调的部分。它们既有连续性质又有拓扑性质中心的分布需要覆盖样本空间宽度需要匹配每个中心周围的样本密度。如果手动试几乎无从下手。而且这两个参数之间还有耦合关系中心密集的区域宽度得适当缩小中心稀疏的区域宽度得放大否则覆盖不到。一个维度为D的输入数据如果把中心、宽度、权重全部编码进一个个体里编码长度是M×D M M×K其中M是隐含节点数K是输出维数。以经典的植物分类数据集为例四维特征、三类别、六个中心时编码长度约46维这个规模完全在元启发式算法的射程内。这也是整条技术路线能成立的前提问题维度不算夸张但局部极值丰富线性下降的搜索策略容易卡死。所以需要一个能在探索和开发之间反复震荡的算法。2. 哈里斯鹰优化算法的攻防逻辑2.1 探索阶段到处找兔子哈里斯鹰优化算法模拟的是哈里斯鹰群体捕猎兔子的过程核心策略随兔子的逃跑能量变化而切换。先看第一阶段探索。这个阶段里鹰群不知道兔子在哪只能四处搜索。标准HHO引入了两种随机搜索机制。第一种是随机选中一只鹰然后依赖另一只鹰的位置生成新位置公式是“随机个体位置减去随机系数乘上随机个体与当前个体的距离”。这样做的意思是让搜索轨迹不要趋于一个固定方向全图随机性强。第二种是把当前个体往种群平均位置靠拢并且在整个搜索空间内叠加一个随机偏移。这两种机制组合保证了前期搜索范围的覆盖。探索阶段只需要保障一点样本个体不是因为互相靠得太近而集体丢失多样性。很多改进算法死在前期就是因为迭代一开始种群就扎堆后期无论怎么切换策略都救不回来。标准HHO一般不会犯这个错它靠的是随机个体更新不是只围绕当前最优个体行动。2.2 攻击切换的关键逃逸能量E哈里斯鹰算法里最核心的控制参数是逃逸能量E。它的计算方式是E 2 * E0 * (1 - t/T)其中E0是每次迭代开始时在[-1,1]区间随机取的初始能量t是当前迭代次数T是最大迭代次数。可以这样理解E兔子的体力从2开始随着猎捕时间推移逐步下降。当E的绝对值大于等于1说明兔子精力充足鹰群继续探索当E的绝对值小于1兔子疲劳鹰群转入开发阶段开始围攻。这个参数决定了算法什么时候从“广撒网”切换成“集中打击”。标准HHO的E是一条直线从初始值一路减到0。这样做确实有效但问题也很明显直线衰减意味着中后期几乎不可能再回到探索状态一旦种群在某个局部区域扎堆全局搜索能力就没了。这个缺陷正是我后面做改进的最大动机。2.3 开发阶段的四种围攻策略当兔子能量不足时鹰群会采用四种围攻策略具体用哪个取决于随机因子r和当前|E|的组合。这里的r表示兔子有没有成功逃脱。第一种是软围攻对应r0.5且|E|0.5。这时候兔子还在挣扎但能量不足鹰群的位置更新围绕“兔子当前位置与鹰当前位置的差值”展开。第二种是硬围攻对应r0.5且|E|0.5兔子体力几乎耗尽鹰群直接向兔子当前位置猛扑更新依赖E和当前鹰与兔子之间的距离。第三种和第四种比较特殊都是渐进式快速俯冲。区别在于软围攻带俯冲时鹰群先假设一个带随机跳跃强度的位置Y再用莱维飞行生成一个更远的试探位置Z如果Y和Z里有更好的就更新否则维持原位置。硬围攻带俯冲则是围绕种群平均位置来做上面的操作。莱维飞行在这里的作用是让鹰群具备“长尾跳跃”的能力避免一直跟在兔子身后小幅移动。四种策略相互配合形成了一个完整的捕猎框架。标准HHO在中等难度优化问题上表现相当能打但一旦问题具有大量欺骗性局部极值它还是会因为开发阶段缺乏波动而陷入早熟。3. TTHHO的瞬态三角改进设计3.1 改进一三角波包络的瞬态逃逸能量针对标准HHO逃逸能量直线衰减的缺陷我在TTHHO中引入了瞬态三角波包络。实现思路是给原始的E乘上一个与当前迭代进度相关的三角波函数而不是让E单调递减。具体表达式为tri 1 - abs(2 * t / T - 1) E 2 * E0 * (1 - t / T) * (0.5 0.5 * tri)这里的tri是一个周期性的三角波分量它的最大值出现在迭代中途。所以E不再是一条条均匀下落的直线而是会在整体下降的趋势中反复起伏。比如迭代到中期时tri接近1E会被放大兔子的“体力”仿佛又回了一点鹰群会临时转回探索模式而迭代后期tri接近0E又被压缩鹰群才真正进入猛攻阶段。这招的核心价值在于给算法一个“后悔药”。一旦前期种群所有个体都围着某个局部最优打转标准HHO几乎不可能再跳出来。而TTHHO的能量震荡会让个体在中期有机会跳出当前的搜索盆地重新大范围搜索。我在多个测试函数上观察过加了三角波包络之后收敛曲线在迭代后半段会出现明显的“二次下降”这正是算法跳出局部极值的信号。这不是玄学是E的动态变化直接改变了探索与开发的时间比例。3.2 改进二三角游走的局部逃逸算子第二个改进用在位置更新环节。标准HHO在软围攻和硬围攻阶段个体位置更新的随机性来源只有E和随机系数轨迹比较规则容易被“困住”。我在这里加入了一个基于三角分布的随机游走项叫三角游走算子。三角分布由三个参数控制下限a、上限b、众数c。它的随机数可以用两个均匀随机数生成r rand if r (c - a) / (b - a) step a sqrt(r * (b - a) * (c - a)) else step b - sqrt((1 - r) * (b - a) * (b - c)) end将这个三角分布生成的步长叠加到围攻策略的位置更新中可以让个体在保持追击方向的同时产生非对称的局部试探。与正态分布相比三角分布的取值范围边界明确、不会产生极端离群步长适合控制局部扰动的幅度。与均匀分布相比它又能让步长朝向众数区域集中局部搜索更有方向感。我在实现时把三角游走项的系数设计成随着迭代动态衰减的瞬态形式比如乘以(1 - t/T)的平方根。前期步长大帮助探索后期步长小保证精细开发。这样一来“瞬态”和“三角形”两个关键词都落到了实处。3.3 改进后的算法流程把两个改进组装进标准HHO框架后TTHHO的整体执行逻辑如下初始化种群在搜索空间内随机生成N只鹰的位置计算每只鹰的适应度确定当前猎物位置rabit。循环迭代每次迭代先根据当前迭代次数计算三角波包络tri生成初始能量E0得到瞬态三角逃逸能量E。判断阶段如果|E|1进入探索阶段沿用标准HHO的两种随机策略如果|E|1进入开发阶段。开发阶段内部根据随机因子r和|E|具体落入四种围攻策略中的哪一种在做位置更新时叠加三角游走扰动项。更新个体位置后检查越界计算适应度比较并更新最优个体rabit。到达最大迭代次数后输出最优解。从工程角度看这个改动没有改变标准HHO的主体循环结构只增加了一个三角波函数和一个随机数生成函数。代码改动量不大但换来的搜索行为改善却非常明显。这也是我觉得这类“小改大收益”的思路值得分享的原因。4. 用TTHHO优化RBF的整体方案4.1 编码方式一个个体就是一组RBF参数在TTHHO优化RBF网络时最重要的一步是把RBF网络的参数编码成鹰个体的位置向量。我采用的编码方式如下个体向量的前半段按顺序排列所有隐含层中心节点的各维坐标后半段排列每个中心对应的宽度参数。输出权重不参与编码因为它在中心、宽度确定后能用最小二乘解析求出。以输入维度D、隐含节点数M为例个体编码长度是M×D M。比如鸢尾花数据D4M6编码长度就是28。这个长度对TTHHO的搜索压力很小。解码的时候先从前M×D个分量中还原出M×D矩阵每行是一个中心向量再从最后M个分量中还原出每个中心对应的σ值。这种编码的最大优点是避免把权重也塞进优化空间里。权重的取值范围和中心完全不同混在一起会降低搜索效率。既然权重有闭式解就没必要浪费优化资源去搜。这个取舍理解起来很简单能让数学方法解决的部分就别让启发式算法去碰。4.2 适应度函数与交叉验证适应度函数就是优化过程中的“裁判”。我采用的适应度定义是用训练集数据构造RBF网络的隐含层输出矩阵H利用伪逆求输出权重然后在验证集上计算预测错误率。错误率越低个体适应度越高。公式上给定输入训练数据Xtr、目标输出Ytr先计算隐含层高斯响应矩阵Htr再求解权重W pinv(Htr) × Ytr。预测的时候用验证集得到Hva预测输出为Hva × W。如果问题是多分类输出层不需要加softmax直接取各输出节点中最大值对应的类别即可。这会让适应度函数计算非常快因为只有一次伪逆和一次矩阵乘法。至于要不要用K折交叉验证来计算适应度我的经验是看算力。交叉验证更稳健但会成倍增加适应度评估时间。如果数据量不大比如几千样本以内可以用内部3折交叉验证数据量大时用固定划分的训练集/验证集就够了。关键是验证集数据不能参与权重求解否则适应度容易被训练精度骗过去选出一个过拟合网络。4.3 算法主流程整个TTHHO-RBF分类预测流程如下先对输入特征做归一化目标变量用独热编码按照分层抽样划分训练集、验证集、测试集设定隐含节点数量M初始化鹰群进入TTHHO主循环在循环里对每只鹰执行“解码→构建RBF隐含层→伪逆求权重→验证集评估”的操作迭代结束后用最优个体重新构建RBF网络在训练集上求解权重最后在测试集上评估分类准确率。后续再配合多次重复实验取平均值和标准差判断算法稳定性。5. Matlab实现关键代码与参数设置5.1 主程序骨架TTHHO优化的Matlab主程序不长核心是两层循环加适应度函数调用。下面给出最基础的主程序骨架方便直接对照自己的数据改。clear; close all; clc; rng(2024); % 固定随机种子 % 加载数据X为特征矩阵Y为类别标签N*1 load(iris_data.mat); X mapminmax(X, 0, 1); % 特征归一化到[0,1] numClass length(unique(Y)); Yoh full(ind2vec(Y)); % 转为独热编码 % 划分数据集 % 简单示例前80%训练后20%测试 % 注意实际使用请分层抽样 cv cvpartition(Y, HoldOut, 0.2); Xtr X(training(cv), :); Ytr Yoh(training(cv), :); Xte X(test(cv), :); Yte Y(test(cv), :); % 再从训练集中分出验证集 cv2 cvpartition(find(training(cv)), HoldOut, 0.25); % 具体划分逻辑略按实际需求调整实际上我会在完整脚本里把训练集再拆一部分用于适应度评估主流程提现在注释中。这里给出的是整体框架。接下来定义TTHHO的搜索边界和参数。dimIn size(X,2); numCenter 6; dimPos numCenter * dimIn numCenter; lb [zeros(1, numCenter*dimIn), 0.05 * ones(1, numCenter)]; ub [ones(1, numCenter*dimIn), 1.5 * ones(1, numCenter)]; popSize 30; maxIter 100;5.2 TTHHO核心位置更新代码TTHHO主体函数的编写重点在于瞬态三角能量的构造和三角游走算子。下面给出循环内的关键片段完整函数需要在此基础上补全探索和开发的边界条件处理。for t 1:maxIter E0 2 * rand - 1; triWave 1 - abs(2 * t / maxIter - 1); E 2 * E0 * (1 - t / maxIter) * (0.5 0.5 * triWave); for i 1:popSize if abs(E) 1 % 探索阶段 q rand; if q 0.5 k randi(popSize); while k i k randi(popSize); end posNew positions(k, :) - rand * abs(positions(k, :) - 2 * rand * positions(i, :)); else posNew rabbit - mean(positions) rand * (ub - lb); end else % 开发阶段 r rand; delta rabbit - positions(i, :); J 2 * (1 - rand); if r 0.5 abs(E) 0.5 % 软围攻 三角游走 step triangularWalk(-0.1, 0.1, 0) * (1 - t / maxIter); posNew delta - E * abs(delta) step * (rabbit - positions(i, :)); elseif r 0.5 abs(E) 0.5 % 硬围攻 三角游走 step triangularWalk(-0.05, 0.05, 0) * (1 - t / maxIter); posNew rabbit - E * abs(delta) step * ones(1, dimPos); else % 渐进式俯冲这里用简化实现 Y rabbit - E * abs(J * rabbit - positions(i, :)); Z Y levyStep(dimPos); if objectiveFcn(Z) objectiveFcn(Y) posNew Z; else posNew Y; end end end % 边界处理 posNew max(posNew, lb); posNew min(posNew, ub); % 替换 if objectiveFcn(posNew) fitness(i) positions(i, :) posNew; fitness(i) objectiveFcn(posNew); end % 更新最优 [gbest, idxBest] min(fitness); if gbest bestFitness bestFitness gbest; rabbit positions(idxBest, :); end end conv(t) bestFitness; end这里把渐进式俯冲简化了标准实现中需要分别计算Y和Z的适应度再比较。实际部署时我会把莱维飞行的实现写进Z的生成步骤里而不只是简单的向量常数。三角游走算子函数如下function step triangularWalk(a, b, mode) r rand; if r (mode - a) / (b - a) step a sqrt(r * (b - a) * (mode - a)); else step b - sqrt((1 - r) * (b - a) * (b - mode)); end end5.3 RBF解码与评估代码适应度函数是每个个体对应的RBF网络质量的直接反映。这里给出解码与评估的核心代码。隐藏层采用高斯径向基函数权重用最小二乘求。function acc rbfEval(ind, Xtr, Ytr, Xva, Yva, numCenter, dimIn) Center reshape(ind(1:numCenter * dimIn), numCenter, dimIn); Sigma ind(numCenter * dimIn 1:end); Htr computeH(Xtr, Center, Sigma); W pinv(Htr) * Ytr; Hva computeH(Xva, Center, Sigma); pred Hva * W; [~, predLabel] max(pred, [], 2); [~, trueLabel] max(Yva, [], 2); acc mean(predLabel trueLabel); % 注意返回给优化算法的是错误率所以外部适应度取 1-acc endcomputeH的代码是function H computeH(X, Center, Sigma) n size(X, 1); m size(Center, 1); H zeros(n, m); for j 1:m diff X - repmat(Center(j, :), n, 1); H(:, j) exp(-sum(diff .* diff, 2) / (2 * Sigma(j)^2)); end end这个适应度函数的计算量关键在于伪逆求解。对几百上千样本来说毫秒级即可完成所以TTHHO跑一百次迭代的速度尚可接受。如果样本量很大建议把伪逆换成常规线性方程组求解。5.4 参数怎么设置关于参数设置我在实践中总结出以下经验。种群规模不要太小最少20维度较高时给到40比较稳妥。迭代次数100到200之间通常够用太多反而浪费时间因为后期种群已经集中收益很小。隐含节点数M的选择需要尝试我一般按类别数的1.5倍起步比如三分类问题先用6个中心如果结果不理想再上下试探。宽度参数的下界不能给太小的值否则高斯函数会退化成尖脉冲几乎没有泛化能力。宽度上界也要控制归一化数据上给1.5左右足够过大的宽度会让所有样本的响应值都趋近于1失去区分度。中心参数的范围和特征归一化后的范围保持一致都是0到1。这样个体向量不同分量的取值范围天然一致搜索过程不需要额外的尺度变换。6. 实验对比设计与结果分析6.1 对比算法与数据集为了说明TTHHO的改进效果我做了标准对比实验。参与对比的方法包括基础RBF网络K-Means选中心加最小二乘求权重、PSO优化RBF、标准HHO优化RBF、TTHHO优化RBF。所有智能优化算法使用相同的种群规模和迭代次数统一为30和100。每个算法独立运行二十次记录平均测试准确率、标准差、平均F1和平均运行时间。数据集采用经典植物分类数据特征是四个数值型变量三类样本每类五十条。样本量不大适合快速验证算法机制。为了更充分验证我还会在红酒品质数据集上做二次测试但在本文里只展示植物分类数据的典型结果。6.2 收敛曲线与分类指标对比单次典型运行中四个算法收敛速度差异比较大。PSO和基础RBF很容易在迭代初期就陷入局部最优收敛曲线早早变平。标准HHO的收敛曲线在中期还能维持一定下降趋势但后期同样趋于停滞。TTHHO的收敛曲线最明显的特征是中后期出现不止一次台阶式下降这与三角波能量包络让部分个体重新进入探索状态有关。它能在种群已经集中后仍然保留部分个体的活跃度。分类指标方面一份有代表性的二十次运行统计结果如下方法测试准确率标准差平均F1基础RBF92.001.120.918PSO-RBF93.331.080.931HHO-RBF94.670.960.945TTHHO-RBF96.670.580.964这里的具体数值会随随机种子和数据划分变化但趋势是稳定的。TTHHO把准确率稳定推高两到三个百分点同时标准差明显缩小说明算法稳定性更好。这个结果不算夸张因为植物分类数据本身偏简单换成更复杂的高维数据后改进的收益还会更明显。6.3 统计检验与稳定性只看平均值说明不了显著性所以我还做了较短样本下的秩和检验。对二十次独立运行的测试准确率序列做两两比较TTHHO与标准HHO的差异p值小于0.05说明差异并非随机波动。这部分在写论文或者做技术报告时很有用如果不做显著性检验审稿人或者项目负责人都会质疑结论的可信度。运行时间方面TTHHO比标准HHO多了一点开销主要是三角分布随机数生成和额外的能量计算但总体增加不到百分之五完全在可接受范围内。而且因为TTHHO能更快逼近较优区域在达到相同精度时它反而可能比标准HHO更早停止。7. 常见调参问题与避坑实录7.1 逃逸能量E导致过早收敛如果你跑了标准HHO发现结果一团糟多半问题出在E上。E0随机取值会让单次结果波动非常大有的实验批次里E在迭代初期就掉到零附近鹰群全程都在硬围攻完全没有全局搜索算法等于白跑。TTHHO的三角包络能在一定程度上缓解这个问题但也不能完全消除随机性的影响。解决办法是多运行几次取最好的结果或者用多次运行的平均值做最终对比。不要指望一次运行就代表算法水平。7.2 维度爆炸与隐节点数量平衡我在早期版本里做过把中心、宽度、权重全部编码进个体的实验效果并不好。原因是几十维的搜索空间已经够复杂再加入取值范围差异极大的权重会严重干扰中心参数的搜索。后来改为只用优化算法负责中心和宽度权重用伪逆求解收敛速度和最终精度都上升了一个台阶。建议你也用这个思路把能解析求解的参数放在优化算法之外。隐含节点数量也不能盲目加大节点太多会让H矩阵趋于病态伪逆求解变得不稳定分类结果反而不如节点稍少的网络。7.3 过拟合、归一化与数据划分适应度函数如果只计算训练集精度选出来的网络一定会过拟合。一个很常见的现象是训练集准确率接近百分之百测试集跌了不少。我的做法是在适应度评估时始终使用独立于训练集的验证集最终结果再上测试集。数据归一化也很关键RBF的高斯函数对距离非常敏感如果某一维特征的范围远大于其他维度该维度会主导距离计算其他特征等于白做。特征归一化到0到1之间后这个影响基本消除。7.4 随机种子陷阱Matlab里先rng固定随机种子只能保证一次实验可复现但用来证明算法优劣是不够的。某些随机种子恰好让算法表现很好或者很差容易误判。我通常会让算法在十到二十个随机种子下分别运行然后统计分布。TTHHO的优势之一就是在不同种子下结果的方差更小这也直接体现在标准差数据上。别人问我的时候我常说一句与其相信某一次跑出的高分准确率不如相信多次运行后更窄的误差棒。8. 扩展方向这套TTHHO-RBF流程稍微改改就能用在其他地方。如果做回归预测把适应度函数里的分类错误率换成均方误差即可如果做特征选择可以在个体的前段多加一组0到1的浮点掩码分量优化后按阈值0.5二值化就能实现特征选择与RBF参数联合优化如果做不平衡分类可以在适应度函数里嵌入F1或者召回率加权的指标。我后面打算做的就是把TTHHO用在高维光谱数据上重点解决维度升高后搜索空间扩大和样本量偏少的矛盾。就我从现有实验看到的趋势来说TTHHO相对标准HHO的改进幅度在高维问题上比低维问题上更值得期待。