news 2026/10/21 15:46:44

EEMD-MPE-KPCA-BILSTM:振动信号智能故障诊断全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
EEMD-MPE-KPCA-BILSTM:振动信号智能故障诊断全流程解析

做设备故障诊断这些年,我养成了一个习惯:拿到一组振动信号,先别急着上模型,而是先问自己三件事——信号里有哪些故障成分?用什么特征能把这些成分区分开?分类器能不能把特征里的时序关系吃透。这次要复盘的正是一条完整链路:EEMD–MPE–KPCA–BILSTM故障识别方案。这套流程适合手里有振动、声发射等非平稳信号,想做“分解—提特征—降维—识别”全流程的人,也适合刚接触智能故障诊断、想搞清楚模块为什么这样排的同学。全文我会按我实际跑的思路讲,参数、坑、排查路径都放到一起说,少讲空洞的套话。

1. 为什么要把EEMD、MPE、KPCA、BILSTM串成一条线

1.1 信号分解—特征提取—降维—识别的“生产线”逻辑

我最早接触故障诊断时也天真地想过:直接把原始振动波形扔给LSTM或者CNN不就行了?后来实验数据打脸了。工业现场的振动信号几乎都是非平稳、非线性的,里面除了故障冲击成分,还有齿轮啮合频率、转频及其谐波、随机噪声、环境干扰。把这样一段“大杂烩”直接送入分类器,模型很难自动分清哪些成分来自故障,哪些来自正常工况。

EEMD、MPE、KPCA、BILSTM这条链,本质上是一条特征生产线:

  • EEMD是原材料清洗和分拣。它把混叠在一起的振动信号自适应地分解成若干固有模态分量(IMF),相当于把一锅乱炖分成了几盘菜。
  • MPE是从每盘菜里提取“味道指标”。多尺度排列熵能在不同时间尺度下量化信号的复杂度和规律性,故障导致的冲击、调制,会在熵值上留下明显痕迹。
  • KPCA是质检筛选。提取后的特征往往维数高、冗余大,而且是非线性相关的,用核主成分分析在核空间里降维去冗余,让模型把注意力放在真正区分故障的少数几个维度上。
  • BILSTM是最后的装配判断。降维后的特征序列仍然有先后关系和上下文依赖,双向长短时记忆网络可以从前后两个方向捕捉这些依赖,输出故障类别。

这条线不是我凭空拼的,而是对应了诊断领域的经典共识:先做信号自适应分解,再在分量域构造统计特征,最后用“降维+分类模型”完成模式识别。每个环节都在解决前一个环节留下的问题,少一个,后面的模型要么输入太脏,要么特征太乱,要么维度太高。

1.2 端到端深度学习为什么还没完全替代这条线

我知道现在很流行端到端,拿着原始信号直接训一个深度网络,好像前面的信号处理都不需要了。但我的实测经验是:端到端方案有两个前提,一是样本量要足够大,二是数据分布要相对稳定。工业场景里故障样本本来就稀缺,尤其是早期故障、复合故障,想拿到几千条高质量标注样本很难。这时候直接训练大网络,很容易过拟合。

而EEMD–MPE–KPCA这套前置处理,本质上是把人类对故障机理的先验知识注入到了特征里。就算样本量只有几百,特征分布也相对清晰,分类器不需要自己从原始波形里“硬学”特征。另外,分步处理还有可解释性的好处。模型分错了,我可以去看是分解环节出了问题,还是特征本身不可分,而不是面对一个黑盒网络无从下手。

所以我倾向于把这条链理解成“半自动特征工程+轻量级时序分类器”的组合。它不一定在公开大数据集上比端到端刷分高,但在真实小样本、强噪声场景下,稳定性和可排查性都要好得多。

2. EEMD分解:先解决模态混叠,再谈特征质量

2.1 EMD自适应分解的核心逻辑

