☰
WMSST与MCNN-BiGRU结合:滚动轴承故障诊断的时频深度学习方法
2026/10/19 8:44:17 网站建设 项目流程

1. 为什么故障诊断绕不开时频变换这一关

1.1 振动特征藏在“瞬时冲击”里,波形统计指标容易误判

我在做滚动轴承故障诊断这几年,最直观的一个体会是:故障信息不是“均匀分布”在整段波形里的,而是以短暂冲击、局部调制的方式存在。轴承内圈出现点蚀之后,滚动体每经过缺陷位置就会激起一个衰减振荡,这个冲击持续的时间可能只有几毫秒,能量占比非常小,但频率范围却拉得很宽。早期故障阶段,它完全可能被转频分量、齿轮啮合分量和随机噪声淹没。

很多人一开始习惯用均方根、峰度、裕度因子这类时域统计量做判断。信号平稳时,这些指标确实好用,但对转速波动和负载变化特别敏感。同样一个轴承,负载稍微一变,均方根值就可能差出百分之三四十;峰度值对单次冲击又过于敏感,一次误触发就报警。我见过不少工程现场不是模型不够好,而是特征量在入口处就把关键信息“平均”掉了——时域指标本质上是对一段波形的整体压榨,冲击的瞬态结构根本留不住。

频域分析虽然能反映周期性冲击对应的边带和谐波,但它把“什么时候发生冲击”这个时间信息丢了。故障诊断真正需要的,是一个既保留时间定位、又保留频率分布的描述方式。这就是时频分析为什么在诊断管道里处于不可替代的位置——它给出的是一个“二维矩阵”,横轴是时间,纵轴是频率,矩阵值代表该时刻该频率下的能量强度。有了这个矩阵,深度学习网络才能同时观察到“冲击何时出现”和“能量集中在哪个频带”两层信息。

1.2 常用时频工具各自的软肋

短时傅里叶变换是最容易上手的,它把信号切成一段段小窗做傅里叶变换。问题在于窗口长度一固定,时间分辨率和频率分辨率就互相锁死了:窗太短,时间定位准,频率看起来糊成一片;窗太长,频率分得开,但时间轴变得迟钝。为了避免这个矛盾,换用小波变换,它通过伸缩母小波获得不同尺度的时频窗,高频部分时间分辨率好,低频部分频率分辨率好。这套机制对小波基的选择很敏感,而且小波系数能量在高频区域仍然存在明显的扩散——谱线不是一条细线,而是一片“糊”的区域,人眼能看,网络学习起来却不容易。

维格纳分布虽然理论上分辨率很高,但多分量信号会产生交叉项,也就是在两个真实分量中间出现虚假的第三第四个峰,这对故障诊断来说几乎不可接受,因为轴承故障信号天然就是多分量的。所以实际工程里很少直接用维格纳分布喂给深度网络。

这一串对比说明了一个核心问题:我们需要的是一种能把能量重新“聚拢”到瞬时频率附近,同时又能兼顾不同频带细节的时频表示。小波多尺度同步压缩变换WMSST正是沿着这个思路设计的,它也是本文整个诊断网络的第一级入口。把这一步做好,后面多尺度卷积神经网络和双向门控循环网络才能吃到高质量的特征图,诊断上限也随之抬高。

2. WMSST为什么是时频工具箱里更适合诊断的选项

2.1 同步压缩解决“能量模糊”:把散掉的系数重新归属

同步压缩变换的基本思想并不复杂,但要真正看懂它,得先理解小波系数为什么是“模糊”的。连续小波变换把信号和不同尺度的母小波做内积,得到的结果会被摊在时间-尺度平面上。问题是,一个频率分量往往同时和多个尺度的子波都有一定相关性,于是能量会从一个中心尺度向两侧泄漏,形成一条“带”而不是一条“线”。频率越高的分量,这种泄漏在尺度轴上表现得越宽。

