简介这份资源面向机械故障诊断方向的研究生、工程师及算法初学者提供一套基于VMD排列熵与ELM的滚动轴承故障诊断Python实现方案帮助读者快速搭建从振动信号分解、特征提取到状态分类的完整流程。压缩包共407个文件以404个txt振动信号样本为主另含2个py脚本与1个csv特征数据整体约4.8MB结构紧凑便于直接运行与二次开发。其中py脚本分别完成VMD分解与排列熵计算、ELM分类训练txt文件对应不同工况下的轴承振动数据csv则用于特征汇总。目前已有633人学习下载适合希望理解变分模态分解、排列熵特征构造及极限学习机分类的读者参考可据此复现故障识别实验、对比不同特征组合效果并在此基础上迁移到其他旋转机械的健康监测任务中。1. 从一段振动信号说起VMD、排列熵和ELM到底怎么串起来做轴承诊断手里只有一段轴承振动信号怎么判断它到底是内圈裂了、外圈剥落了还是滚动体出了问题很多人第一反应是上深度学习但真到产线边上样本少、标注贵、算力紧训练一个几十层的网络往往不划算。我后来稳定用的一套组合是先用 VMD 变分模态分解把原始振动信号拆成若干本征模态分量再对每个分量算排列熵 PE 作为特征最后喂给 ELM 极限学习机做分类。整条链路在 Python 里几十行就能跑通训练阶段几乎不耗时特别适合小样本、要快速迭代的故障诊断场景。这套方案解决的核心问题是把非平稳、噪声重的振动信号转成维度低、区分度高、且对样本量不敏感的特征向量。适合谁适合手上有一台试验台、采了几组正常和故障数据、想快速验证诊断思路的工程师也适合做课程设计或论文复现的同学。它不追求 SOTA 精度追求的是可复现、可解释、能在普通笔记本上跑完。下面我按“信号怎么拆、特征怎么提、分类器怎么用、坑在哪”的顺序讲透。2. VMD 变分模态分解把一段混叠振动拆成干净分量2.1 为什么选 VMD 而不是 EMD轴承振动信号在故障冲击下是非平稳的直接做 FFT 只能看到全局频谱冲击发生的时刻和周期被抹掉了。经验模态分解 EMD 曾经是主流但它有两个老毛病模态混叠和端点效应分解出来的 IMF 经常一个分量里混着好几个频段后面算熵就失真了。VMD 变分模态分解的思路完全不同它把分解写成一个变分优化问题假设每个模态是围绕中心频率的窄带信号通过交替方向乘子法迭代求解把各模态的中心频率和带宽同时约束住。结果就是 VMD 出来的分量频带更干净模态混叠明显减轻中心频率也稳定。代价是要预先指定模态个数 K 和惩罚因子 alpha这两个参数选不好要么过分解要么欠分解。我的经验是轴承故障特征频率通常集中在几个频段K 取 3 到 6 之间先试alpha 默认 2000 起步再根据分量中心频率是否分散来微调。2.2 用 Python 跑通 VMD 的最小代码网上 vmd 的 Python 实现有好几个版本我一般用 vmdpy 这个包接口清晰。先装依赖pip install vmdpy numpy scipy scikit-learn matplotlib然后是最小可运行示例输入一段一维振动信号import numpy as np from vmdpy import VMD # signal: 一维振动信号长度建议 1024 # alpha: 带宽约束默认 2000 # tau: 噪声容限0 表示严格保数据 # K: 模态个数 # DC: 是否含直流分量振动信号一般 False # init: 中心频率初始化1 表示均匀分布 # tol: 收敛容差 u, u_hat, omega VMD(signal, alpha2000, tau0, K4, DCFalse, init1, tol1e-7) # u 形状为 (K, N)每一行是一个模态分量 print(u.shape) # (4, len(signal))逻辑说明VMD 函数返回三个东西u 是时域模态分量u_hat 是频域谱omega 是各模态中心频率。真正拿来做特征的是 u每一行代表一个分解出来的分量。参数说明alpha 越大每个模态带宽越窄容易把有用信息切碎alpha 越小带宽越宽模态之间容易串。K 是最关键的K 太小会把故障冲击和背景噪声混在一个分量里K 太大则会出现中心频率相近的冗余分量。我一般先画 omega看中心频率有没有挤在一起挤了就减 K。2.3 K 和 alpha 怎么定一个可操作的判断流程参数没有万能值但有一套稳定的试法。第一步固定 alpha2000K 从 3 试到 6每次记录 omega。第二步看相邻中心频率的间隔如果两个模态中心频率差不到信号采样率的 5%说明过分解减 K。第三步对每个分量算峭度轴承故障冲击会让某个分量的峭度明显偏高如果所有分量峭度都差不多说明分解没抓住冲击回去调 alpha 或检查信号本身。提示VMD 对信号长度敏感太短的信号比如少于 512 点分解不稳定建议先做分段或补零到 1024 以上再分解。3. 排列熵 PE把每个模态分量压成一个数3.1 排列熵为什么适合振动信号分解完得到 K 个分量如果直接把整段波形当特征维度太高而且对时间平移敏感。排列熵 PE 的好处是它只看信号里相邻数值的大小排列模式对幅值变化不敏感对突变和复杂度敏感计算量还小。轴承正常时振动相对规则排列熵偏低出现故障冲击后信号复杂度上升排列熵升高。所以每个模态分量算一个 PE 值K 个分量就得到 K 维特征向量维度低、物理意义清楚。PE 的核心参数是嵌入维数 m 和延迟时间 tau。m 一般取 3 到 7太小区分度不够太大计算量涨且对噪声敏感。tau 通常取 1因为振动信号采样率高相邻点已经足够。我常用 m5、tau1这个组合在轴承数据上比较稳。3.2 排列熵的 Python 实现与参数import numpy as np from math import factorial def permutation_entropy(x, m5, tau1): n len(x) # 构造所有长度为 m 的嵌入向量 idx np.arange(m) * tau patterns [] for i in range(n - (m - 1) * tau): seg x[i idx] # 用 argsort 得到排列模式 order tuple(np.argsort(seg)) patterns.append(order) # 统计每种排列出现概率 from collections import Counter counts Counter(patterns) probs np.array([c / len(patterns) for c in counts.values()]) # 归一化排列熵 pe -np.sum(probs * np.log(probs)) / np.log(factorial(m)) return pe # 对 VMD 的每个分量算 PE features np.array([permutation_entropy(u[k], m5, tau1) for k in range(u.shape[0])]) print(features) # 长度等于 K 的特征向量逻辑说明先按嵌入维数 m 和延迟 tau 把信号切成重叠片段每段用 argsort 得到大小排列模式统计各模式频率再算香农熵并除以 log(m!) 归一化到 0 到 1。参数说明m 越大能区分的排列模式越多但需要的数据点也越多经验上信号长度至少要是 m! 的几倍才稳定。tau 大于 1 会引入跳点振动信号一般不需要。归一化很重要否则不同 m 下的 PE 没法比较。3.3 特征向量的组织方式K 个 PE 值组成一个 K 维向量这就是一条样本的特征。实际做的时候我会把正常、内圈故障、外圈故障、滚动体故障四类各采若干段每段都走一遍 VMDPE最后拼成一个矩阵行是样本、列是特征。这里有个细节不同样本的 VMD 分解是独立做的所以每个样本的 K 个分量顺序可能不一致但 PE 值本身不依赖分量顺序直接按行拼就行。如果担心顺序问题可以对 PE 值排序后再拼我试过对 ELM 分类结果影响很小。4. ELM 极限学习机小样本下的快速分类器4.1 ELM 相比 SVM 和 BP 的取舍特征有了接下来是分类。SVM 在小样本上表现好但核函数和惩罚系数调起来费劲BP 神经网络要反复迭代样本少容易过拟合。ELM 的思路是隐层权重和偏置随机生成后不再调整只求输出层权重而输出层权重可以通过一次最小二乘解析求解。这意味着训练阶段没有迭代速度极快而且随机隐层在高维特征上反而有不错的泛化。代价是 ELM 对隐层节点数敏感节点太少欠拟合太多过拟合而且随机初始化带来结果波动。我的做法是隐层节点数取特征维度的 5 到 20 倍之间试多跑几次取平均或者固定随机种子保证可复现。4.2 用 Python 实现 ELM 并完成分类import numpy as np from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score class ELM: def __init__(self, n_hidden100, activationsigmoid, seed42): self.n_hidden n_hidden self.activation activation self.seed seed def _act(self, x): if self.activation sigmoid: return 1 / (1 np.exp(-x)) return np.maximum(0, x) # relu def fit(self, X, y): rng np.random.RandomState(self.seed) n_samples, n_features X.shape # 随机输入权重和偏置训练中不再改变 self.W rng.randn(n_features, self.n_hidden) self.b rng.randn(self.n_hidden) H self._act(X self.W self.b) # 输出层权重解析解加正则提升数值稳定性 self.beta np.linalg.pinv(H.T H 1e-6 * np.eye(self.n_hidden)) H.T y def predict(self, X): H self._act(X self.W self.b) return H self.beta # X: 样本特征矩阵 (n_samples, K) # y: one-hot 标签 (n_samples, n_classes) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3, random_state0) elm ELM(n_hidden80, activationsigmoid, seed42) elm.fit(X_train, y_train) y_pred elm.predict(X_test) acc accuracy_score(np.argmax(y_test, 1), np.argmax(y_pred, 1)) print(accuracy:, acc)逻辑说明fit 里随机生成输入权重 W 和偏置 b 后固定计算隐层输出 H再用伪逆求输出权重 beta。predict 用同一套 W、b 算 H乘 beta 得到输出。参数说明n_hidden 是隐层节点数我一般从 50 起试到 200activation 用 sigmoid 或 relu 都行sigmoid 更平滑正则项 1e-6 是防止 H.TH 奇异样本极少时可以调大。seed 固定后结果可复现这点在写论文或做对比实验时很重要。4.3 训练集划分与结果评估的注意点轴承数据往往同一类样本来自连续采集如果随机划分训练测试集相邻样本高度相似测试精度会虚高。更严谨的做法是按时间段划分前 70% 时间做训练后 30% 做测试。另外类别要不均衡就分层抽样。评估别只看准确率混淆矩阵能看出哪两类容易混比如内圈和外圈在早期故障时 PE 特征接近混淆矩阵会暴露这个问题。5. 避坑与排查这套链路最容易翻车的五个地方5.1 现象VMD 分解后所有分量看起来都差不多原因alpha 太小或 K 太大模态带宽过宽导致分量之间高度相关。解决先把 alpha 提到 2000 以上K 降到 3 或 4画各分量频谱确认中心频率是否分开。如果还是混检查信号是否做了去均值直流分量会干扰分解。5.2 现象排列熵值全部接近 1区分不开故障原因m 太小或信号噪声太大排列模式趋于随机。解决把 m 提到 5 或 6先对分量做一次平滑或带通滤波再算 PE。另外确认信号长度足够长度不足 m! 的几倍时 PE 估计偏差大。5.3 现象ELM 训练精度很高但测试精度崩了原因隐层节点过多导致过拟合或者训练测试集随机划分造成数据泄漏。解决减 n_hidden加正则改用按时间划分。我踩过这个坑随机划分下测试集精度 99%按时间划分掉到 85%后者才是真实水平。5.4 现象每次跑 ELM 结果都不一样原因输入权重随机初始化。解决固定 seed或者跑 10 次取平均并报告标准差。如果标准差很大说明特征区分度不够回去优化 VMD 参数或 PE 参数而不是怪 ELM。5.5 现象换一台设备数据整套参数全失效原因采样率、转速、故障特征频率都变了VMD 的 K 和 PE 的 m 需要重新标定。解决把 K 和 m 当作可调超参换数据后先做一轮小网格搜索别指望一套参数打天下。这是血泪经验我早期直接套用旧参数结果诊断全错。6. 进阶把 PE 换成多尺度排列熵以及怎么验证特征真的有用基础版每个分量只算一个 PE信息量有限。进阶做法是多尺度排列熵 MPE对每个分量先做粗粒化得到不同时间尺度序列每个尺度算一个 PE拼起来特征维度变成 K 乘尺度数。这样能同时捕捉高频冲击和低频调制信息对早期微弱故障更敏感。代价是计算量涨且尺度数太多会引入冗余。我一般取尺度 1 到 10再对特征做一次方差筛选或 PCA把维度压回来。验证特征有没有用别只看最终准确率。我习惯做两件事一是画特征散点图用前两个主成分看四类样本是否分得开分不开说明特征不行换分类器也白搭二是做消融分别用原始信号直接分类、只用 VMD 分量能量分类、用 PE 分类对比准确率确认 PE 确实带来了增益。下面这个小表是我在某次试验台上的对比供参考特征方案特征维度ELM 测试准确率原始信号统计量672%VMD 分量能量481%VMD 排列熵493%VMD 多尺度排列熵4095%可以看到 PE 的贡献很明显多尺度再涨一点但维度翻了十倍是否值得看你的算力预算。最后说个习惯我每次做完都会把 VMD 的 omega、PE 参数、ELM 的 seed 和 n_hidden 记在一个配置字典里连同数据划分方式一起存下来。这套链路参数多不记录的话两周后自己都复现不出来。希望帮到你。本文还有配套的精品资源点击获取