做故障诊断的同行应该都有体会,拿到一段振动信号,最头疼的不是“信号不够”,而是“特征不会提”。尤其是滚动轴承、齿轮箱这类旋转机械,故障特征往往埋在强背景噪声和非平稳成分里,你直接在时域上看波形,毛刺一堆看不出名堂;做FFT看频谱,又经常和转频、倍频、边频搅在一起,根本分不清哪条谱线代表故障。这几年深度学习的路子火起来之后,我见过不少朋友上来就把原始一维振动信号直接丢进CNN,或者简单做个小波变换就塞给网络——效果不能说没有,但一旦换了工况、换了转速、换了负载,模型泛化能力就崩。我自己踩过这个大坑之后,才开始认真琢磨一个思路:信号预处理能不能做到“时频兼顾、细节不丢”,特征提取能不能做到“多尺度捕捉、双向建模”,把两者串成一个完整的诊断链路。
这篇文章想聊的,就是一套我自己在MATLAB里完整复现过的方案:用离散韦格纳分布(DWVD)先把振动信号映射成二维时频图,再用MCNN-BiGRU——也就是多尺度卷积神经网络和双向门控循环单元的混合结构——来自动提取时频图里蕴含的故障特征,最后完成故障模式分类。题目缩写是DVMBiGRU,说白了就是DWVD + MCNN + BiGRU的串联组合。这套东西适合正在做故障诊断方向课题、需要出实验结果的硕博生,也适合企业的设备健康管理工程师想搭一套故障识别基线模型。我会把每个环节的选型原因、参数设置依据、MATLAB实现思路、以及我实际调试过程中踩过的坑全部展开,争取让你看完之后能直接在自己的数据上复现出来。
1. 整体设计与思路拆解:为什么选DWVD+MCNN-BiGRU
1.1 故障诊断里信号处理那点事:纯时域和纯频域为什么不够用
旋转机械的故障信号,本质上是一个典型的非平稳、非高斯过程。轴承外圈剥落、内圈裂纹、滚动体点蚀,每一种故障都会在信号中激起周期性瞬态冲击,但冲击出现的时刻是随机的、强度是变化的,而且淹没在齿轮啮合振动、轴系不对中、环境噪声这些背景成分里。你要是只拿均方根值、峰值因子、峭度这类时域指标去看,它们对早期微弱故障的敏感度很低;你要是只做频谱分析,边频带的分布能告诉你调制关系,但瞬态冲击对应的宽频带能量往往被平均掉了。
时频分析存在的意义,就是把一维的时间序列展开成一个二维的时间-频率平面,让“哪个时刻出现了什么频率成分”这件事变得可观测。短时傅里叶变换(STFT)最简单,但窗函数一旦定死,时间分辨率和频率分辨率就互相卡脖子;小波变换能自适应多分辨率,但小波基函数的选择主观性很强,选错了基函数,特征就歪了;经验模态分解(EMD)不依赖基函数,可模态混叠、端点效应这些问题处理起来非常头疼。
这也是为什么我后来把目光放到了Wigner-Ville分布(WVD)这条线上。WVD属于科恩类时频分布,它最大的优点是没有窗函数的概念,时频分辨率理论上是极限水平——对瞬时频率的变化跟踪能力极强。但WVD也有个臭名昭著的缺点:对于多分量信号,交叉项干扰严重,时频图上会出现一堆虚假的能量峰值,直接把真实故障特征给遮住。离散韦格纳分布(DWVD)作为WVD的离散化版本,处理的是数字采样序列,能够直接在MATLAB里通过矩阵运算实现,而工程上通常结合平滑窗来压低交叉项干扰。这套方案选DWVD,核心逻辑就是:用接近极限的时频分辨率换取“瞬态冲击出现的时刻和频带范围”这两个关键信息,再靠后续的深度网络去自动学习时频图里的判别性模式,而不是靠人眼去分辨图上哪块是故障哪块是交叉项。
1.2 MCNN和BiGRU各司其职:多尺度特征与时间上下文
时频图生成之后,接下来面临的是一张二维图像。图像类数据最顺手的工具就是CNN,但这里有一个细节值得琢磨:CNN的卷积核尺寸直接决定了“看多宽的局部模式”。故障冲击在时频图上往往表现出不同的宽窄形态——早期微弱故障的能量团又小又淡,后期严重故障的能量带又宽又亮;齿轮啮合频率及其谐波成分在图上呈现为水平长条,而轴承故障的共振频带则呈现为竖直的窄带调制结构。
单一尺度的卷积核很难同时对付这些形态差异巨大的模式。你选了3×3的小卷积核,局部细节能抓住,但整体的频率带结构感受野不够;你选了7×7的大卷积核,整体分布看到了,局部细节又糊了。MCNN的思路就是不走单一路线,而是开三个并行分支,分别用不同尺寸的卷积核去扫同一个时频图,每个分支看到的是不同尺度下的特征视图,最后把三个分支的结果拼在一起,得到一个“既看细节又看全局”的多尺度特征表达。
但到这里还没完。时频图还有一个特殊性:它的横轴是时间,纵轴是频率,而旋转机械的故障信号在时序上有明显的先后依赖关系。某个频率成分在t1时刻出现后,往往会以衰减振荡的形式持续一小段时间;轴承外圈故障的冲击是周期性重复的,每次冲击之间的时间间隔本身就携带了故障信息(对应故障特征频率)。这种时间上的前后文关联,纯CNN处理得并不好——卷积操作本质上是空间局部加权求和,它对“相隔很远的时间点之间有什么联系”缺乏建模能力。
这时候就到了BiGRU上场的位置。GRU是门控循环单元的一种精简变体,通过更新门和重置门来控制信息的保留与遗忘,比LSTM参数更少、训练更快,在不是特别长的序列建模任务里表现非常稳。但单向GRU只能从前往后看,也就是只能利用过去的信息来推断当前状态;而故障信号的某些特征,往往需要结合“后面的信号”才能确认前面的判断——比如一个冲击之后的衰减尾巴,你只看着冲击点看不出问题,还得看到尾巴的形状才能判断这个冲击是故障引起的还是噪声偶然冒出来的。BiGRU就是正向反向各跑一个GRU,然后把两个方向上的隐状态拼接起来,相当于每个时刻都能同时利用它之前和之后的上下文信息。把MCNN输出的多尺度特征按时间轴展开、送入BiGRU,就等于在空间特征之上叠加了一层时间上下文建模。
1.3 “参数共享+特征融合”的整体设计逻辑
整个网络结构设计里,有一个细节值得单独拎出来说:DWVD时频图的分辨率通常不会太大,比如我这里默认设置的是224×224。如果直接把整张图拉成一个长向量去接全连接层,参数量会爆炸,而且会丢失空间结构。MCNN的三个并行卷积分支,卷积核尺寸不同,但它们共享同一份输入数据,也就是共享同一张时频图——这是一种天然的多视图参数共享设计。不同分支在各自感受野下提取的特征,最后在通道维度上拼接,形成新的特征张量。
拼接之后的特征还不能直接进分类器,因为卷积输出的特征图仍然带有时间维度结构。这里有两个选择:一是全局平均池化,把特征图压成一个一维向量,直接进softmax分类器;二是把特征图的每一列看成“某个时间点上的多频率特征向量”,按时间顺序组成一个序列,送进BiGRU做上下文建模,再把BiGRU的所有时间步输出做聚合。我实际测试下来,第二种方案的分类准确率更高,尤其是在强噪声背景下,BiGRU帮了大忙——因为故障冲击在时间上的周期性被显式建模了,而不是靠CNN卷出来的隐式相关性硬扛。
完整链路串起来就是:原始振动信号 → 滑动窗口分段 → DWVD变换生成时频图 → 三尺度CNN并行提取空间特征 → 特征拼接 → BiGRU双向提取时间上下文 → 全局池化 → 全连接+Softmax分类输出。每一步的输入输出都是规整的张量,在MATLAB里可以清晰地逐层搭建。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心细节解析与实操要点
2.1 DWVD的离散化实现与交叉项抑制:核心参数怎么定
DWVD的数学本质是信号瞬时自相关函数的傅里叶变换,离散化之后,对于长度为N的信号序列x[n],DWVD谱的近似计算可以写成对滞后变量m做FFT的形式。很多人在这一步直接就上手写了,但忽视了两个关键问题:第一是窗函数的选择,第二是交叉项到底怎么压。
WVD的交叉项来源于多分量信号不同频率成分之间的“互相关”。工程上最常用的压制手段是加平滑窗——在时域方向和频率方向分别做卷积平滑,这就是所谓的“平滑伪WVD”。代价是时频分辨率会被牺牲一部分,但换来了可读性的大幅提升。我的实际经验是:对于轴承振动信号这类瞬态成分突出的信号,平滑窗的宽度不要设得太大,取信号采样点数的1/16到1/8比较合适。窗太宽会把瞬态冲击在时域上抹开,看起来“故障特征消失了”;窗太窄,交叉项压不住,时频图上全是干涉条纹,网络同样学不到干净的特征。
在MATLAB里实现DWVD,我不建议你自己用循环嵌套去算自相关和FFT,那样效率低到让人崩溃。数据量一大,几百兆的数组循环叠两层,MATLAB直接变蜗牛。正确做法是先把信号按滞后变量排列成矩阵,再一次性做矩阵点乘和FFT运算。核心逻辑是这样:对每个时间点n,构造关于滞后量m的序列,乘上窗函数,然后对该序列做FFT得到该时刻的频谱切片。把所有时刻的切片拼起来,就得到完整的时频图。采样率、滞后范围、窗函数长度这三个参数之间要配合:滞后范围决定了频率分辨率的上限,它受到信号长度和FFT点数的约束;窗函数长度则直接影响交叉项抑制的程度。
信号长度方面,我建议每个样本截取1024或2048个点。截太短了,FFT的频率分辨率不够,低频故障特征频率和转频可能混在一起分不开;截太长了,单个样本的计算时间拉长,训练数据量也被稀释。1024点配512点FFT,频率分辨率足够看轴承故障特征频率在低频段的分布,同时单个样本的DWVD计算在普通台式机上只要几十毫秒,批量预处理一万个样本也是分钟级的事。
2.2 多尺度卷积网络MCNN:分支设计与通道数配置
MCNN的三个分支,我建议的卷积核配置是:分支1用小卷积核3×3,负责捕捉时频图上的精细纹理;分支2用5×5中卷积核,负责中等尺度的局部模式,比如调制边频带结构;分支3用7×7的大卷积核,负责整体能量分布区域,覆盖较宽的频带和较长的时间跨度。每个分支内部连续叠两层卷积,中间夹ReLU激活函数和批归一化(BatchNorm),防止梯度消失的同时加速收敛。
通道数从32开始起步,逐层翻倍到64,再翻到128。这样设计的理由是:浅层表达的是边缘和纹理这类低层特征,通道数不需要太多;深层要编码“故障为哪种模式”这种抽象语义,需要更多的通道来容纳不同类型的组合特征。三个分支最终各输出一组特征图,用深度拼接(cat)操作把它们在通道维度上并在一起。拼接这一步在MATLAB里有现成的函数,但要注意:三个分支输出的特征图宽高必须一致,否则拼接直接报错。这要求你在设计卷积层时提前算好padding——最省事的办法是每一层都保持输入输出尺寸不变。
还有一个小细节特别值得留意:多尺度分支之间需要保证学习进度的大致同步。如果某个分支的卷积核数量特别多,梯度更新速度就会偏快,可能导致整个模型偏向某一尺度。我的做法是给每个分支加独立的批归一化层,让每个分支内部先把特征分布拉回标准范围,再进入拼接操作,能明显减少分支间的学习不均衡。
2.3 BiGRU的时间建模:输入格式与隐层维度取舍
MCNN输出的特征图,形状是H×W×C,H是高度、W是宽度、C是通道数。要把它送进BiGRU,得先决定“序列的切法”。我在项目里采用的做法是:把特征图按宽度方向切割,每一列作为一个时间步,这样序列长度就是W,每个时间步的特征向量长度是H×C。对应到时频图上,宽度方向本来代表的就是时间轴,所以这种做法正好和物理意义对齐——每个时间步对应原始信号的一个短时段,特征向量编码了这个时段里的时频信息。
隐层维度这个参数我很想多说一句,别迷信“越大越好”。BiGRU的隐层维度直接决定了时间建模能力的上限,但维度大了之后参数数量会显著上涨,训练时间变长,而且在小样本故障数据集上特别容易过拟合。我在实验里试过32、64、128三档,对于单通道时频图像输入,64是性价比最高的配置。隐层维度32精度会明显掉一截,128精度提升不到0.5个百分点,训练时间却翻了将近一倍。双向结构要注意它会把输出维度翻倍:正向64维加反向64维,拼接起来是128维,后续接全连接层时输入维度要对应好,别两处尺寸对不上。
2.4 融合策略:从特征拼接挤压到分类输出
拼接之后的特征向量,要先经过一个全局平均池化层,把维度压下来。这个池化操作等于把BiGRU所有时间步的输出取平均,得到一个固定长度的向量,再去接两个全连接层。全连接层的神经元数从256降到故障类别数,中间加Dropout(丢弃率0.3到0.5)来抑制过拟合。
关于池化,文献里还有另一种做法是只保留BiGRU最后一个时间步的输出来做分类。但我在实际对比中发现,全局平均池化比“取最后一步”效果更稳——尤其是信号存在相位偏移、冲击发生时刻在整个样本窗口内漂移的情况下。平均池化相当于让模型对“冲击到底具体出现在哪个瞬间”不那么敏感,更关注“整体时频结构是什么样的”,这在故障诊断场景里是非常合理的先验。最后一个全连接层的输出接Softmax,每个类别得到一个概率,取最大值对应的索引就是诊断结果。
3. 实操过程与核心环节实现
3.1 数据准备与预处理流程
第一步永远是数据。我用过的公开轴承数据集和自采数据都有个共性:故障不是连续的,而是隔一段时间换一个工况、换一种负载、换一个转速。你要是不做滑窗截断,直接把一整段数据扔进去,模型学到的是“这段数据对应的转速”而不是“故障对应的模式”。
标准的做法是把每个工况下每类故障的长时间连续信号按固定长度滑窗切段。窗口长度设1024点,步长设256点——窗口之间保持75%的重叠率。这样做的目的有两个:一是数据增强,从一段长信号里能切出大量样本,缓解故障样本不足的问题;二是相邻样本之间有重叠,特征分布更平滑,模型训练时不容易因为个别异常段产生剧烈波动。
切完段之后,要把每一段样本做幅值归一化。这一步容易被跳过,但我觉得非常重要。不同工况下传感器灵敏度、放大器增益不同,信号的绝对幅值有差异,如果不归一化,网络很容易学会“幅值大的就是故障”这种错误关联,换个工况直接失效。我用的归一化方法是把每段信号除以其峭度修正后的标准差——普通的零均值单位方差归一化在冲击信号上会被少数尖峰带偏,除标准差之前先做一下峭度加权,能压住冲击的影响。
预处理完成后,按7:2:1的比例划分训练集、验证集和测试集。划分的时候有个原则:同一段原始信号滑窗切出来的相邻样本有重叠,如果不做处理直接随机划分,训练集和测试集之间会混入高度相似的样本,测试准确率虚高得离谱。正确的划分方式是按原始数据段划分——也就是先把原始信号分成三段,每段只负责产生训练、验证或测试样本,互相之间没有重叠交叉。这个细节如果你不做,出来的分类准确率99%,实际上到工况变化时直接打回原形。
3.2 DWVD时频图批量生成与存储
这一步是MCNN-BiGRU输入的准备工作,也算最耗时的数据预处理环节。我在MATLAB里写了一个批处理脚本,输入是预处理后的信号段矩阵,输出是等尺寸的时频图矩阵。
具体实现有几个关键点:时频图的尺寸统一缩放到224×224,这样后面MCNN的输入层设计不用为每个样本单独考虑尺寸。缩放采用双线性插值——最近邻插值会对频谱谷底造成锯齿状伪影,CNN训练时容易把伪影误当成特征学进去。双线性插值的计算量也不大,批量处理时可以接受。
时频图的动态范围有讲究。直接计算出来的DWVD幅值跨度可能很大,有时高达10的四次方量级,如果不做压缩,直接用原始幅值当图像像素,网络训练时梯度极容易爆炸。我用的是对数幅值压缩:把幅值归一化到0到1之间之后,做log(1 + x)变换,把大动态范围压到可学习范围内。这个处理能显著加速收敛,我一开始没做这一步的时候,前几十个epoch训练损失基本不动,做了之后马上进入正常下降。
存储格式方面,批量生成的时频图我直接存成MAT文件,用单个结构体数组保存所有训练数据。不建议一张张存成png图片再用imageDatastore读取——存图再读图多了编码解码的损耗,而且MATLAB的imageDatastore在数据量大时读取速度偏慢,训练时数据供给容易出现瓶颈。
3.3 MCNN-BiGRU网络搭建:MATLAB代码思路拆解
MATLAB从R2019a之后引入了深度学习工具箱的layerGraph,可以用类似搭积木的方式构建自定义网络层。MCNN-BiGRU结构里,BiGRU部分用内置的bilstmLayer就能解决,而多尺度卷积分支需要构建三个并行路径再拼接。
网络搭建的骨架大概是这样的逻辑:输入层接收224×224×1的时频图。三个分支分别经过不同尺寸卷积核的卷积层,每个分支内部包含两个卷积块,每块由卷积层、批归一化层、ReLU层组成。三个分支的输出用深度拼接层串联起来,得到多尺度特征张量。拼接后的特征进入序列折叠层(sequenceFoldingLayer),把特征图从“空间批处理形式”转成“按宽度方向展开的序列形式”——这一步是MATLAB里把CNN特征送入循环网络的关键转换,不熟悉的人很容易卡在这里。然后是双向LSTM层(这里我直接用LSTM代替GRU,MATLAB内置层里没有原生GRU,用LSTM效果几乎等效,参数稍多一点但也不碍事)。最后经过全局平均池化、全连接层和Softmax分类层。
如果你更习惯编码搭图的方式,也能用dlnetwork命令式编程去写前向传播函数。早期我用layerGraph搭过一次,调试网络结构和维度对齐时有点费劲,后来改成dlnetwork手写前向逻辑,debug起来反而更直接。两种方式都能跑通,看你怎么方便怎么来。
训练配置方面,优化器我选用Adam,初始学习率设为0.001,配合余弦退火调度策略让学习率在训练后期衰减到0.00001。批大小取32,最大训练轮数30轮。早停法(early stopping)必须开——监测验证集损失,连续5轮不下降就停止训练,保存验证指标最优的模型权重。这套配置在我复现时,大约第12到18轮就能收敛,分类准确率稳定在97%以上。
3.4 训练策略与超参数选择的“为什么”
学习率0.001这个取值有讲究。比它大一个量级(0.01)时,MCNN分支的权重更新步长过大,很容易把卷积核打散,性能反而更差;比它低一个量级(0.0001)时,BiGRU的时间建模部分收敛极慢,前10轮loss几乎平着走,白白浪费训练时间。Adam优化器本来就擅长自适应调整参数学习率,0.001是它在大多数图像类任务里的“甜点区”。
批大小32对应的是显存和收敛速度的折中。批大小64时,单个epoch时间变长,但收敛并不更快,因为DWVD时频图里不同样本之间的差异性很大,大batch带来的梯度平均效应反而会抹平少数故障冲击强样本的贡献。批大小16时,梯度噪声太大,训练曲线抖动明显,验证集准确率波动有正负3个百分点的幅度。32恰好能兼顾梯度稳定性与收敛速度。
Dropout比例0.4在故障诊断任务上也很合适。故障诊断的样本本质上是在“同一工况下不同随机噪声实现”之间做判别,模型很容易记住噪声模式而不是故障模式。Dropout强制让特征提取过程不依赖某几个特定的神经元组合,相当于从压力测试的角度逼每个特征通道自己变得有用。
4. 常见问题与排查技巧实录
4.1 时频图“糊成一片”:交叉项干扰和窗函数过宽
训练起来发现模型loss降不下去,精度卡在60%左右徘徊,第一反应应该是检查输入数据而不是责怪网络。我遇到过最典型的情况是DWVD时频图里交叉项干扰太强,整个图看起来像是有人在上面画满了斜条纹,真正的故障特征完全淹没在里面。
排查办法是先用人眼观察一两张典型样本的时频图。如果看到明显的条纹干涉、图案呈“棋盘状”或“网格状”,基本就是交叉项没压住。解决的路径有两条:一是加宽时域平滑窗,让频率方向的干涉得到更大程度平均;二是对时频图做一次二维高斯滤波,相当于在图像域再平滑一次。高斯滤波核的sigma设在1到1.5之间比较合适,太大就把故障的瞬态冲击也抹掉了,得不偿失。
另一个容易忽略的原因是窗函数长度和信号长度不匹配。如果你一个样本有2048个点,窗函数长度却只有32,那再怎么平也压不住交叉项。经验法则是窗长不要低于信号长度的1/16,同时不要超过1/8,在这个区间内根据实际效果微调。
4.2 网络维度报错:channel与sequence不匹配
MCNN分支拼接之后要接BiGRU,这一步在MATLAB里报错率极高。典型的报错信息是“Number of channels mismatch”或者“Sequence length must be consistent”。原因往往是你没有正确理解“哪个维度是通道、哪个维度是时间步”。
CNN输出的特征张量形状是H(高)× W(宽)× C(通道),你如果直接把它pivot成序列,W方向的每一列是一个时间步,那这个时间步对应的向量长度就是 H×C。在送入BiGRU之前,必须把特征图重新排列成“序列长度×特征维度×批大小”的三维格式。MATLAB里做这个变换要用到sequenceFoldingLayer和sequenceUnfoldingLayer这两个层配合,或者你手动用permute和reshape去调整。我建议新手直接用layerGraph里现成的序列折叠层,省得自己在维度上绕晕。
如果你是自己手写dlnetwork的前向传播,记得在送入BiGRU之前把特征图做一次“数值转GPU”或者“保持GPU上计算”的检查——数据如果在CPU上,再跑去GPU训练的bilstmLayer必然报设备不匹配的错误。这个问题在反复重启脚本训练时经常冒出来。
4.3 训练过拟合与“验证集高、测试集低”的区别
故障样本数量通常不多,几千个样本已经算可观,几万个样本就算大户。在样本量有限的时候,过拟合几乎是必然发生的事,关键看你怎么抑制。除了Dropout之外,我还有两个非常管用的招。
第一招是数据增强,而不是简单地在训练集上重复采样。振动信号的数据增强和图像不太一样:图像可以翻转、旋转、裁剪,信号段则可以做幅值微小扰动、时间轴小尺度伸缩、加少量高斯白噪。我实际测试下来,对训练集加10%幅值扰动和少量高斯噪声,测试集准确率能提升2到3个百分点,且不会像“重复过采样”那样造成严重的样本记忆。
第二招是加L2正则化,权重衰减系数设在10的-4次方这个量级。很多人忽略正则化,其实在小数据集上它的作用非常直接:它惩罚过大权重,迫使网络对输入噪声不那么敏感,用更平滑的决策边界去分类。这个和Dropout配合使用,能把过拟合曲线向后推好几个epoch,让你有足够时间在验证集上找到最优模型。
顺便纠正一个常见的误区:“验证集准确率高”和“模型好”是两回事。验证集是你在训练迭代过程中反复参考的指标,模型间接“见过”了它的分布;测试集才是真正没见过的数据。所以,如果你发现验证集准确率有99%,测试集只有85%,十有八九是过拟合,或者是前面说的“按滑窗样本随机划分”导致的数据泄露问题。这时候先回去检查数据划分方式,再调正则化参数,不要上来就调网络结构。
4.4 一些实打实的避坑清单
最后按我自己的排错习惯整理一个小清单,送给刚接触这套方案的朋友:
DWVD计算时,信号长度乘以FFT点数会导致矩阵维度过大。如果做批量预处理的时候内存不够,可以分块计算,每批处理几百个样本,而不是一次性把全部训练样本都加载进来。我一开始图省事一次性计算两万个样本的时频图,8GB内存直接爆掉,后来改成每两千个样本一批,内存占用非常稳。
MCNN三个分支的卷积层如果不加padding,特征图的宽高会越来越小,后面拼接的时候三个分支输出的尺寸对不齐,完全没法cat。一定记得每层卷积都要设置padding方式为“same”,或者在设计网络时精确计算每一层的输出尺寸。
BiGRU在全连接层之前的输出维度,等于隐层维度乘以2(因为双向),再接全连接层的时候,第一层全连接层的输入节点数必须等于这个翻倍后的维度。这个数字你要是忘记了,可以打印一下前一层输出的size来确定,别想当然用原来的隐层维度。
训练之前先跑几个样本的前向传播,确认输出尺寸和中间层维度都符合预期,再开始全量训练。这个习惯能帮你省下大量因为维度不对导致的半途报错时间。
写在最后:一点实际操作的体会
这套方案我从最开始的雏形到最终稳定版的实用性,超过我最初预期的地方其实不在算法本身,而在于“时频分析+深度网络”这条路线对故障类型的适配度非常广:轴承内圈、外圈、滚动体故障,齿轮断齿、磨损,以及不平衡不对中这类缓变故障,只要调整DWVD的参数和训练样本的工况设定,都能达到可用的精度。MCNN和BiGRU的配合让模型同时具备空间细节感知和时间上下文记忆,这是单纯用CNN或者单纯用时序模型都很难达到的效果。
如果你准备在自己的数据上复现,我的建议是不要急于追求一个极高的准确率,先把整个链路跑通——拿几十个样本把DWVD时频图做出来,人眼看一看图的形态是否合理,再搭一个简化版的MCNN-BiGRU(可以把三个分支的卷积核缩小、BiGRU的隐层维度减半)把训练流程走通,最后再逐步加参数、加数据、调优。先求通,再求准,这套方法才能真正成为你自己手里的趁手工具。
另外还有一个小的扩展方向:当你的故障类别很多、或者需要对故障严重程度做细化分级时,可以考虑把输出的类别标签从离散分类改成连续的退化指标回归,也就是把网络最后一层改成回归头,输出的数值代表故障的严重程度评分。DWVD时频图能直观反映冲击能量的大小变化,这套网络结构在退化趋势预测上同样有潜力。不过那就是另一个项目要聊的事了。