同步压缩的做法,是利用小波系数的相位信息,在每个时间点上估计出局部瞬时频率,然后把宽度方向上的能量重新分配到它真正对应的那个频率槽里。用公式表达大致是这样:设小波系数为 W_f(a,b),先求关于时间方向的偏导,得到每个时频格点上的瞬时频率估计值:

ω(a,b) = -i · (∂W_f(a,b)/∂b) / (2π · W_f(a,b))

然后在频率轴上做重排,把落在同一个中心频率槽 ωl 附近的系数累加起来,就得到压缩后的频谱表示。它相当于把原本散在雾里的灯光重新聚回灯芯上。对故障诊断来说,这意味着转频边带、故障特征频率、谐波等成分在时频图上会呈现为更锐利、更清晰的脊线,而不是一团团模糊的云。

这里有一个重要前提:同步压缩对信号的瞬时频率变化模式有要求。如果信号的频率调制太剧烈,或者两个分量在时频平面上交叉,相位估计就会出错,压缩后的结果反而更乱。轴承故障信号虽然有调制,但调频速度通常远低于载波频率,单看每个短时窗是基本满足压缩条件的。因此,同步压缩处理轴承信号,比处理大变频工况下的齿轮箱信号要稳得多。

2.2 多尺度机制:全频带一次压缩会牺牲局部细节

“多尺度”三个字,是WMSST区别于普通同步压缩的关键。普通同步压缩对整个分析频带做一次能量重分配,它的视角是全频带统一的,等于默认了所有频带都采用相同的压缩策略。但实际故障信号往往不是这个结构:滚动体故障的冲击能量集中在很高的频带,包络又调制在一个较低的重复频率上;转频和齿轮啮合频率则集中在低频区。如果一股脑全频带压缩,网络能看到的整体谱型很干净,然而不同故障模式下的小差异——比如某类故障在几个特定窄带上有细微的谱形差异——很容易在全局压缩中被抹平。

多尺度处理的基本路线是分而治之:把分析频带切分成若干子频带,对每个子频带分别进行同步压缩;也可以把不同小波尺度区间分组,每一组单独完成压缩后再把结果拼接。举个例子,把采样率5120Hz的信号先分到0~500Hz、500~1500Hz、1500~2500Hz三段,每一段分别用不同的小波基或不同压缩参数做一次同步压缩,最后按频率轴顺序拼接成一张多尺度时频图。这样做的好处,是高频细节不会被低频强能量“卷走”,每个频带内部的微小结构都能保留下来,网络后级的分辨能力自然更强。

顺带一个工程上的注意点:频带划分不要贪多。分得太细,每个子带里的样本点太少,能量统计波动大,时频图充满椒盐噪声;分得太粗,又失去了多尺度意义。我实践中一般把感兴趣频段分三段或四段就足够,后面配合深度网络去学特征,会比你手动调出细密的划分更稳定也更省事。

2.3 WMSST输出如何变成MCNN友好的输入

从WMSST得到的结果本质上还是小波系数矩阵,要喂给卷积网络,需要先做几件事。第一步是取模值,因为网络的输入应该是实数矩阵,而小波系数本身携带相位信息,我们更看重能量强度。第二步是频率轴裁剪,把无关的高频噪声带或低频直流区切掉,只保留有效分析范围。第三步是幅度刻度,我强烈建议不要直接用全局0到1归一化。原因很明显:如果某条强转频线的能量是某个高频冲击能量的50倍,全局归一化会把那个微弱的冲击成分压到接近0,网络基本学不到它。

更稳妥的做法是先按频带归一化,或者先取对数刻度再归一化。工程上常见的管道是log1p(abs(sst)),对数能把高低能量的数量级差距压缩到几个单位以内,再用mat2gray归一化。如果需要保留原始能量差异,就做成多通道输入:把不同频带分别归一化后,作为RGB的三个通道送入卷积网络。这样网络既能独立看到每个频带的结构,又能通过跨通道卷积综合出全局信息,这是一个小而实用的技巧。

3. MCNN-BiGRU的结构:空间感受野与时间上下文分开学

