2026/10/5 9:20:16

参数优化VMD结合改进样本熵的滚动轴承故障诊断方案

参数优化VMD结合改进样本熵的滚动轴承故障诊断方案 简介这份文档面向机械故障诊断方向的研究生与工程技术人员聚焦滚动轴承故障特征提取与识别这一典型难题。针对振动信号噪声冗余、特征不丰富导致识别率偏低的问题文档系统梳理了从EMD、LMD到VMD的信号分解方法演进脉络并重点阐述采用遗传变异粒子群算法优化VMD惩罚因子与分解个数再结合样本熵构建故障特征向量、以SVM完成分类识别的完整思路同时分析了样本熵在衡量复杂度时的局限并提出基于故障机理的改进算法。资源包内含1个docx文档约1.52MB内容涵盖方法原理、参数优化策略、仿真实验与结构安排适合作为课题入门、算法复现与论文写作的参考材料。目前已有374人学习下载可帮助读者快速建立VMD参数优化与样本熵特征提取的知识框架理解小样本条件下SVM分类器的选型依据。1. 参数优化 VMD 加样本熵这套滚动轴承诊断方案到底解决了什么轴承故障诊断最让人头疼的不是没有数据而是数据里噪声太多、故障特征太弱。你拿加速度传感器采一段内圈故障信号时域波形上冲击成分被背景噪声盖得七七八八直接做 FFT 只能看到一堆模糊的边频带。这份资源围绕一个很具体的痛点展开用参数优化的 VMD 把原始振动信号拆成若干 IMF 分量再用改进的样本熵量化每个分量的复杂度最后送进 SVM 做分类。整套流程覆盖信号处理、特征提取和诊断识别三个环节适合手里有凯斯西储大学轴承数据、想跑通一条完整诊断链路的人。它不教你从零推导变分模型而是把参数怎么选、熵值怎么算、分类器怎么接这三件事串成可复现的步骤。如果你之前用 EMD 被模态混淆折腾过或者用固定参数的 VMD 分解出来一堆虚假分量这套东西值得拆开看。2. VMD 分解与参数敏感性为什么 K 和 α 不能拍脑袋定2.1 变分模态分解的核心机制VMD 和 EMD、LMD 最大的区别在于它不是递归分解而是一次性把信号拆成 K 个窄带 IMF 分量。每个 IMF 被定义成调幅-调频信号分解过程本质上是求解一个约束变分问题在“各分量之和等于原始信号”的约束下让所有分量的估计带宽之和最小。求解时引入二次惩罚因子 α 和拉格朗日算子把约束问题转成非约束问题再用 ADMM 交替更新各分量的中心频率和带宽。这个机制带来的好处很直接端点效应基本消失模态混淆被抑制分解效率比递归方法高出一截。但代价是 K 和 α 必须提前给定而这两个参数对分解结果的影响非常大。2.2 K 和 α 对分解效果的具体影响用仿真信号来观察最直观。构造一个包含 90 Hz、95 Hz、100 Hz、105 Hz、110 Hz 五个频率成分的 AM-FM 信号采样频率 1000 Hz固定 α2000分别取 K3、4、5、6、7 做 VMD 分解K3、4、5 时分解出的中心频率数量不够100 Hz 附近的成分没有被完整分离出来属于欠分解。K6 时五个频率成分全部被正确分解中心频率收敛到对应频点。K7 时95 Hz 附近冒出一个虚假分量同时 100 Hz 成分反而没分出来属于过分解。固定 K6改变 α 从 0.3fs 到 5fs 观察α0.3fs 时100 Hz 成分没分出来欠分解。α0.6fs 时迭代初期中心频率出现混叠最终也没能正确分离。αfs 时中心频率最终能反映真实频率成分但迭代次数偏大。α2.5fs、4fs、5fs 时迭代后期中心频率正确但达到最优效果的迭代次数先减后增α5fs 时 110 Hz 附近还出现了较长时间的混叠。结论很明确K 和 α 的最优值没有解析解靠经验试凑只能得到“相对最优”换一组工况数据就得重新调。这就是为什么需要引入优化算法来自动搜索参数组合。2.3 用遗传变异粒子群算法搜索最优参数标准粒子群算法容易陷入局部最优这份方案在 PSO 里嵌入了遗传算法的变异操作。具体做法是记录每个粒子个体最优值的保持代数当保持代数达到 maxAge 阈值时对粒子位置和速度执行遗传变异强制跳出局部极值区域。适应度函数的设计是这套方案的一个关键细节。它没有只用包络熵而是把包络熵和迭代次数加权组合import numpy as np def fitness_function(K, alpha, signal, beta1/1000): 计算 VMD 参数组合的适应度值 K: IMF 分量个数 alpha: 惩罚因子 signal: 原始振动信号 beta: 迭代次数的量化因子 # 执行 VMD 分解返回 K 个 IMF 分量和迭代次数 imfs, iter_count vmd_decompose(signal, K, alpha) # 计算每个 IMF 分量的包络熵 envelope_entropies [] for imf in imfs: # Hilbert 解调获取包络信号 envelope np.abs(hilbert(imf)) # 归一化 p envelope / np.sum(envelope) # 包络熵计算 Ep -np.sum(p * np.log(p 1e-12)) envelope_entropies.append(Ep) # 取最小包络熵作为局部极小熵 min_Ep np.min(envelope_entropies) # 适应度 最小包络熵 beta * 迭代次数 fitness min_Ep beta * iter_count return fitness, min_Ep, iter_count包络熵衡量的是 IMF 分量的稀疏性分量中噪声多、冲击特征被掩盖时包络熵偏大分量中出现规律性冲击脉冲时包络熵偏小。取 K 个分量中最小的包络熵作为局部极小熵对应的分量就是蕴含故障特征最丰富的那个。β 取 1/1000 是在分解效果和分解效率之间做的折中β 再小的话迭代次数的影响基本可以忽略。粒子群参数按经验值设置种群规模 m20学习因子 c1c22最大迭代次数 nmax40maxAge2惯性权重从 0.9 线性递减到 0.4变异概率 q1/D0.5D2 是因为只优化 K 和 α 两个参数。3. 样本熵的局限与改进从故障机理反推算法修正3.1 传统样本熵为什么在轴承故障上翻车样本熵的评判原则听起来很合理时间序列越复杂熵值越大。但直接拿它算轴承振动信号结果和机理分析对不上。用凯斯西储大学 SKF6205 轴承数据实测四种状态的样本熵值是工况类型传统样本熵值改进样本熵值正常状态0.97170.2923内圈故障1.59761.3700滚动体故障1.69370.7557外圈故障0.70991.2338正常状态的熵值 0.9717 居然大于外圈故障的 0.7099按样本熵的规则这意味着正常信号比外圈故障信号更复杂但机理分析恰恰相反故障状态下轴承啮合尺度变化振动幅值加剧信号复杂度应该更高。3.2 阈值 r 被冲击幅值“绑架”了问题出在阈值 r 的设定上。传统样本熵取 r 为原始信号标准差的 0.1~0.2 倍而故障状态下的振动信号含有周期性冲击幅值外圈故障时幅值范围能到 [-5, 5]正常状态只有 [-0.2, 0.2]。冲击幅值把标准差拉大阈值 r 跟着变大模式匹配时的相似容限变宽更多本不相似的向量被判定为匹配最终算出来的熵值反而偏小。用依拉达准则剔除部分冲击幅值后重新计算内圈故障熵值从 1.5976 升到 1.7200外圈故障从 0.7099 升到 0.8600说明冲击幅值确实在压低熵值。但剔除冲击幅值本身又会丢失故障信息不是正路。3.3 基于故障机理的样本熵计算流程改进思路是对原始信号先做一阶差分把冲击幅值的影响降下来让算法关注冲击之间的局域波动。差分后信号的标准差记为 SD1阈值设为 r 0.2·SD1。相似容限在 [0.1, 0.2] 区间时四种状态的区分度最好容限过大正常状态和滚动体故障混在一起容限过小内圈故障和外圈故障分不开。具体计算步骤import numpy as np def mechanism_sample_entropy(signal, m2, r_factor0.2): 基于滚动轴承故障机理的样本熵 signal: 原始振动信号 m: 模板匹配长度 r_factor: 阈值系数默认 0.2 # 步骤1一阶差分降低冲击幅值影响 diff_signal np.diff(signal) # 步骤2以差分信号标准差设定阈值 SD1 np.std(diff_signal) r r_factor * SD1 N len(diff_signal) # 步骤3构建 m 维向量并计算匹配概率 def count_matches(dim): templates np.array([diff_signal[i:idim] for i in range(N - dim 1)]) count 0 total 0 for i in range(len(templates)): # 计算最大差值绝对值 dists np.max(np.abs(templates - templates[i]), axis1) # 排除自身匹配 matches np.sum(dists r) - 1 count matches total 1 return count / (total * (total - 1)) if total 1 else 0 Bm count_matches(m) # 匹配 m 个点的概率 Am count_matches(m 1) # 匹配 m1 个点的概率 # 步骤4样本熵值 if Bm 0 or Am 0: return float(inf) return -np.log(Am / Bm)差分操作把原始信号中的直流分量和缓变趋势去掉保留的是冲击之间的局部波动细节。阈值 r 不再被冲击幅值直接放大而是由差分信号的标准差决定这样故障状态下冲击之间的波动能被正确捕捉到。改进后正常状态熵值 0.2923 小于三种故障状态的熵值与机理分析一致。4. 完整诊断链路搭建从原始信号到分类结果4.1 数据准备与参数寻优整套流程的输入是四种状态正常、内圈故障、滚动体故障、外圈故障的振动信号。以凯斯西储大学数据为例采样频率 12 kHz转速 1797 r/min0 kW 负载损伤直径 0.1778 mm。每种状态取若干段样本每段长度建议不低于 2048 个点保证样本熵计算时有足够的模板匹配对数。参数寻优阶段对每种状态分别用遗传变异粒子群算法搜索最优的 [K0, α0] 组合。注意这里是对每种状态独立寻优因为不同故障类型的信号频带分布不同最优参数组合也会有差异。# 遗传变异粒子群算法主循环简化框架 for state in [normal, inner, ball, outer]: signal load_bearing_data(state) # 初始化粒子群 particles initialize_swarm(size20, dim2) # K 搜索范围 [2, 10]alpha 搜索范围 [100, 5000] bounds [(2, 10), (100, 5000)] best_fitness float(inf) best_params None for iteration in range(40): for i, particle in enumerate(particles): K int(particle.position[0]) alpha particle.position[1] # 边界约束 K np.clip(K, bounds[0][0], bounds[0][1]) alpha np.clip(alpha, bounds[1][0], bounds[1][1]) fit, min_Ep, iters fitness_function(K, alpha, signal) # 更新个体最优 if fit particle.best_fitness: particle.best_fitness fit particle.best_position [K, alpha] particle.age 0 else: particle.age 1 # 遗传变异个体最优保持代数超限时触发 if particle.age maxAge: particle.position genetic_mutation(particle.position, q0.5) particle.age 0 # 更新全局最优 current_best min(particles, keylambda p: p.best_fitness) if current_best.best_fitness best_fitness: best_fitness current_best.best_fitness best_params current_best.best_position # 线性递减惯性权重 w 0.9 - (0.9 - 0.4) * iteration / 40 update_velocities(particles, w, c12, c22) print(f{state}: K0{best_params[0]}, alpha0{best_params[1]:.1f})这段代码里几个参数需要留意K 的搜索范围不宜设得太宽一般 2 到 10 足够覆盖轴承信号的频率成分数量α 的下界不要低于 100否则分解带宽过大导致模态混叠maxAge2 是经验值设大了收敛慢设小了变异太频繁反而破坏搜索稳定性。4.2 特征向量构造与 SVM 分类拿到最优参数后用 VMD 分解各状态的振动信号得到 K0 个 IMF 分量。对每个 IMF 分量计算改进样本熵组成 K0 维特征向量。这里有个细节不同状态下最优 K0 可能不同需要统一取一个固定的 K 值来保证特征向量维度一致通常取各状态 K0 中的最大值不足的分量用零填充或者只取前 min(K0) 个分量。SVM 分类器采用多核学习框架组合全局核和局部核from sklearn.svm import SVC from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 构造特征矩阵每行是一个样本的 K0 维样本熵特征 X build_feature_matrix(signals, K0, alpha0) # 标签0-正常1-内圈2-滚动体3-外圈 y build_labels(num_samples_per_class) # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy ) # 多核 SVM全局核 局部核加权组合 # H(X,Y) w * H_global(X,Y) (1-w) * H_local(X,Y) # 常见做法是全局核用多项式核局部核用 RBF 核 svm SVC(kernelrbf, C10, gammascale) svm.fit(X_train, y_train) y_pred svm.predict(X_test) accuracy accuracy_score(y_test, y_pred) print(f分类准确率: {accuracy:.4f})SVM 的惩罚参数 C 和核函数参数 gamma 对分类精度影响较大。如果手头样本量很小每类几十个C 取 1 到 10 之间gamma 用 scale 自动估计就行。如果分类准确率不理想优先检查特征向量——把四种状态的样本熵值画出来看看类间距离是否足够大而不是急着调 SVM 参数。5. 避坑与排查跑这套流程最容易翻车的五个地方5.1 VMD 分解报错或返回空分量现象调用 VMD 时程序崩溃或者返回的 IMF 分量全为零。原因最常见的是 K 值设得过大超过了信号实际包含的频率成分数量导致某些分量的中心频率无法收敛。另一个可能是 α 设得过小带宽约束太弱迭代过程中出现数值溢出。解决先把 K 限制在 2 到 8 之间试跑确认能正常分解后再交给优化算法搜索。α 的下界不要低于 100。如果用的是 Python 的 vmdpy 包检查信号长度是否满足 N 2*K否则直接报错。5.2 样本熵计算结果为 inf 或 NaN现象计算样本熵时返回无穷大或缺失值。原因模板匹配时 Bm 或 Am 为零即没有任何一对向量在相似容限内匹配。这通常发生在 r 设得太小、或者信号长度太短的情况下。解决先检查 r 的取值改进样本熵里 r 0.2·SD1如果差分信号的标准差本身很小r 会趋近于零。可以设一个下限比如 r max(0.2·SD1, 1e-6)。另外确保每段信号长度不低于 2048 点模板匹配长度 m 取 2 就够了取太大会减少有效匹配对数。5.3 优化算法搜出来的参数还不如手动设的现象遗传变异粒子群算法跑了 40 代搜出来的 [K0, α0] 分解效果反而不如经验值 K5、α2000。原因适应度函数里 β 取值不当迭代次数项权重过大算法为了减少迭代次数牺牲了分解效果。或者种群规模太小、迭代代数不够搜索没充分展开。解决β 从 1/1000 开始试如果搜出来的参数包络熵明显偏大把 β 降到 1/2000 甚至 1/5000让分解效果占主导。种群规模至少 20迭代代数至少 30。另外检查粒子位置更新时有没有做边界约束K 和 α 飞出搜索范围后没有截断的话适应度计算会出错。5.4 分类准确率远低于预期现象特征向量送进 SVM 后准确率只有 60% 出头四种状态混淆严重。原因特征向量区分度不够。可能是 VMD 分解时用了统一的 K 和 α但不同故障状态的敏感频带不同统一参数下某些状态的特征被淹没。也可能是样本熵只提取了复杂度信息丢失了频域特征。解决对每种状态独立做参数寻优然后用各自的最优参数分解。如果还不行在样本熵特征基础上拼接 IMF 分量的中心频率或者峭度值构成多维特征向量。SVM 这边可以先做个特征标准化把各维熵值缩放到同一量级。5.5 换一组数据后整套流程失效现象在凯斯西储大学数据上跑通了换成自己设备的振动信号后分解结果混乱、分类准确率暴跌。原因采样频率、转速、传感器安装位置都变了信号的频率分布和幅值范围跟原数据完全不同。原来搜出来的 K 和 α 在新数据上不适用样本熵的阈值系数 0.2 也可能需要调整。解决换数据后重新跑一遍参数寻优不要直接套用旧参数。采样频率变化时α 的搜索范围要按新的采样频率重新设定。如果新数据的信噪比明显更差先做一轮带通滤波再送 VMD否则噪声分量会干扰包络熵的计算。6. 进阶技巧用中心频率约束把虚假分量挡在门外参数寻优解决了 K 和 α 的选取问题但还有一个隐蔽的坑即使 K 和 α 都搜到了最优值VMD 偶尔还是会在高频段产生一个能量很低的虚假分量。这个分量的包络熵可能很小被适应度函数误判为“富含故障特征”实际上它只是数值求解过程中的残差。我一般会在参数寻优结束后加一道后处理检查每个 IMF 分量的中心频率是否落在合理的频带范围内。轴承故障特征频率通常分布在几千赫兹以内如果某个分量的中心频率接近采样频率的一半基本可以判定为虚假分量直接从特征向量里剔除。def remove_spurious_imfs(imfs, center_freqs, fs, threshold0.4): 剔除中心频率过高的虚假 IMF 分量 imfs: VMD 分解得到的 IMF 分量列表 center_freqs: 各分量的中心频率 fs: 采样频率 threshold: 频率阈值系数默认 0.4*fs valid_imfs [] valid_freqs [] for imf, freq in zip(imfs, center_freqs): if freq threshold * fs: valid_imfs.append(imf) valid_freqs.append(freq) else: print(f剔除虚假分量: 中心频率 {freq:.1f} Hz) return valid_imfs, valid_freqsthreshold 取 0.4 是个经验值对应 12 kHz 采样时中心频率上限约 4800 Hz。如果你诊断的是低速重载设备故障特征频率可能更低threshold 可以压到 0.2。反过来高速轴承的故障频率可能到 6000 Hz 以上threshold 要放宽到 0.5。另一个值得做的验证是把改进样本熵和传统样本熵同时算一遍对比四种状态的类间距离。如果改进样本熵的类间距离没有明显拉开说明差分操作可能把有用的故障信息也滤掉了这时候要回头检查信号的预处理环节——是不是原始信号里冲击成分本身就太弱需要先做包络解调再送进这套流程。从那以后我每次跑轴承诊断不管数据看起来多干净都会先把四种状态的样本熵值画出来目视检查一遍类间分离度确认特征本身没问题再往下走分类。这一步花不了五分钟但能省掉后面调 SVM 参数调到头秃的时间。希望帮到你。本文还有配套的精品资源点击获取