NRBO-FMD:基于牛顿拉夫逊优化的特征模态分解参数自动寻优方案
2026/8/29 3:07:18 网站建设 项目流程

简介:在滚动轴承与齿轮箱等旋转机械的振动信号处理中,特征模态分解(FMD)是一种能有效提取非平稳冲击成分的新兴时域分解方法。然而FMD的分解效果高度依赖滤波器长度L与模态数K两个关键参数,传统人工试凑或网格搜索不仅效率低,且难以保证全局最优。牛顿拉夫逊优化算法(NRBO)通过结合经典梯度搜索与种群迭代,具有收敛快、参数少、局部搜索能力强的优势,将NRBO与FMD结合可实现分解参数的自动寻优。以包络熵最小化和峭度最大化构建综合适应度函数,NRBO-FMD能够自适应匹配最优L与K值,显著提升故障特征频率的提取精度。该方案在仿真信号与真实轴承外圈故障数据上均验证了优于PSO、GA的收敛速度和稳定性,为旋转机械智能故障诊断提供了高效可靠的工程化工具。

1. FMD算法是个好东西,但卡在两个关键参数上

做机械故障诊断、尤其是滚动轴承和齿轮箱振动信号分析的朋友,这几年对特征模态分解(Feature Mode Decomposition,FMD)应该不陌生。相比EMD、EEMD、VMD这些老牌分解算法,FMD的思路完全不一样——它不靠递归筛选,也不靠模态混叠的惩罚约束,而是通过设计一组自适应滤波器组,把信号按频率特征切分成若干个“特征模态”,再通过相关系数筛选出和故障特征频率最相关的分量。这个思路在处理非平稳、强噪声信号时确实能打,尤其在轴承外圈、内圈故障特征提取上,效果往往比VMD更干净。

但FMD有个很现实的问题:它不是一个“傻瓜式”算法,分解效果对两个参数极其敏感——滤波器长度L和模态数K。L取得不合适,分解出来的模态要么过度平滑丢掉冲击成分,要么保留太多噪声;K取少了,故障特征混在某个模态里出不来;K取多了,就会把同一个物理成分劈成好几段。手动去试这组参数,运气好试个几十次能出一个勉强能看的结果,运气不好,同一组参数换个数据集就得重新调一遍。

业内普遍做法是靠经验网格搜索,或者用遗传算法、粒子群这类群体智能算法去自动寻优。但遗传算法收敛慢,粒子群容易陷局部最优,而且它们的收敛精度和迭代速度在长时间振动信号上都不够理想。这也是我一开始尝试把FMD用在多个不同工况数据集上的痛点——每次换数据都得重调参数,还不能保证是全局最优。

后面查文献时看到了Newton-Raphson-Based Optimizer(NRBO)这个算法,思路很有意思。它把经典牛顿迭代法的梯度搜索思想和群体位置更新策略结合到一起,收敛速度快,局部开发能力强,而且参数少、实现简单。我就想着把NRBO作为FMD的参数寻优引擎,做一个自动化的NRBO-FMD工具,用Matlab完整实现,替代手调参数的痛苦流程。这篇文章把我整个做出来的过程、原理、代码结构和踩坑记录都拆开讲清楚,希望能帮到同样被FMD参数问题折磨的同行。

2. NRBO优化器为什么适合做FMD的参数寻优

2.1 先弄明白FMD到底卡在哪个环节

FMD早期的雏形来自频带筛选思想。简单说,它先把信号经过一系列带通滤波器,得到一组新的“字典”,然后通过迭代优化让字典里的每个模态尽可能纯净。它不像VMD那样在频域里设定中心频率和带宽惩罚,而是直接在时域里通过滤波器的系数自适应演化,所以对瞬态冲击的保真度比VMD好。

这里面L和K的作用分别是:

  • L:滤波器长度。它决定了滤波器频率分辨率和时域冲击响应的长度。L太小,滤波器频带边缘的泄漏会让模态之间混淆;L太大,计算量陡增且会出现边缘效应,同时滤波器对瞬态成分的响应会变得迟钝。
  • K:分解模态数量。它决定了滤波器的频带切分数目。K = 2时可能把轴承外圈故障的固有频带和噪声混在一起;K = 6时可能把一个完整的故障脉冲序列拆到两个模态里。