3.1 三个卷积分支,对应不同的特征尺度

时频图本质上是一张图像,但它和自然图像有个关键区别:它的横纵轴都有物理意义,横轴是时间,纵轴是频率。因此卷积核的尺寸意味着网络看“多大范围内的时空邻域”。

MCNN的多尺度设计通常由三个并行分支组成。第一个分支使用较小的卷积核,比如3×3,它负责捕捉时频图上的局部点状特征,对应单个冲击在某一时刻某一频点上的尖峰;第二个分支使用中等尺寸的卷积核,比如5×5,它能把几个相邻频点的活动综合起来,捕捉冲击的短时带宽;第三个分支使用更大的卷积核,比如7×7,它可以覆盖到连续几个时间步,观察到冲击的包络调制规律。三个分支用相同的padding方式,保证输出特征图的宽高一致,然后沿通道方向拼接。

面对轴承故障时频图像,这种多分支结构确实有它的道理:滚动体故障的谱形通常表现为高频共振带上间隔均匀的尖峰;内圈故障因为传递路径随位置变化,尖峰幅度会有周期性起伏;外圈故障则相对稳定。这些差异在不同尺度上的表现并不相同,单支路卷积只能看到一种“视线”,多支路并联等于同一张图上同时架了三台不同焦距的相机,拼接之后信息互补性远强于单分支。卷积之后接上批归一化和ReLU,批归一化能防止不同分支输出的数值尺度差异过大,ReLU则给模型引入非线性,同时把负值响应截掉,保持特征稀疏。

3.2 BiGRU为什么比单向GRU更适合承接时频特征序列

卷积层拿到的是一张完整的二维时频图,卷积输出的特征图也是二维的。要交给循环网络,就需要把特征图沿时间轴理解为一个序列:每一时刻 t 对应一组沿频率维和通道维展开的特征向量。这个展开的过程,信息组织上很像“逐帧观看”一段频谱动态。

门控循环单元GRU本质上是对LSTM的一种精简,它把输入门和遗忘门合并成更新门,参数更少,训练更快,在小样本诊断场景下不容易过拟合。但单向GRU有一个天然的偏置:它只能从过去看到现在,难以利用“未来信息”。而时频图上的一个冲击,它的左边和右边往往都是重要的上下文——冲击发生前的一小段平缓背景提供了对比,冲击发生后的衰减振荡则提供频率衰减的信息。双向GRU通过正反两个方向同时扫过序列,每个时间步的输出都聚合了前后两端的状态,正好贴合这种对称上下文需求。

我在实际使用中还有一个朴素感受:BiGRU对序列长度不算太敏感,但训练开销比单向GRU明显增加。如果每类样本只有一两千条,可以优先选单向GRU做初步验证,把整个模型的训练快速跑通,确认数据管线和超参数没有大问题,再替换成BiGRU提精度。这样能节省很多调试时间,也避免一开始就把网络拖进长序列的矩阵运算里。

3.3 先卷积后GRU的顺序,为什么是更好的选择

确实存在两种设计思路:一种是把原始时频图直接输入双向GRU,让循环网络自己学时空关系;另一种是先用卷积提取局部特征,再交给GRU建模时序。前一种看起来更“端到端”,但从参数效率和训练稳定性看并不划算——时频图动辄几十×几百个点,如果直接喂给循环网络,相当于一进GRU就要处理几百个时间步,每个时间步的输入维度也非常高,计算量成倍上涨,收敛速度明显变慢。

先卷积后GRU的设计,用卷积层把原始图像压成了“时间轴×特征维度”的序列,每一帧的特征已经被局部感受野提炼过,不再需要循环网络去逐像素构图。这既降低了GRU处理序列长度带来的负担,也让循环网络的注意力集中在时间关联上,而不是浪费在低层纹理识别上。这也是我在多次消融实验后确定下来的结构:卷积组负责空间特征的识别,GRU负责时间依赖的整合,职责边界非常清晰。

