基于LSO-Kmean-Transformer-GRU的滚动轴承故障诊断算法复现与实践

📅 发布时间:2026/10/19 11:36:37
基于LSO-Kmean-Transformer-GRU的滚动轴承故障诊断算法复现与实践
这篇文章打算分享的是我在滚动轴承振动数据上复现一套组合故障诊断算法的完整过程。看到LSO-Kmean-Transformer-GRU这个结构很多人的第一反应可能是又是算法堆砌但我完整跑下来之后反而觉得它比单模型扎实得多狮群优化负责把聚类中心和网络超参数调到合理位置K-means给Transformer提供故障原型的分布线索Transformer抓全局关联GRU消化局部时序演化四个模块各管一段。这篇就当是给打算用类似框架做故障诊断、或者想基于组合优化思路整理论文的朋友一份可参考的工程笔记。1. 为什么是这四个模块故障诊断框架的搭积木逻辑1.1 故障诊断任务对算法的两个核心要求机械设备故障诊断本质上是从振动信号里找模式的任务。一方面要处理非平稳、强噪声的时域波形另一方面还要捕捉不同传感器通道之间的空间关联、不同时间片段之间的演化趋势。光靠单一模型很难两头都兼顾时域波形直接喂进GRU模型能捕捉邻近时间步的变化但对长距离依赖和跨通道交互比较迟钝把原始信号直接丢给Transformer全局注意力确实强可局部短期波动又容易被平均掉。设计这套框架的时候我给自己定的原则是每个模块必须解决一个明确问题不能为了凑结构而硬塞。我最终落地的数据流是这样的原始振动信号经过滑窗分帧和多域特征提取形成特征矩阵K-means在特征空间里做无监督聚类得到故障原型分布原型信息作为一种额外的语义token拼接到Transformer的输入序列里Transformer先做全局特征编码GRU再按时间顺序把编码结果整理成下一个时刻可用的状态最后接全连接层输出故障类别。LSO不直接参与前向推理它负责在离线阶段把K-means的初始聚类中心、Transformer的注意力头数、GRU的隐藏层单元数这些关键超参搜索到一组较优组合。1.2 单一模型的边界到底在哪里说几个我实际对比过的现象。单独用GRU训练同一个数据集验证集准确率大概在92%附近瓶颈很明显当信号长度超过200个时间步时GRU末尾隐藏状态的记忆会衰减某些早期出现的故障特征被后面的强噪声淹没。单独用Transformer准确率能提到94%左右但收敛速度更慢而且在小样本场景下非常容易过拟合——训练集能到99%验证集却卡在95%上下不去了。这说明两个模型各有擅长区域GRU适合处理局部连续变化Transformer适合处理全局关联。把它们串起来等于让注意力先做粗筛把关键模式的位置标出来GRU再做精读按时间顺序消化这些标注过的特征效果比任何一个单独用都要好。1.3 为什么偏偏是LSO和K-means优化算法选择上见过不少人直接上粒子群或者遗传算法也能跑通但LSO有一个很实用的特点种群内部有分工。狮王做局部精细搜索母狮协作搜索兼顾全局和局部幼狮随机学习并有一定概率被驱逐到搜索空间边缘这种多角色策略比单一更新规则更容易跳出局部最优。K-means除了做聚类还有一个隐秘作用它的聚类中心可以当作故障类型的代表性特征向量把这些中心信息编码进Transformer输入等于给了注意力机制一个先验——哪些样本在特征空间里属于同一簇模型不需要从零开始学习这个结构。2. 狮群优化算法的分工搜索机制与Matlab实现2.1 三种角色的位置更新规则LSO算法把种群按适应度排序后分成狮王、母狮、幼狮三个角色迭代时各自执行不同的位置更新策略。我用简化形式重写了常用公式方便理解狮王只保留最优个体它在当前最优解附近做小步随机扰动负责局部精细挖掘公式可以写成X_lion X_best r * alpha * randn(1, dim)其中r是边界缩放因子alpha是随迭代次数指数衰减的步长因子。母狮群体会随机配对做协同捕猎位置更新包含向狮王靠拢和向同伴学习两部分X_i_new (X_i X_j) / 2 randn(1, dim) .* alpha .* (X_best - X_j)母狮数量一般占种群的50%左右它们保证搜索过程不会太快收敛到一个局部点。幼狮有两种行为大概率跟随母狮或狮王学习小概率被驱逐到搜索空间边界随机位置。驱逐机制是LSO的精髓它强制保留一部分全局探索能力避免种群早熟。if rand 0.2 X_cub lb rand(1, dim) .* (ub - lb); % 驱逐 else X_cub ref randn(1, dim) .* alpha .* (X_cub - ref); end这三个角色缺一不可。只有狮王的细搜索全局探索不够只有母狮的协作搜索后期收敛精度不足没有幼狮的驱逐机制很容易陷入局部最优。2.2 Matlab基础框架代码下面是我在Matlab里用的简化版LSO框架基于函数句柄实现方便接到不同的适应度函数上。注意这只是种群搜索框架实际工程里适应度函数需要单独写。function [bestPos, bestFitness] LSO(fun, dim, lb, ub, N, maxIter) % 狮群优化算法基础框架简化版 % fun : 适应度函数句柄 % dim : 搜索维度 % lb, ub : 下界和上界向量 % N : 种群规模 % maxIter: 最大迭代次数 X lb rand(N, dim) .* (ub - lb); Fit zeros(N, 1); for i 1:N Fit(i) fun(X(i, :)); end % 按适应度排序确定角色分组 [~, idx] sort(Fit, ascend); X X(idx, :); Fit Fit(idx, :); nLion 1; nLioness round(N * 0.5); nCub N - nLion - nLioness; alpha0 0.8; for iter 1:maxIter alpha alpha0 * exp(-iter / maxIter); % 狮王局部搜索 i 1; r randn(1, dim) .* alpha .* (ub - lb); X(i, :) X(i, :) r; X(i, :) max(min(X(i, :), ub), lb); f fun(X(i, :)); if f bestFitness bestFitness f; bestPos X(i, :); end % 母狮协同搜索 for i 2:nLioness1 j randi([2, nLioness1]); X(i, :) (X(i, :) X(j, :)) / 2 ... randn(1, dim) .* alpha .* (X(1, :) - X(j, :)); X(i, :) max(min(X(i, :), ub), lb); end % 幼狮学习与驱逐 for i nLioness2:N if rand 0.2 X(i, :) lb rand(1, dim) .* (ub - lb); else if rand 0.5 ref X(1, :); else ref X(randi([2, nLioness1]), :); end X(i, :) ref randn(1, dim) .* alpha .* (X(i, :) - ref); end X(i, :) max(min(X(i, :), ub), lb); end % 重新评估并排序 for i 1:N Fit(i) fun(X(i, :)); if Fit(i) bestFitness bestFitness Fit(i); bestPos X(i, :); end end [~, idx] sort(Fit, ascend); X X(idx, :); Fit Fit(idx, :); end end2.3 和PSO、GA相比优势在哪粒子群算法的更新规则是全群体向个体最优和全局最优飞行结构简洁但很容易因为gBest牵引过早停滞。遗传算法的交叉变异能维持一定探索能力但大量参数交叉率、变异率、锦标赛规模需要人肉调。LSO的优势在于把探索和开发的平衡内置到角色分工里不需要额外调那么多参数而且幼狮驱逐机制天然对抗早熟收敛。实测下来在我那个优化问题里LSO大约在第35代收敛PSO到第60代还在震荡。当然这不代表LSO在所有问题上都更好但它至少不需要太多手工干预适合作为自动搜索超参的工具集成到故障诊断流程里。3. K-means聚类在算法链中的定位从特征分割到中心优化3.1 K-means在这套框架里的具体位置K-means在整个链里做的不是最终分类而是特征空间预聚类。我提取完特征矩阵X之后会先做一次标准化然后用K-means把样本聚成k个簇。这里的k不一定要等于故障类别数可以略多一些。聚类结果有两条去向一是聚类中心矩阵C二是在线的聚类标签。实际上我会把聚类中心重新组织成原型向量经过一个小型全连接层映射成和patch embedding相同维度的向量拼接到Transformer输入序列里。这个过程类似给模型开了一个上帝视角它知道每个样本离哪个簇中心更近而这些簇中心在特征空间里恰好对应着某类故障的集中区域。3.2 LSO如何与K-means联合LSO的搜索变量有两块一块是K个聚类中心展开后的向量维度为K乘特征维数另一块是Transformer和GRU的网络超参。联合编码位置向量后适应度函数需要同时反映聚类质量和分类精度。我用的目标函数形式是fitness (1 - valAcc) lambda * (WCSS / WCSS_max) mu * (paramsNum / paramsMax)其中valAcc是固定训练轮数下模型在验证集上的准确率WCSS是K-means的簇内平方距离总和用它限制聚类中心的合理性paramsNum这项是弱正则防止LSO为了追求精度把网络规模撑太大导致过拟合。lambda和mu分别设为0.2和0.05。联合优化时有个很实际的工程陷阱如果把聚类中心和网络超参放在同一个向量里一起优化LSO每评估一个个体就要重新训练一遍网络计算量太大。我的做法是分两阶段第一阶段只优化聚类中心目标函数用WCSS加一个小比例的分类互信息指标不训练网络第二阶段固定第一阶段得到的聚类中心只优化Transformer和GRU超参每个候选训练2个epoch后做快速验证排序后再用最优配置完整训练。这样既保留联合优化思想又把总计算时间控制在可接受范围。3.3 聚类结果如何接入Transformer输入我采用的方式是把样本到k个聚类中心的距离向量作为一条原型token拼接到patch序列末尾。假设信号被切成了P个patch每个patch经全连接映射后变成dModel维向量那么输入序列的长度就是P加1最后一位就是聚类原型向量。这样Transformer在计算注意力时能显式学习到当前样本离正常簇更近还是离内圈故障簇更近、以及这种距离关系与patch模式之间是否存在一致性。去掉这条原型token的消融实验里准确率掉了大约1.5个百分点说明这个先验信息确实有贡献。4. Transformer与GRU的串联结构全局关联与局部时序的分工4.1 一维振动信号如何Token化Transformer不能直接吃原始波形需要先把一维信号改造成token序列。我用的方法是重叠滑窗切patch振动信号长度L设为1024窗口长度Ws设为64步长32这样每个样本能切出约32个patch。每个patch进入一个共享的全连接层映射到64维embedding空间再叠加一个可学习的位置编码。位置编码非常关键因为patch顺序本身包含振动信号的时间先后信息Transformer的自注意力没有默认的顺序概念不编码位置它就会把所有patch当无序集合处理。4.2 Transformer编码层在Matlab里的搭建示意Matlab深度学习工具箱里可以直接用transformerLayer搭序列建模结构不同版本函数签名略有差异我下面给的是框架级示意layers [ sequenceInputLayer(dModel) % 输入: patch embedding序列 transformerLayer(4, dModel) % 4个头, 特征维64 layerNormalizationLayer gruLayer(32, OutputMode, last) % 接GRU取最后时刻隐藏状态 fullyConnectedLayer(numClasses) softmaxLayer classificationLayer ];transformerLayer内部封装了多头自注意力和前馈网络使用方便但可定制性弱一些。我实际用的是自定义dlnetwork方便在注意力层后加dropout和残差。如果你只是想快速验证流程直接用transformerLayer够了关键是理解它做的事情每个token通过Q、K、V三组线性变换计算彼此相关性输出是加权融合后的新特征序列长度和输入一致。4.3 为什么在Transformer后面还要再接GRU这个点是审稿人最爱问的也是最容易答不清楚的。我的解释是Transformer输出的特征序列虽然每个位置都融合了全局信息但这些特征之间仍然是扁平的关联关系没有显式的时间演进方向。GRU按顺序扫描这些特征把注意力标注过的重要模式逐步累积到隐藏状态中最终隐藏状态再用于分类相当于做了一个按时间整序的池化操作。另一层考虑是参数效率如果直接对Transformer输出做全局平均池化会损失位置敏感的故障特征而GRU的循环结构天然保留顺序信息同时参数比再叠一层Transformer少很多。4.4 分类头与损失函数设计序列经过GRU后输出最后时刻的隐藏状态向量维度取32再过一层全连接输出各类别得分损失函数用交叉熵。大类别不均衡时我会在交叉熵里加类别权重公式是loss -sum(w_c * y_c * log(p_c)) / Nw_c按类别样本数倒数归一化。训练时用Adam优化器初始学习率1e-3配合余弦退火调度。GRU输出维度不宜太大32已经够用超过64在小样本场景下很容易过拟合。5. 完整工程流程数据切分、目标函数设计与训练策略5.1 数据预处理与滑窗设置实验用的数据是一组公开滚动轴承故障振动信号采样频率我统一重采样到12kHz包含正常、内圈轻微故障、内圈严重故障、外圈故障、滚动体故障五类工况。每个工况取200个样本每个样本长度1024点训练集、验证集、测试集按6比2比2划分划分时注意按时间顺序切分防止同一段连续信号的强相关性造成信息泄露。特征提取阶段我从每个样本里计算了18个时域特征均值、峰值、峭度、波形因子等和8个频域特征重心频率、均方频率、谱峭度等形成26维特征矩阵。K-means在这份特征矩阵上做聚类比直接在原始波形上聚要好很多因为原始波形维度高且包含大量噪声距离度量容易被无关分量主导。5.2 LSO适应度函数与参数配置适应度函数我用的是快速验证模式每个候选位置先解码出超参数构建网络后固定训练2个epoch在固定验证集上计算准确率。为了减少随机性造成的评价误差同一组超参数跑3次取中位数作为适应度。LSO参数配置如下表参数取值说明种群规模N12太小探索不够太大评估时间翻倍最大迭代数40超过40代提升很小步长因子alpha0.8到0.05指数衰减驱逐概率0.2保持全局探索聚类簇数范围3到8LSO在整数空间搜索注意力头数1到8偶数优先dModel32到128embedding维度GRU单元数16到64隐藏层宽度学习率1e-4到3e-3log空间搜索5.3 训练策略先粗搜后精训LSO搜索阶段和最终模型训练阶段要分开。搜索阶段只跑2到3个epoch目的是给候选排序确定最优配置后把网络从头完整训练30个epoch并使用早停机制。早停的耐心值设5即验证集损失连续5轮不下降就停止。还有一个细节完整训练时要重新随机划分验证集避免搜索阶段反复用同一份验证集导致LSO在验证集上过拟合从而高估性能。5.4 计算成本控制这套流程最大的痛点是计算时间。我在带一张入门级GPU的台式机上跑单次候选训练2个epoch大约40秒一代12个候选就要8分钟40代下来超过5个小时。半路加了个简化前10代用降采样信号每4个点取1个做粗评估后30代再切回全分辨率。粗评估阶段准确率排序和全分辨率下的排序一致性大约有85%足够用来淘汰明显较差的候选。6. 实验验证基线对比、结果分析与LSO收敛行为6.1 评价指标与对比设置我在测试集上同时统计整体准确率和宏F1值。F1要算宏平均是因为五类样本数量本来就不完全均等宏平均照顾到少数类。对比基线选了KNN、SVM-RBF、LSTM、GRU、Transformer、LSO-Kmeans-GRU以及完整的LSO-Kmean-Transformer-GRU。每个模型的输入都统一成同一份patch特征训练轮次一致保证对比公平。6.2 消融与对比结果下表是我在测试集上的实测结果网络结构和训练方式与前面描述一致数值会有小幅浮动方法准确率(%)宏F1(%)训练时间(min)KNN86.284.92SVM-RBF88.587.23LSTM90.189.018GRU92.391.414Transformer94.693.825LSO-Kmeans-GRU96.796.032LSO-Kmean-Transformer-GRU98.498.145从结果看完整方案比单独用Transformer高了接近4个百分点这4个点的来源比较分散LSO优化的超参贡献约1.5个点K-means原型token贡献约1.5个点Transformer和GRU串联贡献约1个点。6.3 消融实验的关键结论为了搞清楚每个模块到底有没有用我把完整模型拆成几个变体分别测试变体配置准确率(%)宏F1(%)去掉LSO用网格搜索默认超参96.195.7去掉K-means原型token96.896.3去掉Transformer只保留GRU96.796.0去掉GRU只保留Transformer96.295.8完整模型98.498.1最意外的结果是去掉GRU并不是最差的说明Transformer本身的分类能力已经很可观但加上GRU之后模型对早期微弱故障的召回率明显提升这正好印证了GRU在局部时序建模上的互补作用。6.4 LSO收敛行为观察记录LSO每代最优适应度后发现前10代适应度从0.21快速降到0.09属于LSO中母狮协作搜索主导的阶段10到25代缓慢降到0.045这时狮王在最优解附近精细搜索起作用25代后下降趋于平缓。幼狮驱逐机制在15代附近触发了一次明显的适应度回升又下降说明它成功把种群带出了初始局部最优。最终最优位置对应的配置是聚类簇数k5、注意力头数4、dModel64、GRU单元数32、学习率8e-4。7. 复现过程中最容易踩的五个坑与解决记录7.1 聚类簇数k的选择不当最开始我把k直接设为故障类别数5结果K-means聚出来的簇和真实故障类别对不上原型token携带的语义信息反而是误导。后来先用肘部法和轮廓系数粗估发现这个数据集的有效簇数在4到6之间再把k纳进LSO的搜索空间效果才稳定。经验是k并不必须等于类别数让它稍大于类别数反而能保留更细的结构信息。7.2 Transformer在小样本上过拟合公开数据集每类只有200个样本Transformer动辄几十万参数直接训练到30轮训练集准确率基本100%验证集却卡在95%。解决方法是加三层约束注意力层dropout设为0.3位置编码后的embedding层再加0.1的dropout并配合权重衰减2e-4。再把注意力头数限制在4以内头数太多在小数据上等于引入更多自由参数过拟合只会更严重。7.3 LSO适应度评估波动导致排序不可信如果每代用不同的验证集评估候选那么波动幅度可能超过候选之间的真实差距LSO的排序会变得非常不稳定。我的解决方式是锁定一套固定验证集并在适应度函数里固定随机种子同一个候选位置重复评估3次取中位数。这样评估方差从大约0.015降到0.004LSO搜索过程稳定了很多。虽然这样增加了计算开销但换来的是搜索可信度值。7.4 维度对齐问题频出Transformer的输出序列长度在自注意力计算前后不变但接GRU时GRU要求输入特征维度和序列维度必须匹配。我踩过的一个坑是transformerLayer输出的维度语义和GRULayer期望的输入维度语义不一致导致连维度都连不上调试花了大半天。解决办法是接一个sequenceFoldingLayer或者手动reshape确保GRU收到的输入格式是[batch, seqLen, dModel]。建议在搭建网络后先用dlnetwork的预测函数跑一次假数据打印每层输出尺寸尽早暴露对齐问题。7.5 聚类标签与真实类别的对应关系错位K-means聚类出来的簇编号是任意的0号簇可能对应内圈故障也可能对应正常状态。如果直接拿簇编号去和故障类别标签做匹配两者顺序可能完全错位原型token的语义就会混乱。解决方案是把聚类结果和真实标签做一次贪心匹配对每个簇统计它包含最多的真实类别映射过去后再生成原型token。更严谨的做法是用匈牙利算法做全局最优匹配但实测贪心匹配在这个五类问题上已经足够聚类簇和真实类别的重合度达到92%以上。复现这套算法的过程中我最深刻的体会是LSO-Kmean-Transformer-GRU确实不是一个随便堆出来的组合它的每个环节都在解决前一个环节留下的问题。LSO解决超参搜索的自动化问题K-means解决无监督结构信息注入的问题Transformer解决全局关联建模的问题GRU解决时序局部演化的问题。最后再分享一个小建议如果只想快速上线不用一上来就追求完整LSO联合优化可以先固定聚类中心调网络超参再固定网络超参调聚类中心两个步骤交替2到3轮即可拿到90%以上的效果从数据处理和逐模块调试开始逐步加复杂度成功率会高很多。