EEMD是在EMD(经验模态分解)基础上发展来的,所以先得说清楚EMD在干什么。EMD不需要预设基函数,它从信号本身出发,通过不断找局部极值点、拟合上包络和下包络、减去包络均值,把信号一层层剥离。剥离出来的每个IMF要满足两个条件:一是极值点数和过零点数相差不超过1,二是上下包络的均值在每一点上接近零。

这么做的好处是“自适应”。转速变化、冲击载荷导致的非平稳成分,EMD也能按信号内在的时间尺度进行分离。比如一段轴承外圈故障信号,EMD通常会把高频冲击成分分到靠前的IMF,把转频和调制成分分到靠后的IMF,噪声和趋势项则落在最后。

但EMD有个非常出名的问题——模态混叠。简单说,同一个IMF里可能同时含有差异很大的时间尺度成分,或者同一个尺度成分被拆到两个IMF里。这会导致后面提取特征时,分量边界不干净,特征里混着噪声和无关成分。我第一版实验直接用的EMD,结果发现某些样本的IMF2和IMF3形态几乎一样,MPE特征两两高度相关,分类器学习得很痛苦。

2.2 集合平均如何抑制模态混叠

EEMD的核心思路叫“噪声辅助分析”。它把白噪声加到原始信号上,然后对加噪后的信号做EMD,反复做多次,最后把所有结果对应位置求平均。白噪声的作用是改变信号极值点的分布,迫使不同时间尺度的成分在每一次分解中自动归位,多次平均后白噪声彼此抵消,真实分量自然突显出来。

我用一个生活化的类比来理解它:EMD就像让一个不熟悉的裁判看体操动作,他很容易把节奏相近的动作看混;EEMD相当于让同一裁判反复看多遍,每次给画面加一点随机的“干扰噪点”,最后取平均,他反而能分清哪些动作是真实的、哪些是偶然看错的。实测下来,加了集合平均之后,分解结果的IMF数量更稳定,同一个故障类型下,各个样本分解出的分量对齐程度明显提高。

2.3 EEMD关键参数的经验取值

EEMD有两个核心参数:噪声幅值和集成次数。噪声幅值通常表示为原始信号标准差的倍数,我常用的范围是0.1到0.4倍,默认先取0.2。如果噪声幅值太小,起不到调节极值点分布的作用,模态混叠压制不住;如果太大,噪声反过来会污染低频分量,分解结果出现大量虚假IMF。

集成次数我一般取100到200次,少于50次时平均效果不稳定,多于300次时计算时间暴涨,但对结果提升很有限。这里有个时间成本权衡:数据量大的话,200次集成可能就要跑很久,建议先拿两三条样本试分解,观察IMF数量稳定了再批量跑。

还要提一下端点效应。EMD拟合包络时,信号两端没有极值点,包络容易发散,导致两端出现“飞翼”,这在边界处尤其麻烦。我会在分解前对信号做镜像延拓,或者截取信号时故意留一点冗余,等分解完丢掉两端人机边界相关部分。这块细节很多人不提,但实际影响MPE特征稳定性,值得重视。

3. MPE特征提取:用多尺度排列熵把复杂度变成数字

3.1 排列熵:一种快而稳的复杂度统计量

分解得到IMF后,下一步是量化每个分量的特征。传统做法是提取时域统计值(均值、方差、峰峰值)和频域特征(重心频率、谱峰),但这些特征对故障状态变化的敏感性有限。我后来换成排列熵,原因是它思路简单、计算极快,而且对信号中的微弱变化更敏感。

排列熵的基本思想是:把一个序列按 m 个点分组,看相邻 m 个点的相对大小关系,形成一种“排序模式”。比如某三个点的关系是“中间点最小、后一个点最大”,这就是一种模式。统计所有模式出现的概率,代入信息熵公式,得到排列熵。如果序列完全随机,所有排序模式出现概率接近,熵值高;如果信号有固定节奏,某些模式反复出现,熵值就低。故障引起的冲击和调制会改变信号的规律性,熵值因此会变化,这正是我们可以用做判别的依据。

3.2 多尺度化给故障特征配了一副“广角镜”