4. MATLAB实现:把WMSST和MCNN-BiGRU组装成可跑管线

4.1 数据预处理与样本库构建

实现的第一步不是搭网络,而是把原始振动信号切成样本、转成时频图。原始采集数据一般很长,动辄几十秒甚至几分钟,直接整段送入网络不现实。常规做法是用滑动窗口切段。我一般选取2048个采样点作为一个窗口,重叠率设置成50%,这样既能保证每段包含足够的冲击周期,又能增加样本数量。采样率如果你的数据是12kHz,2048点对应约0.17秒,低速轴承40Hz左右的转频也能覆盖几个周期,再低就需要加长窗口。

切完窗之后,每个样本波形做去均值和去趋势,防止直流漂移干扰时频变换,然后送入WMSST生成时频图。这里我提供了一个模块化的思路:对不同频带分段调用同步压缩函数,最后合并成多通道图像。用MATLAB写出来大致是这样的核心骨架:

function im = wmsstToImage(sig, fs, freqBands) % sig: 单个样本的振动信号 % fs: 采样频率 % freqBands: 形如 [f_low f_high] 的频带矩阵 [sst, f] = wsst(sig, fs); % 同步压缩小波变换 bandImgs = {}; for k = 1:size(freqBands, 1) idx = f >= freqBands(k,1) & f <= freqBands(k,2); band = abs(sst(idx, :)); band = log1p(band); % 对数能量刻度 band = imresize(band, [64 64]); % 统一尺寸 band = mat2gray(band); bandImgs{k} = band; end im = cat(3, bandImgs{:}); % 多通道图像 end

这里有几个容易踩的点。wsst返回的频率轴顺序是升序,索引切片时要确认传递的边界不会越界;不同MATLAB版本对同步压缩函数的调用方式有细微差别,比如有的版本还要求指定小波名,运行前用help wsst确认一下本地签名最稳妥。imresize把不同频带的时频矩阵统一缩放成相同尺寸,是为了后级卷积层能够接受固定大小的输入;如果你愿意保留原有频率分辨率,也可以不缩放,但网络输入层尺寸要对应调整。我在实验里统一缩到64×64,内存开销小,训练速度快,精度损失可以接受。

4.2 MCNN-BiGRU网络搭建要点

在MATLAB的深度学习工具箱里,可以直接用层数组和层图构建这个网络。输入层使用imageInputLayer([64 64 3]),三通道对应上面生成的三频带图像。三个卷积分支分别用3×3、5×5、7×7的卷积核,每个分支32个滤波器,padding保持尺寸不变,输出特征图沿通道拼接。拼接后接一个maxPooling2dLayer(2, 'Stride', 2),把空间尺度减半。

关键一步是让特征图能够进入BiGRU。MATLAB如果当前版本没有直接的双向GRU层,可以用两个GRU层拼接——一个按时间正向处理,另一个先把序列翻转再处理,最后把两个方向输出融合,等价于双向GRU。更省事的是使用bilstmLayer作为替代方案,BiLSTM和BiGRU在诊断场景下精度接近,但BiLSTM参数更多、训练更慢。做法上提供参考:

% 以层图方式搭建关键分支 lgraph = layerGraph(); lgraph = addLayers(lgraph, [ imageInputLayer([64 64 3], 'Name', 'input') ]); % 分支1:小卷积核 lgraph = addLayers(lgraph, [ convolution2dLayer([3 3], 32, 'Padding', 'same', 'Name', 'conv3x3') batchNormalizationLayer('Name', 'bn3x3') reluLayer('Name', 'relu3x3') ]); % 分支2:中卷积核 lgraph = addLayers(lgraph, [ convolution2dLayer([5 5], 32, 'Padding', 'same', 'Name', 'conv5x5') batchNormalizationLayer('Name', 'bn5x5') reluLayer('Name', 'relu5x5') ]); % 分支3:大卷积核 lgraph = addLayers(lgraph, [ convolution2dLayer([7 7], 32, 'Padding', 'same', 'Name', 'conv7x7') batchNormalizationLayer('Name', 'bn7x7') reluLayer('Name', 'relu7x7') ]);