在实际信号中,这两个参数并不是独立的。L和K共同决定了滤波器组的频率切割方式。稍微画一下频率响应就能看出来,两组不同的(L, K)也可能导致相似但未必相同的分解结果,这就造成了参数寻优的非线性目标面,手动整定几乎不可能高效完成。

2.2 NRBO的迭代机制拆解

NRBO的核心是把牛顿-拉夫逊迭代中“利用导数信息逼近零点”的思想搬到种群寻优里。每个个体代表一组候选参数,个体的位置更新不仅参考自身历史最优和种群全局最优,还通过一种类似“牛顿方向”的修正项来加速收敛。

用大白话说,它不像粒子群那样纯粹靠社会认知和个人认知做加权移动,而是每次位移都会估计一下当前位置的“梯度走向”,方向对了就大步走,方向不对就修正角度。从收敛曲线上看,NRBO的适应度下降速度通常比PSO快一个量级左右,稳定性也好于遗传算法。

NRBO需要调整的算子数量少,仅有种群大小N和最大迭代次数T两个主要人为设定参数。这对于工程场景很友好,因为用户不想在“优化器”内部还需要去调一堆参数。

2.3 和PSO、GA在FMD寻优上的对比

我在做NRBO-FMD过程中,顺手用同目标函数测过粒子群和遗传算法做过的FMD参数寻优,结果有参考价值:

优化器平均收敛代数最优适应度稳定性(多次运行)
GA约120代一般一般,依赖交叉变异概率
PSO约85代较好容易早熟,参数敏感
NRBO约35代优于前两者稳定,多次结果差异小

需要说明的是,这个对比不是严谨的基准测试,只是在同一数据集、同一适应度函数、相近计算代价下的实测感觉。但NRBO确实在收敛速度和结果质量上给了我惊喜。它的种群演化过程中引入了局部逃逸机制,每次迭代会放弃一部分适应度差的个体重新初始化,这在多峰目标面上有效避免了早熟——恰恰是PSO在FMD寻优中最容易犯的毛病。

3. 搭建NRBO-FMD的完整过程:目标函数设计、参数绑定与代码实现

3.1 目标函数怎么定:包络熵和峭度联合评判

NRBO要寻优,必须先定义“什么样的分解结果是好的”。FMD的分解目标是要从复杂振动信号中提取出包含故障冲击的分量,所以评判指标要能反映“冲击性”和“稀疏性”。

我第一个想到的是包络熵。包络熵本质上是包络谱信息熵,信号经过Hilbert解调后的包络越“尖锐”,说明冲击成分越集中,包络熵越小;包络越杂乱无章,包络熵越大。所以包络熵最小化几乎天然适配FMD的分解目标。

但只用包络熵有一个坑:如果某次分解把信号彻底过平滑,包络熵也会变小,而真实的故障冲击也被抹平了,这个时候会出现“无挑战的假最优”。所以我加了一个峭度约束:在包络熵基础上,用模态的时域峭度作为评判维度的补充。峭度对早期故障冲击非常敏感,健康信号的峭度接近3,出现冲击性故障后峭度会显著增加。

最终适应度函数设计思路是:NRBO在每次迭代中生成一组候选(L, K),FMD对信号进行一次完整分解,得到K个模态后率先计算每个模态的包络熵和峭度,然后加权综合形成单个适应度值。权重上我偏向包络熵多一点,取0.7和0.3,原因后面会细说。

这样做有个好处:NRBO的内部逻辑只需要关心“一组参数对应的分解结果得分如何”,完全不用干预FMD的内部运行,耦合度低,模块可以单独替换。

3.2 参数绑定方式与边界设定

NRBO的每个个体在算法里是一个二维向量,分别对应L和K。由于L是滤波器长度、K是模态数,两者都有明确的物理含义,所以必须做整数化处理。我在代码中直接把位置向量向下取整,并且把边界做了硬约束:

  • L的范围:一般取[30, 500],覆盖常见的滤波器长度需求。太短没有频带选择性,太长则计算量飙升。
  • K的范围:取[3, 12]。正常轴承故障信号分解到3到12个模态基本够用。取太大会把一个物理分量劈碎,太小则噪声混叠明显。