单独计算一层排列熵,只能反映一种时间尺度下的复杂度。但故障信号常常是“局部冲击+长周期调制”混合体,如果只盯一个尺度,很容易漏信息。MPE的做法是先把原始序列做粗粒化:窗口长度为 s 时,把每 s 个连续点取平均,得到一条长度缩短的新序列,再在这个新序列上计算排列熵。s 就是尺度因子。

举个例子,s=1 时,MPE就等于普通排列熵,反映的是最细粒度的时间结构;s=5 时,相当于把信号每5个点压缩成一个低频值,看到的是更粗的时间结构。正常轴承和故障轴承的差异,往往不是只在某一尺度出现,而是在多个尺度上都有分布。我画过不同状态下MPE随尺度变化的曲线,正常状态熵值整体偏高,故障状态在某些尺度上会有明显凹陷,这条曲线本身就非常像一幅“指纹图”。

3.3 MPE参数怎么选,依据是什么

MPE有三个常见参数:嵌入维数 m、时间延迟 tau、尺度因子 s。我在实验中使用 m=5、tau=1、s=10,这组参数在我测过的数据集上表现稳定,但不同场景需要微调。

  • 嵌入维数 m:一般取4到7。m太小,排序模式太少,熵值区分度不够;m太大,排列模式数 m! 爆炸,需要的序列长度也急剧增加。比如 m=6 时模式数是720,如果信号本身很短,统计就不充分。顺序上我总是先看样本点数,再决定m。
  • 时间延迟 tau:通常取1到6。tau=1 最常用,因为它保留相邻点间的局部关系;tau取大值会跳过局部细节,对高频冲击信息不够敏感。有文献说tau取1到3之间比较稳妥。
  • 尺度因子 s:我习惯取10,数据集大时取12到16也可以。s太小的多尺度信息不充分,s太大时粗粒化后序列过短,熵估计方差变大。

还有一个容易被忽视的点:EEMD分解出的IMF个数是不固定的,不同样本可能得到不同数量的IMF。为了让每个样本的特征长度一致,我通常只保留前 k 个与故障相关的分量,比如前6个或前8个,然后把每个IMF的MPE按尺度拼接成一个向量。如果某样本没有分出足够多的IMF,就补零或舍弃末尾分量。这样每个样本最终都得到一个维度为IMF数 × 尺度数的特征矩阵。

4. KPCA核降维:在核空间里给高维特征瘦身

4.1 高维特征带来的麻烦

假设我们保留8个IMF,每个IMF计算10个尺度的MPE,那么单个样本就有80维特征。如果再叠加时域统计、谱特征,上百维很常见。高维特征直接送进BILSTM有个严重问题:维数高,训练参数多,样本稍微少一点就过拟合;特征之间高度相关,模型拿到的有效信息冗余,训练速度也慢。

PCA这种线性降维解决不了MPE特征的非线性耦合。MPE在不同尺度和不同IMF之间,关系往往不是线性的。比如相同故障状态下,IMF3的尺度5熵值与IMF5的尺度8熵值可能呈复杂的非线性联动。这时线性投影会把大量重要结构“压扁”丢掉,所以要用KPCA。

KPCA的思路是先通过核函数把原始特征映射到高维核空间,在核空间里做线性主成分分析。因为核空间里的线性关系,对应着原始空间里的某种非线性关系,所以KPCA能捕捉到更多非线性结构,相当于“先升维,再降维”,听着矛盾,实际上是让非线性结构在更高维空间里展平,再挑主要方向。

4.2 核函数选择和累计贡献率

我最常用的是RBF核,也就是高斯核,因为它覆盖的非线性范围广,参数只有一个gamma。gamma选不好影响蛮大:gamma太小,每个样本的影响范围太大,降维结果趋近于线性PCA;gamma太大,样本之间几乎互不影响,主成分会被个别样本主导。我通常在0.001到0.1这个区间做粗略网格搜索,默认从0.01开始试。