拼接层之后,再用自定义的序列变换层把特征图重整为时间序列形式,输入到GRU模块,最后接全局池化、全连接层和softmax层。这里有个建议:不要一开始就把网络做得很深,先把一个浅版、小卷积核版跑通全流程,确认数据加载、标签对齐、损失计算都没问题,再逐步加深加宽。我见过太多同学一上来搭建一个上百层网络,训练时才发现读取数据环节就错了,浪费大量时间。

4.3 关键参数的选择参考

整个模型里需要关注的参数不少,我把一组比较通用的初始配置整理成表,供初次复现时参考。没有绝对最优的参数,这张表的价值是让你有一个不翻车的起点。

模块参数项初始建议值说明
数据单样本点数2048覆盖足够冲击周期且不过长
数据滑动重叠率50%增加样本量并保持连续性
WMSST频带分段3段过低/高频段分开压缩
WMSST时频图尺寸64×64内存与精度的折中
MCNN分支卷积核3×3 / 5×5 / 7×7覆盖不同尺度
MCNN每分支滤波器数32浅层特征量够用
BiGRU隐藏单元数128序列建模能力与开销平衡
训练初始学习率1e-3过大会导致震荡
训练批大小64适应中低显存环境
训练Dropout0.3降低过拟合风险

初次跑通后,可以优先对两个参数做调优:一是时频图尺寸,它直接影响模型输入的信息量,64增加到128通常会带来1~2个百分点的精度提升,但训练时间可能翻倍;二是GRU隐藏单元数,128增加到256会对复杂故障模式更友好,但小样本下容易过拟合,需要同时增强Dropout和早停策略。

5. 实测对照与复现踩坑:准确率之外还要看什么

5.1 四组对照实验,我实际观察到了什么

我在一个轴承振动实测数据上做了一组消融对照,数据包含正常、滚动体故障、内圈故障、外圈故障四种状态,每种状态约1500个样本,训练集和测试集按7:3随机划分。四组实验分别是:原始波形+CNN、STFT时频图+CNN、WMSST+MCNN(去掉循环网络)、WMSST+MCNN-BiGRU完整结构。结果大体符合预期。

方法测试准确率模型体积训练耗时
原始波形+CNN92.4%小短
STFT时频图+CNN94.8%中中
WMSST+MCNN(无GRU)95.7%中中
WMSST+MCNN-BiGRU97.8%中大较长

最有价值的不是最后那组绝对数字更高,而是差异来源:从STFT换成WMSST,提升约0.9个百分点;加上BiGRU又提升约2.1个百分点。BiGRU带来的增益明显大于更换时频表示方法,说明在这类数据上,时间上下文建模的收益被低估了。很多人以为特征提取主要靠CNN,循环网络只是“锦上添花”,实验数据显示这其实是“半壁江山”。

我还专门看了一眼混淆矩阵,发现绝大多数错误集中在内圈故障和滚动体故障之间。原因也好理解,这两种故障的冲击都受到滚动体公转位置调制,时频形态高度相似,单靠时频能量分布不容易区分,需要更加精细的相位关系信息。这个观察提示我,后续改进方向应该是如何在WMSST阶段保留部分相位信息,而不是继续盲目增大网络宽度。

5.2 排查链路:训练loss反弹和验证集震荡

复现过程中最容易遇到的问题,就是训练loss持续下降但验证集准确率剧烈震荡。我第一次跑这个网络也撞上了。当时的现象很典型:前5轮loss稳步下降,准确率缓慢爬升,到第8轮突然验证准确率掉到50%以下,下一轮又弹回90%以上,整个验证曲线像锯齿。