这里额外注意,L的取值应该尽量是偶数。因为FMD内部通常会设计为偶数抽头滤波器来保证线性相位,奇数L时滤波器性能不稳定,所以我在取整之后做了奇偶校正,奇数就加1变成偶数。

3.3 主程序框架和核心代码注释

整个Matlab工程分为四层:

  1. 主入口脚本NRBO_FMD_main.m:负责加载数据、设置NRBO参数、调用优化器、输出最优参数和最终分解结果。
  2. NRBO优化器函数NRBO.m:实现牛顿拉夫逊优化算法的核心种群迭代。
  3. 适应度函数FMD_fitness.m:将候选参数传给FMD并计算包络熵与峭度加权值。
  4. FMD分解器FMD.m:完成具体分解,输出模态矩阵和中心频率。

NRBO优化器的核心迭代部分,我摘几段关键逻辑出来说明:

% NRBO核心迭代——位置更新与牛顿修正方向 for iter = 1:T for i = 1:N % 计算当前个体的牛顿方向修正项 Delta = rand(1, dim) .* (X_best - X(i, :)); % 位置更新,rho和theta为NRBO自适应参数 X_new = X(i, :) - rho * (X(i, :) - X_best) + ... theta * Delta + ... (1 - theta) * randn(1, dim) .* (X_upper - X_lower); % 边界修正与适应度评估 X_new = bound_check(X_new, X_upper, X_lower); fit_new = fitness_func(X_new, data); % 贪婪选择 if fit_new < fit(i) X(i, :) = X_new; fit(i) = fit_new; end end end

这个更新式比普通PSO多了两处关键设计:一是Delta项实际上是在估计局部梯度方向,二是theta参数在迭代前期和后期动态变化,前期大、后期小,保证先探索后开发。这种设计逻辑复用了牛顿法中“根据导数变化不断逼近零点”的思想,这也是它名字里“牛顿拉夫逊”的由来。

适应度函数的关键代码如下:

function score = FMD_fitness(params, data) L = round(params(1)); % 滤波器长度 K = round(params(2)); % 模态个数 if mod(L, 2) == 1 L = L + 1; % 保证偶数 end % 执行FMD分解 modes = FMD(data, L, K); % 计算所有模态中包络熵最小值 env_entropy_min = 1e10; kurtosis_max = 0; for k = 1:K env = abs(hilbert(modes(k, :))); % 包络熵计算 p = env / sum(env); entropy = -sum(p .* log(p + eps)); if entropy < env_entropy_min env_entropy_min = entropy; end temp_kurt = kurtosis(modes(k, :)); if temp_kurt > kurtosis_max kurtosis_max = temp_kurt; end end % 加权组合,包络熵越小越好,峭度越大越好 score = 0.7 * env_entropy_min - 0.3 * kurtosis_max; end

包里还额外写了并行计算支持——如果Matlab版本支持Parallel Computing Toolbox,可以在NRBO主循环里把for i = 1:N改成parfor i = 1:N。但注意,第一次跑并行池要预热,小数据量下并行可能反而更慢,建议数据长度超过20万点再用。

3.4 数据预处理:做好这几步,寻优结果差不了

在把原始信号喂给NRBO-FMD之前,预处理步骤直接影响到后面各环节的执行效果。我的流程是:

  1. 去均值、去趋势项:计算data = data - mean(data),消除直流分量带来的低频干扰。
  2. 带通预滤波:用500Hz到5000Hz的带通滤波先滤掉大部分工频干扰和高频噪声。注意,这步不是为了替代FMD,而是为了降低FMD在寻优过程中的计算负担。
  3. 降采样(若采样率过高):如果采样率是100kHz以上,FMD每次迭代做滤波的计算量会非常大,建议降采样到20kHz左右,但不影响分析频带的前提下进行。
  4. 分段评估:如果数据很长,比如超过100万点,建议先截取一段包含故障冲击的中段数据做参数寻优,再用最优参数跑全段分解。这个技巧能大幅缩短寻优时间。

4. 仿真信号与真实轴承数据实测:到底有没有效果

4.1 构造一个已知故障特征的仿真信号来验证

为了验证NRBO-FMD的分解能力,我先构造了一个模拟轴承外圈故障信号。故障特征频率设为97.6Hz,共振频带中心在2600Hz附近,采样率20kHz,时长0.5秒,叠加宽带噪声和两个工频干扰分量。