降维后保留多少维,一般是看累计方差贡献率。我习惯先设90%,然后试85%、95%两组对比一下。注意一个细节:贡献率阈值并不是越高越好。保留太多主成分,KPCA等于没降维;保留太少,又会把类别区分度高的细节丢掉。我通常会投影到二维三维空间,用散点图看一眼不同故障类别的聚类情况,如果类别混成一片,就调低贡献率或换核函数参数。

4.3 KPCA前后的数据标准化不能省

KPCA对特征尺度非常敏感,因为核函数计算的是样本间距离,而不同IMF的熵值范围可能差异很大。我在把特征矩阵送入KPCA前,会先对每一个特征维度做z-score标准化,公式就是(x - mean) / std。这里必须强调:mean和std要用训练集计算,然后同样应用到验证集和测试集,不能每个数据集单独算,否则会造成信息泄漏,评估结果虚高。

KPCA降维之后的特征向量,就是BILSTM每个时间步的输入特征。在具体实现上,我习惯把每个样本的“尺度”当作时间步方向,每个时间步上的特征就是经过KPCA压缩后的低维特征向量。也可以把IMF当作序列方向,这两种组织方式我都试过,前者在我的数据集上更稳定,供参考。

5. BILSTM分类模型:双向时序结构如何吃下这些特征

5.1 从LSTM到双向LSTM,为什么有必要

LSTM通过门控机制解决了长序列梯度消失问题,但标准的LSTM只按时间顺序正向处理,这等于只看“过去”。故障特征里有很多信息其实是前后呼应的。比如轴承内圈故障产生的冲击,会伴随一段衰减振荡,冲击本身和后续的衰减是一个完整“事件”;只看着前面,模型很难知道接下来会发生什么。双向LSTM的做法是把序列从正向和反向各跑一遍,再把两个方向的隐状态拼在一起,这样每个时间步的输出都同时包含“前文”和“后文”信息。

我最初也试过普通LSTM,准确率大概低3到5个百分点,尤其在滚动体和保持架这类故障特征较弱的类别上,双向结构的优势更明显。原因我想是弱故障特征在时序上跨度更长,正向建模容易受干扰,反向能“从头到尾再校验一遍”。

5.2 网络结构与超参数设定

我用的网络结构不算复杂:

  • 输入层:时间步数为尺度数,特征维度为KPCA降维后的维数;
  • 第一层:BILSTM,隐藏单元64,返回序列;
  • Dropout:0.3;
  • 第二层:BILSTM,隐藏单元32,可返回最后一步或全序列;
  • Dropout:0.3;
  • 全连接层:32个神经元,ReLU激活;
  • 输出层:Softmax,节点数等于故障类别数。

这个规模在小样本场景下够用了。隐藏单元不是越多越好,我曾把第一层加到128,准确率没有明显提升,训练时间却翻倍,还更容易过拟合。优化器用Adam,初始学习率0.001,配合ReduceLROnPlateau,在验证损失连续5轮不下降时把学习率降为原来的0.5。Batch size我固定为32,如果样本量很小,16会更稳。

这里还要多说一句ReduceLROnPlateau。很多人训练RNN习惯用固定学习率,结果损失曲线来回震荡。我的经验是动态学习率在这个任务里几乎必用,因为不同故障类别的学习难度差异大,前期要快,后期要细。

5.3 过拟合监控与模型保存

小样本训练BILSTM,最怕的就是训练损失一路下降,验证损失过了一个点之后反弹。我的监控办法是每轮结束都记录训练损失和验证损失,并在验证损失最低点保存模型权重。测试时加载的是验证集上表现最好的那版权重,而不是最后一轮权重。这个细节能直接救回不少准确率。

另外,虽然前面已经做了KPCA降维,BILSTM本身对输入尺度也敏感。我会在送入网络前再做一次标准化,或者干脆在模型里加一个BatchNormalization层。两种方式效果差不多,我用的是后者,因为它把标准化融入到训练过程,不用单列预处理步骤。

6. 实验跑通后的三个坑与我的排查思路

6.1 数据切分时的样本泄漏问题