我按顺序排查了四个环节。第一步看数据划分,确认训练集和测试集是否有重叠窗口,如果滑动窗口重叠率太高,相邻样本高度相关,随机划分会造成严重的数据泄露,表现为训练准确率虚高、验证波动大。把重叠率降到50%以下,并按连续时间段划分而不是随机样本划分后,情况缓解很多。第二步看学习率,1e-3配合Adam在大多数情况下稳定,但如果batch比较小,Adam在后期容易出现震荡,我先把学习率调到5e-4试试。第三步看梯度,loss如果出现NaN,说明梯度爆炸,给GRU加梯度裁剪或降低学习率可以解决。第四步看类别均衡,四种状态样本数量如果差异大,网络会偏向多数类,小类在验证集上表现时好时坏。

我把这四步做完,验证曲线就稳定了。这个排查顺序值得记下来:数据泄露永远优先于网络结构问题,因为结构再调也不能弥补训练集和测试集互相“透题”。

5.3 两个内存相关的大坑

第一个坑:全量数据一次性转成时频图放进内存。假设你有6000个样本,每张时频图64×64×3的float32数组,算下来不过300MB左右,看起来不多。但如果把时频图分辨率提升到256×256,这个数字就涨到4.7GB,再加入中间变量,很容易把普通电脑的内存和显存同时打爆。我的建议是设定一个样本池,训练时按批实时生成时频图,或者提前转成uint8格式存到磁盘,训练时再转回float类型。损失一点精度,换来的是容量的大幅提升。

第二个坑:序列长度不一致导致BiGRU无法批量训练。不同样本的时频图宽度如果因为信号长度不同而不一致,送入循环网络时每个batch内的序列长度就参差不齐,MATLAB会直接报错。解决办法是在数据预处理阶段统一窗口长度,保证所有样本的时频图宽度一致;如果网络要支持变长序列,就得用掩码机制,但工程上没必要为诊断任务支付这个复杂度。

6. 最后分享几条工程化建议

这套WMSST加MCNN-BiGRU的结构,在我目前做过的几个诊断项目里,稳定性和精度都让我满意,但工程落地时还有几件事容易被文档忽略。

第一件是时频图和多通道的设计不要做成“死配置”。不同工况下,故障特征的载波频带会变化,比如转速从800转到3000转,共振频带往往也会漂移。建议把WMSST的频带范围做成可配置参数,布置系统时先用少量样本做一次频带搜索,再固化到本组工况里。不要指望一套频带万能适用。

第二件是不能只看总准确率。实际故障诊断中,不同故障类别的代价完全不同:漏报一个内圈故障可能造成整台设备报废,而多报一次滚动体故障只是停机检查的损失。我在报告中除准确率外,还固定输出每个类别的召回率和误报率,必要时在损失函数里给少数类或高代价类加权,比事后调阈值有效得多。

第三件是模型部署前一定要做输入扰动测试。现场信号和实验室数据有区别,会混入工频干扰、瞬态噪声甚至传感器碰撞。输入稍有扰动,如果网络输出剧烈切换,那模型很难在现场可信。我一般会在测试集里额外加几组带噪样本,观察模型输出的类别概率是否平滑变化;如果某个概率在0.4到0.6之间跳来跳去,说明特征边界过于脆弱,考虑退回上一级去检查时频图是否包含了过多的环境噪声。

第四件是把这个结构继续扩展的方向。WMSST提供的是二维时频表示,MCNN处理空间结构,BiGRU处理时间依赖。同样的骨架,完全可以把输入从振动信号换成品味相似的声发射信号、电流信号,只需要重新标定频带范围。后续如果拿到多传感器数据,把不同传感器的时频图堆成更深的通道,网络结构几乎不用改,诊断的鲁棒性还会有明显提升。

做故障诊断这么久,我的体会是:方法不在多,而在于每个环节是否真的对准了物理本质。时频变换解决的是“故障特征在哪里”的问题,多尺度卷积解决的是“以什么视角看特征”的问题,双向门控循环解决的是“特征前后的因果怎么串”的问题。三件事想透了,网络结构自然立得住,实际跑数据也不会飘。

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

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

立即咨询