理论上,一个正常的分解结果应该能在某个模态中清晰提取出97.6Hz及其倍频成分。我分别用了三种方式跑:

  • 方式一:固定K=5、L=150,不做优化,直接FMD分解。
  • 方式二:PSO-FMD寻优。
  • 方式三:NRBO-FMD寻优。

方式一分解后,故障特征频率在包络谱里有微弱谱线,但伴有若干个不明干扰峰;方式二能找到较优参数,但运行了大约90代收敛;方式三在35代左右就收敛,且分解出的最优模态的包络谱中97.6Hz峰值最突出,倍频序列也最清楚。

这个仿真结论和预期吻合:NRBO确实能让FMD的性能达到一个更稳定且更优的“工作点”。

4.2 真实轴承故障数据上的表现:一个外圈故障案例

仿真信号验证完毕,我又拿公开的轴承故障数据集做了测试。用的是某实验台驱动端轴承外圈故障数据,采样率12kHz,转速约1750rpm,故障特征频率理论值约105.1Hz。

还是先跑NRBO-FMD寻优,参数范围保持L在[30, 500]、K在[3, 12],其他设置不变。最终NRBO给出的最优参数是L=286、K=7,适应度收敛过程很平稳,没有明显震荡。

FMD按这个参数分解后,在第二个模态的包络谱中,105.1Hz处有一条非常明显的谱线,二倍频、三倍频也连续可见。相比之下,固定参数L=100、K=5时,分解出的模态在105.1Hz处虽然也有峰,但旁边出现了多个不知来源的旁瓣,无法直接判定故障。这就体现出了优化参数带来的实际价值。

值得一提的是,NRBO找到的L=286和K=7这个组合,如果靠手动去网格搜索,以步长L=10、K=1来算,需要搜五六十组参数,每组FMD分解都要几秒钟时间,总耗时至少五分钟以上。NRBO在约30代收敛、每代种群10个个体,实际调用FMD约300次,耗时约40秒,性价比显而易见。

4.3 包络熵和峭度两个指标的实际权重考虑

我上面把适应度函数设定为0.7倍的包络熵最小值减去0.3倍的峭度最大值,为什么这样加权,实际操作中我也试过其他比例。如果你把峭度权重调得太高(比如0.5),优化器会倾向于选择峭度极高但物理意义不清晰的模态——有时候分解结果是白噪声中的单个瞬态脉冲,峭度可以高达几十,但没有任何工程诊断意义。包络熵权重太高,又容易出现过度平滑导致冲击丢失。0.7/0.3这个比例在我测试的大多数数据集上都能给出稳定的故障诊断表现,这也是我最终在源码包里保留这个默认值的原因。

如果你在自用数据上发现效果不佳,建议优先把权重比例调整为0.6/0.4或者0.8/0.2来对比,不需要一上来就改造算法结构。

5. 源码使用指南与六个容易踩的坑

5.1 目录结构和运行方式

压缩包里包含的核心文件如下:

NRBO_FMD_main.m % 主运行脚本 NRBO.m % NRBO优化器实现 FMD.m % 特征模态分解实现 FMD_fitness.m % 适应度函数 test_data.mat % 示例数据(仿真轴承外圈故障信号) README.md % 使用说明

拿到源码后,直接用Matlab R2019b及以上版本打开NRBO_FMD_main.m,修改数据加载路径或直接用自带的test_data.mat运行即可。NRBO的种群规模N默认设为10,迭代次数T默认设为50,对大多数数据完全够用。如果你想追求更高精度,可以增大N到15,但运行时间会增加约50%;如果数据很长,建议先降采样或者截段,再跑寻优。

5.2 六个容易踩的坑

第一,FMD内部的滤波器设计函数对不同Matlab版本兼容性有差异。R2020a及以下版本建议把bandpass函数替换成designfilt方式实现,否则可能报错。R2021b以上版本则没有这个问题。

第二,迭代中偶尔会出现L取到极小值(比如30以下)的情况。L太短会导致滤波器选择性过差,优化器虽然给了边界约束,但边界的下界太小时种群容易往边界上“撞”。推荐把L下界设到50以上会更稳。