我第一版实验的准确率奇高,接近99%,当时还挺高兴。后来仔细一查,问题出在数据切分上。我用滑窗从连续振动信号里截样本时,没有把同一时间段的数据严格分到同一集合里,导致训练集和测试集里出现了大量重叠片段,模型等于提前见过答案。

正确做法是:按时间段划分,前60%的连续信号用来切训练样本,中间20%切验证样本,最后20%切测试样本。如果一台设备有多次启停记录,应按独立记录文件划分,而不是简单随机打乱样本。这一点在诊断类任务里可以说是头号隐性错误,建议每位读者都自查一遍。

6.2 某两类故障总混淆时,先回去看特征图

我的数据集里,内圈故障和外圈故障最初总是互相误判。我一开始调BILSTM结构,没效果。后来我把两个类别的MPE特征画到同一张图上,发现两者的熵值曲线形状几乎重叠,只在个别尺度上拉开一点差距。问题根本不在分类器,而在特征区分度不足。

解决办法是增加特征来源:除了MPE,我补充了包络谱的谱峰频率和边带能量比,把它们也拼进特征矩阵后再做KPCA。新一轮实验,混淆率明显下降。这个案例的教训是:分类器调得再好,也很难分辨特征本身就没区分度的样本。排查顺序永远是从数据、特征、再到模型。

6.3 样本量不平衡导致个别类别失效

工业数据里,正常状态样本往往远多于故障样本。如果不处理,模型会偏向大类别,故障类召回率很低。我常用的办法有三类:一是给损失函数加类别权重,让少数类样本的误判产生更大惩罚;二是对小类别样本做窗口重叠采样,同一段信号用不同起点切出多个样本;三是用SMOTE类方法在特征空间做少数类过采样。注意SMOTE要在KPCA之前还是之后用?我习惯在降维后的特征空间做合成,因为此时维度低、相关性处理过,合成样本更自然。

经过处理后,少数类的召回率基本能提升10个百分点以上。当然,合成样本只能作为辅助,最终评估还是以真实测试集为准,不能把合成样本混进测试集。

7. 工程落地中的心得与后续改进

7.1 一套可复用的流程骨架

我这里给出一段流程骨架代码,具体接口按你的数据格式调整就好:

import numpy as np from PyEMD import EEMD from sklearn.preprocessing import StandardScaler from sklearn.decomposition import KernelPCA from antropy import permutation_entropy # 假设 sig_list 是若干个振动信号样本的列表,labels 是对应标签 eemd = EEMD(trials=100, noise_width=0.2) def extract_mpe(imf, scales=10, m=5, tau=1): mpe_list = [] for s in range(1, scales + 1): # 粗粒化 n = len(imf) // s coarse = np.mean(imf[: n * s].reshape(-1, s), axis=1) # 计算单个尺度排列熵 mpe_list.append(permutation_entropy(coarse, order=m, delay=tau, normalize=True)) return np.array(mpe_list) features_all = [] for sig in sig_list: imfs = eemd(sig) imfs = imfs[:8] # 保留前8个有效分量 feat = np.concatenate([extract_mpe(imf) for imf in imfs]) features_all.append(feat) features_all = np.array(features_all) scaler = StandardScaler().fit(features_all) features_all = scaler.transform(features_all) # 拆训练、验证、测试后,仅在训练集上拟合KPCA kpca = KernelPCA(n_components=0.9, kernel='rbf', gamma=0.01, fit_inverse_transform=False) train_kpca = kpca.fit_transform(X_train) test_kpca = kpca.transform(X_test)

有几个地方需要按数据微调:EEMD的trials和noise_width,MPE的scales、m,KPCA的gamma和贡献率,以及BILSTM的两个隐藏层单元数。我建议先拿10到20条样本把整条链跑通,确认每个环节输出的维度符合预期,再全量计算,省得浪费几个小时在调参上。

7.2 计算开销与缓存策略

这套流程里,计算最重的两块是EEMD分解和MPE提取。EEMD要做上百次集成,每条样本可能耗时数秒甚至更久;MPE又在每个IMF、每个尺度上循环。我实际的做法是:把分解和特征提取的结果以npy格式缓存到本地,文件名包含参数签名,下次直接用缓存。批量数据可以用multiprocessing并行,单机8核基本能快6倍以上。

