
做故障诊断这几年我一直在折腾各种信号处理和深度学习搭伙的路子。今天要聊的这个项目——基于WMSST结合MCNN-BiGRU的故障诊断研究算是我近期比较满意的一套方案。简单说就是用改进的时频分析方法WMSST把振动信号变成高质量的二维时频图再喂给多尺度卷积加双向门控循环单元的网络做特征提取和故障分类。这套组合的好处在于它同时抓住了故障信号在频域上的瞬态特征和时域上的变化规律比单用CNN或者单用RNN都更稳。适合正在做旋转机械故障诊断、轴承齿轮箱状态监测或者想把手里的深度学习工具箱用起来的工程师和研究生。下面把我整个实现过程、踩过的坑、还有代码里那些容易懵的参数全部拆开讲清楚。1. 项目概述与核心思路拆解1.1 为什么是WMSST而不是直接用原始信号很多做故障诊断的朋友一开始都会问为什么不直接把原始振动信号扔进网络我的回答是可以但效果通常打折扣。原因在于原始一维振动信号里的故障特征往往非常微弱特别是早期故障冲击成分被背景噪声淹没直接做端到端学习网络很难自动学到那种细微的周期性冲击规律。而且一维信号对网络结构限制很大很多现成的图像领域预训练模型都派不上用场。把信号变换成二维时频表示相当于替网络做了一次特征预提取。传统的短时傅里叶变换STFT时频分辨率受窗函数制约小波变换虽然多分辨率了但在高频段能量还是会发散。WMSST多尺度同步压缩变换的做法比较巧妙它对信号做连续小波变换之后再对尺度方向进行重排压缩把模糊的能量重新“压”回瞬时频率曲线附近得到的结果时频聚焦性极好。尤其对滚动轴承的故障冲击信号能够在时频图上看到非常清晰的脊线这种质量直接决定了后面网络能不能学出高区分度特征。实际跑下来我对比过STFT、小波和WMSST三种方式喂给同一个分类网络WMSST在故障模式区分度上的优势很明显特别是外圈故障和内圈故障这种容易混叠的模式WMSST时频图上呈现出完全不同的冲击分布形态网络分类的置信度显著提升。1.2 这套方案解决了什么问题故障诊断场景里最难处理的三个问题这套方案都做了针对性设计第一个是故障特征微弱和噪声强的问题。WMSST的时频聚集特性把冲击能量集中了再加上MCNN里不同尺度的卷积核并联结构相当于用多个“放大镜”同时看不同频带的细节微小冲击特征也不容易漏掉。第二个是时序依赖问题。滚动轴承的故障信号并不是孤立的冲击而是有规律的周期冲击序列。单一时刻的时频图只能反映“有没有冲击”无法反映“冲击之间的节奏关系”。BiGRU就是干这个的它从双向提取时间维度的上下文关系捕捉冲击的周期性规律这对区分不同的故障类型非常关键。第三个是计算效率问题。纯Transformer或者很深的CNN网络模型参数动辄几百万工业现场一台普通工控机很难跑实时。MCNN-BiGRU组合起来的参数量适中训练收敛速度快部署也不挑硬件。我实测在普通配置的台式机上跑一次完整的训练流程三十分钟左右就能完成比同规模的纯CNN模型能省下十分之一的训练时间。所以这套方案的定位很明确面向工业现场可落地、数据量不大、但要求诊断结果可靠稳定的场景用精心设计的特征提取和适度的网络结构解决实际问题。2. 核心原理深度解析2.1 WMSST时频分析的工作机制WMSST的核心思想简单说就是对频率轴做“再分配”。传统SST已经做了一步频率重排但它在处理强时变信号和多分量信号时会出现能量错位的问题。WMSST引入了多尺度分解的思想先用不同尺度的小波基分解信号然后在每个尺度内部做同步压缩最后把不同尺度的结果融合起来相当于在不同频率区域用不同的分辨率去刻画信号。代码实现里这一步直接关系到时频图质量的两个核心参数是小波基类型和尺度数。我试过cmor复Morlet小波和mexh墨西哥帽小波复Morlet的结果对冲击特征更敏感建议不管用什么工具箱都优先考虑它。尺度数不是越多越好我用128~256之间的值效果比较理想太小了频率分辨率不够太大了计算量上去了但增益有限。WMSST输出的时频矩阵维度一般比较大直接放进网络会导致输入层过大训练也很慢。我的做法是先把时频图做归一化再缩放到统一尺寸。这里有个细节缩放时尽量保持时频图的长宽比不变先缩放再裁剪不要直接拉伸变形可以保留原始频率结构的完整性避免特征畸变。2.2 MCNN-BiGRU网络结构设计MCNN部分借鉴了多尺度特征融合的思想用多个不同尺寸的卷积核并行处理同一张时频图。比如我用的三路结构卷积核大小分别是3×3、5×5、7×7。小卷积核擅长捕捉局部细节大卷积核能覆盖更宽的频率范围三路输出在通道维度上拼接起来形成了对故障模式的多角度描述。有人可能觉得多尺度卷积和平凡的多通道CNN没什么区别实际差别很大。并行多尺度提取的特征在语义上是互补的小卷积核稳住局部冲击细节大卷积核抓全局频率分布全局和局部结合才能对故障状态的描述更立体。如果只用单一卷积核诊断准确率大约会下降两三个百分点在强噪声环境下差异会更明显。BiGRU放在CNN后面作用对象是CNN提取出来的特征序列。GRU相比LSTM结构更精简参数更少在这个任务上不容易过拟合。双向结构的价值在于某一时刻的特征往往既和前面几个时刻的冲击有关联也和后继时刻的冲击模式有呼应。轴承故障的周期性冲击信号有很强的前后关联双向GRU能同时利用两个方向的信息提升故障类型判别的鲁棒性。我在设计网络的时候没有把BiGRU层数加很多一层就够用了。堆叠两层BiGRU并没有显著提升精度反而让训练时间增加了将近三成。这类故障诊断任务的数据量本身不大一个工况几千个样本很正常网络结构的复杂度是够用就好。2.3 为什么CNN和BiGRU能协同工作有的朋友疑惑CNN提取的是二维特征BiGRU要的是一维序列两者怎么对接答案就是特征重排。CNN的输出是三维张量我把空间维度合并把通道数调整到GRU要求的时间步长度。这就像排积木一样将一摞积木时频图的空间结构拆成一列积木堆沿时间轴展开的特征序列保持每个时刻内部的通道特征不变。这种方式保留了CNN提取的局部特征之间的时间序列关系。故障信号本身就是沿时间轴展开的拆出来的序列天然保持了冲击的时序顺序BiGRU在处理这种序列信息时才能发挥出优势。训练阶段我曾尝试过把特征直接拉平再全连接虽然也能收敛但测试集的准确率比经过BiGRU的低了大概一个百分点验证了时序信息对诊断确实有帮助。3. 实操流程与关键环节实现3.1 整体流程框架整个项目实现分为五个环节。数据预处理是基础WMSST时频变换是特征预提取数据集构建决定了训练质量网络模型搭建是核心训练评估是最终检验。每个环节设一处出错后面模型的结果都会受影响。数据预处理的第一件事是信号分段。原始振动信号是连续采集的长序列需要按一定的长度切成样本。我的经验是每段至少包含故障冲击周期的十到二十倍长度这样网络才能看到足够多的冲击循环。轴承转速、故障特征频率可以直接用来估算这个长度。切完之后要再做归一化把幅值缩放到零到一区间否则信号幅值不同网络收敛速度会受很大影响。时频变换前需要把每个样本信号转成WMSST时频图。这一阶段所用的工具箱可以从网上获取常见音频处理工具库核心代码是利用小波变换和同步压缩的封装函数。在Matlab环境中处理批量数据时可以写一个循环函数要注意使用并行计算同一批次样本会被分块处理处理速度大约能提升三到四倍。3.2 数据集划分和训练策略数据集的划分不能简单随机切分。故障诊断里最常犯的错误就是同一段连续信号被拆进了训练集和测试集模型在测试集上的表现虚高部署到现场就失灵。我的处理方式是先把原始信号按时间顺序切分好再按比例从不同工况、不同时段下抽取样本确保每个类别在训练和测试中都均匀分布。常用搭配是训练集、验证集、测试集的比例在七比一点五比一点五上下效果比较均衡。训练时的关键参数要仔细计算。输入尺寸我设置为224×224的二维时频图批次大小Batch Size设为32初始学习率0.001使用Adam优化器训练轮数是三十轮。过早停止用验证集的准确率作为指标进行连续验证准确率不再提升时就可以提前结束训练可以有效避免后期过拟合。训练过程中要实时监控训练集和验证集的准确率曲线。如果训练集准确率一直涨但验证集一直不涨说明过拟合了需要加正则化或者降低学习率。如果两者都低可能是网络没有充分拟合尝试增加训练轮数或微调网络结构。3.3 核心代码模块说明项目用Matlab实现主要模块包括预处理模块读入振动信号完成去均值、去趋势、归一化、分段操作。这个模块不难但直接影响后续质量我见过太多因为忘了去均值导致时频图上多了一条直流线干扰的情况这一点值得留意。时频变换模块封装WMSST函数输入是一维信号输出是二维时频矩阵。这里要注意输出尺寸的一致性不同长度的信号会生成不同尺寸的时频图导致无法直接批量送入网络需要统一缩放到固定尺寸。网络搭建模块主要依赖深度学习工具箱的层API来搭建MCNN和BiGRU结构。多尺度卷积并行结构可以使用多分支设计分别定义不同尺寸的卷积层最后拼接在一起。BiGRU则使用双向GRU层注意设置合适的隐藏层单元数和丢掉比率。评估模块测试集上计算混淆矩阵输出每种类别的精确率、召回率和F1分数。宏平均F1值更能反映整体诊断水平的真实情况我在文中报告的结果都是以宏平均F1为准的。3.4 参数选择与计算过程示例以我们最常碰到的滚动轴承故障数据模拟任务为例我们采集信号设定了一段转速条件的样本数据。首先根据轴承几何参数计算故障特征频率基于滚动体数目、滚动体直径等数据估算得到外圈故障特征频率是大约一百零几赫兹相应的冲击周期约为几十毫秒的量级。采样率为十千赫兹每个样本截取两千个点大约对应了二十个完整的冲击周期基本满足了网络学习时序规律的需要。我前后对比过样本长度为一千点和四千点的效果一千点的时候冲击周期太少BiGRU学到不到稳定的冲击节奏准确率只有九成出头四千点虽然准确率略有提升但训练耗时明显增加了。两千点是性价比比较高的选择。每类故障样本数我设定在两千个以上四类故障总共八千多个样本配合数据增强手段对这个规模和结构的网络来说已经够用。数据增强方面我用了加噪和时序错位两种方式只在训练集上用测试集保持原始数据这样可以更真实地反映模型面对新数据时的表现。4. 常见问题与排查技巧实录4.1 故障速查表以下是实际操作中最常遇到的几个问题我按现象、原因、解决办法三个维度列成一个速查表遇到问题可以先对照检查一番问题现象可能原因解决办法训练损失不下降学习率设置过大或网络初始化不佳降低学习率到0.0001或换用Xavier初始化时频图模糊不清小波基选择不当或尺度数过少换成复Morlet小波适度增大尺度数验证集准确率高于训练集训练集和测试集数据划分不当按时间顺序严格切分确保各类分布一致训练集过拟合严重模型复杂度超出数据量承受能力增加Dropout概率减小BiGRU隐藏层单元数混淆矩阵中两类故障混淆严重两类故障的时频特征过于接近区分度不足先加数据增强再考虑增加特征通道测试数据上表现大幅下降训练时数据分布和现场数据分布不同检查信号是否经过相同的预处理和归一化方式4.2 噪声干扰的经验教训实际工作里最头疼的不是模型本身的问题而是环境噪声。实验室里采集的样本干净漂亮到了现场各种工频干扰、杂散噪声全来了。我刚开始做项目的时候单纯按实验室的标准去做结果一上现场数据准确率直接掉了十几个百分点。后面摸索出来的办法是训练时的域随机化。在输入到WMSST之前对原始信号叠加不同信噪比的白噪声和窄带干扰信噪比范围从高到低都覆盖到把噪声扰动作为训练数据的一部分。这种方式让网络见过各种“脏”信号部署到现场后准确率的下降幅度可以控制在几个百分点以内稳定很多。另外建议测试时也留一部分带噪声的数据专门评估模型的鲁棒性。最终报告的诊断精度要区分“实验室纯净数据精度”和“带噪数据精度”这样心里有数汇报数据也更有说服力。4.3 数据不均衡的处理方法工业场景下故障数据永远比正常数据少这个坑避不开。通常处理数据不均衡有三种思路采样法、损失函数法和生成法。我的经验是优先尝试对少数类过采样和对多数类降采样的组合简单有效且不容易引入额外复杂度。这里要提醒一下过采样不能简单地复制少数类样本而是要做数据增强生成新的变体。对称翻转、加噪、时频图小块遮挡等方法都可以用。之前见过有人直接复制样本填少数类导致验证分数看上去不错但泛化能力很弱这种情况要尤其小心。如果采样策略还解决不了可以考虑用加权交叉熵损失函数给少数类更高权重。权重设置可以根据训练集中各类样本数量的倒数来定。类别数量差异在十倍以内时加权损失的效果不比费劲做生成模型的效果差而且是完全确定性的不会引入生成模型的随机干扰。4.4 代码层面的几个细节Matlab环境下做这套项目有几个容易踩的坑值得单独提一下第一GPU和CPU切换时模型可能不可复现。深度学习工具箱里的一些操作存在不确定性要在训练前设置随机数种子并且在相同环境下重复跑三次取平均结果报数这样报告里的指标才经得起复现。第二时频变换是计算密集操作如果有上百个样本单线程跑一批数据会非常耗时。我在实际处理大批量数据时用到了并行处理配合内存优化整体速度能提升到原来的几倍。但要注意并行池的内存溢出问题分块处理比一次性全部塞入更稳妥。第三保存模型时要把数据预处理参数一并保存起来。部署时加载模型后如果预测数据没做一模一样的归一化准确率会很难看。这个坑我踩过一次后来规规矩矩把信号的均值、标准差随模型打包保存才彻底解决。5. 一些体会与扩展思考个人实际做下来的感受是这套方案的难度不在于单个技术点有多前沿而在于把信号处理那一套和神经网络这一套真正协同起来。很多做信号的人网络学习不够深很多做深度学习的又不懂信号分析。能把两边都吃透的人项目推进效率会高很多。这套框架还有一个很自然的扩展方向迁移学习。在数据量不足的时候可以先在一个大而全的数据集上预训练网络再在自己的小数据集上微调对故障诊断也能带来明显的增益。我们已经验证过类似思路这样即使现场只有几十分钟的振动数据也能拼出一个可用的诊断模型。最后分享一个小技巧训练结束后除了看准确率我还习惯把网络中间层的特征提取出来做一版特征可视化通常用降维算法把高维特征压到二维平面看看不同故障类别的样本是否在空间上分得开。如果分不开说明前面某个环节还有问题这时候回头去检查时频图的质量可能会发现问题比想象中早得多。这套“可视化反查”的习惯能帮你省下很多无效调试的时间建议每个做故障诊断的人都试试。