第三,FMD分解结果的第一行或最后一行模态经常是残余分量,包含直流偏移和趋势项。计算包络熵和峭度时最好跳过这个模态,或者先对每个模态做去均值处理,否则适应度会被残余分量带偏。

第四,大规模数据下FMD的每次分解都会涉及多次滤波运算,如果种群数N=10、迭代T=50,总FMD调用约500次,一次跑完可能需要两三分钟。其实完全没必要等它跑满。按我的经验,看到适应度连续5代没有明显下降,就可以提前终止迭代了,可以在主循环里加一个早停判断。

第五,NRBO算法对初值有一定敏感性。如果在你的数据上发现收敛到很差的局部最优,可以试着改随机数种子重新跑一次,或者把种群数稍微调大。由于算法内部带局部逃逸机制,实际多次运行后的差异不大,但还是建议跑两次验证一下结果是否一致。

第六,也是最重要的:参数寻优结果要结合工程判断。NRBO给出的最优参数是基于适应度函数定义的“最优”,但适应度函数是人为设计的,它不等于“轴承故障诊断准确率最优”。用分解结果做包络谱分析时,还是要人工看一下特征频率处是否存在明显峰值。工具是用来辅助判断的,不能全盘替代人的经验。

5.3 扩展思路:如何把NRBO-FMD推广到其他场景

NRBO-FMD这个框架不仅限于轴承故障。你只需要改一下适应度函数,就能把它用到很多其他场景:

  • 齿轮箱断齿故障:把目标函数换成边频带能量比,衡量啮合频率两侧边带成分的集中度。
  • 往复压缩机气阀故障:把目标函数换成时域峭度和脉冲因子加权。
  • 电能质量分析:把模态提取后计算谐波畸变率,寻优目标改为畸变率最大最小化。

核心思路是:FMD只负责分解,NRBO只负责寻优,中间用“适应度函数”这座桥来连接。桥怎么设计,完全取决于你想让分解结果服务于什么目标。这个解耦结构也是我把整个工程做成模块化的原因,方便你在自己的研究里替换不同组件。

6. 运行加速和后续改进建议

在实际跑大数据量信号的时候,NRBO-FMD的瓶颈很明确——FMD内部滤波器的计算量。针对这个瓶颈,我试过几个有效的加速手段。

首先是GPU加速。Matlab的gpuArray可以加速部分滤波运算,但不是所有版本的FMD实现都能直接支持。如果你的Matlab版本较新且算法里用的是filterconv这些内置函数,改成gpuArray后能获得约2到4倍加速。不过需要注意,在GPU和CPU之间频繁拷贝数据会抵消加速效果,需要保证数据已经在GPU上才划算。

其次是降采样。很多振动分析场合采样率设得很高,但实际上轴承故障信息集中在几千赫兹以内。根据采样定理降低采样率可以显著缩短每次FMD分解的时间。建议先用1/2或1/4降采样观察包络谱,确认特征频率没有被滤掉后再对全数据做正式分析。

第三是设置合理的迭代次数。我发现N=10、T=30是很多场景下的最佳折中,跑完大约30秒到1分钟。想更快就N=8、T=20,准确度损失通常在可接受范围内。事实上,由于NRBO的局部逃逸机制,迭代后期适应度下降幅度已经很小,强行跑满50次纯属浪费算力。

最后再给一个我经常使用的技巧:在跑NRBO-FMD之前,先用快速谱峭度(Fast Kurtogram)或者自相关谱粗筛一下信号中存在故障冲击的频带。这个预分析能帮助判断K的范围。如果共振频带相对集中,K设小一点(4到6)就够;如果故障出现在多个频带,K就需要大一些(8到12)。这看起来是增加了额外步骤,实际上减少了NRBO无头绪搜索的时间,整体反而更省时间。

NRBO-FMD整体做下来,我最大的感受是:优化算法的价值不在于炫技,而是让信号处理工具能更可靠地落地到工程场景。FMD本身是个好算法,但参数敏感性让它难以被直接上手使用。NRBO的出现把最后这块短板补上了,参数自适应、结果可复现、过程可视化,这才是一个工程工具该有的样子。如果你正在为FMD的参数整定头疼,不妨把这个框架试起来。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询