BILSTM训练的耗时反倒还好,因为特征已经压缩得很低,网络参数不多,在普通显卡甚至CPU上都能几分钟内跑完。这也是我喜欢这套方案的原因之一:离线预处理重一点,在线训练和推理都很轻量。

7.3 想进一步优化可以往这几个方向试

如果你觉得这套流程在你的场景里准确率还不够高,我建议按优先级尝试:第一,把EEMD换成CEEMDAN,分解残差噪声更小,IMF对齐更干净;第二,在BILSTM后加一个注意力层,让模型重点看故障冲击最明显的时间步;第三,在特征层面除了MPE,增加排列熵变体(如加权排列熵、余弦相似度熵),增加特征的信息量;第四,尝试把KPCA换成t-SNE或UMAP做可视化对比,判断特征可分性后再决定降维手段。

最后分享一个我反复踩过又修订的小习惯:千万不要在拿到完整数据集后一次性跑完所有内容,先用小样本把每个模块输出的中间结果都打印出来,保存成变量,一步一步肉眼检查。工业信号里的干扰比实验室数据集多得多,任何一个环节“看似正常但细节不对”,都可能让最后的准确率差出一大截。我过去的教训是,宁愿多花两小时检查中间结果,也不要盲目调网络参数两星期。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 15:46:34

QCustomPlot实时曲线绘制:从原理到性能优化的完整指南

简介:一套基于Qt5与QCustomPlot的实时波形绘制控件资源,面向需要快速搭建上位机、实时曲线或数据监测界面的Qt初学者,目的是降低实时绘图功能的入门与集成难度。核心组件为WidgetPlot2D,内部集成QCustomPlot源码,提供i…

作者头像 李华
网站建设 2026/10/21 15:46:29

从零搭建移动机器人地图模块:lingbot-map架构与踩坑实战

lingbot-map 这个项目名,我第一眼看到时以为只是个普通的地图模块,可真到自己动手搭一个同类子系统时才发现,地图模块被低估得离谱。导航决策可以拍脑袋定,底盘控制有现成轮子,唯独地图这层,既要有建图算法…

作者头像 李华
网站建设 2026/10/21 15:45:04

基于Python与Vue的校园流浪动物领养募捐系统设计与实现

晚上十一点从实验室出来,那窝流浪猫又蹲在垃圾桶边上等投喂。橘猫的右后腿好像瘸了,想送去医院又怕耽误项目答辩,更担心治完没人管、猫还是回到原处流浪。这种两难的心情,校园里几乎每个路过的人都经历过——想帮,但不…

作者头像 李华
网站建设 2026/10/21 15:44:35

小样本医学诊断的利器:GRNN原理与疾病分类实战

1. 疾病诊断小数据场景,为什么GRNN比大模型更“顺手” 我在实际做医学相关数据项目的时候,经常被问到一个问题:为什么不用深度学习?大模型不是效果更好吗?道理没错,但前提是有足够多的数据。现实里的疾病诊…

作者头像 李华
网站建设 2026/10/21 15:44:21

数据库管理系统(DBMS)核心特征全解:从建立维护到数据独立性

我们在团队里带新人的时候,有个常见的尴尬场景:SQL写得溜、索引也会建、备份也知道点,可一旦被问到“你觉得数据库管理系统(DBMS)到底是什么?它的核心特征有哪些?”就答不上来了。 这个问题听起…

作者头像 李华
网站建设 2026/10/21 15:44:07

助理工程师技术总结写作指南:从日志到逻辑自洽的实战方法

简介:本资源是一份面向土建工程领域助理工程师的年度专业技术工作总结范文,适用于刚入行1–2年的基层技术岗人员撰写述职报告、职称申报材料或岗位复盘参考。全文以真实项目为背景,系统梳理了施工资料整理移交(含30栋楼档案归档规…

作者头像 李华