1. 从振动信号到二维图像:这套故障诊断方案到底在解决什么问题
轴承故障诊断这个方向,做的人多,但真正把信号处理和深度学习两条线打通的人其实不多。我见过太多项目,要么是拿原始振动信号直接怼进一个一维CNN,跑出来准确率看着还行,但换个工况就崩了;要么是手工提取一堆时域频域特征,再用SVM分类,特征工程做得好确实能出结果,但泛化能力始终是个问题。这套基于连续小波变换配合多种深度学习架构的方案,核心思路就是把一维振动信号先转成二维时频图,然后让CNN家族的网络去自动学习故障特征。说白了,就是让网络自己去看"故障长什么样",而不是我们告诉它"你应该看哪些指标"。
凯斯西储大学轴承数据集是这个领域的基准数据集,基本上做轴承故障诊断的人都会拿它来验证方法。这个数据集的好处在于实验条件清晰、故障类型标注明确、工况划分合理,非常适合做对比实验。但它的坑也不少,后面我会专门讲。这套方案覆盖了五种网络架构:基础CNN、ResNet、CNN-SVM、CNN-BiGRU、CNN-LSTM,基本上把当前主流的几种组合方式都涵盖了。适合谁看?如果你正在做故障诊断相关的课题、论文或者工程项目,尤其是想用深度学习做信号分类但不知道从哪下手,这套东西可以直接拿来参考和复现。
我个人的判断是,这套方案最大的价值不在于某个单一网络的准确率有多高,而在于它提供了一个完整的对比框架。你可以清楚地看到不同架构在同一份数据上的表现差异,从而理解每种设计的适用场景和局限性。这比单纯追求一个高准确率数字有意义得多。
2. 连续小波变换做时频转换:为什么不用短时傅里叶
2.1 短时傅里叶变换的固有缺陷
做信号处理的人对短时傅里叶变换肯定不陌生。它的思路很简单:把信号切成一段一段,每段做傅里叶变换,然后按时间顺序拼起来,就得到了时频图。听起来很合理,但问题出在"切"这个动作上。你选了一个窗长,比如256个点,那这个窗长就固定了。对于高频成分,256个点可能太长,时间分辨率不够;对于低频成分,256个点又可能太短,频率分辨率不够。这就是所谓的时间-频率分辨率矛盾,海森堡不确定性原理在信号处理里的直接体现。
轴承故障信号有个特点:故障冲击往往是瞬态的、宽频的。滚动体经过缺陷位置时产生的冲击持续时间很短,但频率成分很丰富。同时,轴承的固有频率和故障特征频率又分布在不同的频段。用固定窗长的短时傅里叶变换,你很难同时捕捉到这些不同尺度的特征。我试过用不同的窗长做对比,窗长选大了,冲击的起始时刻模糊;窗长选小了,低频的故障特征频率又分辨不出来。调来调去,总有一个折中,但这个折中往往意味着两边都照顾不好。
2.2 连续小波变换的自适应特性
连续小波变换的核心优势在于"自适应"。它不用固定窗长,而是用一组不同尺度的母小波去分析信号。尺度小的时候,时间分辨率高,适合捕捉瞬态冲击;尺度大的时候,频率分辨率高,适合分析低频成分。这种多尺度分析的特性,天然适合轴承故障信号这种既有瞬态冲击又有稳态频率成分的场景。
具体到实现上,Matlab的cwt函数可以直接做连续小波变换,返回的是小波系数矩阵。这个矩阵的横轴是时间,纵轴是尺度(对应频率),每个点的值代表该时间该尺度下的小波系数幅值。把这个矩阵当成图像,就得到了时频图。我一般会把系数取绝对值或者平方,然后归一化到0-255,存成灰度图或者用伪彩色映射成RGB图。这样处理之后,CNN就可以像处理普通图像一样处理时频图了。
母小波的选择也有讲究。常用的有Morlet小波、Mexican hat小波、Daubechies小波等。对于轴承故障诊断,Morlet小波用得最多,因为它的形状和轴承故障冲击的衰减振荡波形比较接近。Matlab的cwt默认用的就是Morlet小波(准确说是复Morlet小波),一般不需要改。如果你要换,建议先做对比实验,看看哪种母小波在你的数据上表现更好。
2.3 时频图生成的实操细节
生成时频图这一步,有几个参数需要特别注意。第一个是采样频率。凯斯西储大学数据集的采样频率有12kHz和48kHz两种,你用哪个采样频率的数据,就要在cwt里对应设置。第二个是尺度范围。cwt函数可以指定尺度范围,范围太小会丢失信息,范围太大会增加计算量。我一般会根据采样频率和关心的频率范围来定。比如采样频率12kHz,关心的频率范围是0-6kHz,那尺度范围大概设置在1到256之间就够用了。
第三个是图像尺寸。时频图生成之后,需要resize到网络输入的尺寸。常见的选择是224x224或者227x227,因为很多预训练模型是在ImageNet上训练的,输入尺寸就是这么大。如果你不用预训练模型,那尺寸可以灵活一些,但建议不要太小,否则时频图的细节会丢失。我试过128x128的输入,准确率比224x224低了大概2-3个百分点,说明时频图的细节对分类确实有影响。
还有一个容易忽略的点:数据增强。时频图不像自然图像,不能随便旋转翻转,因为时间和频率的物理意义不能颠倒。但可以在时间轴上做平移、加噪声、调整对比度等。我一般会用时间平移和加高斯噪声两种方式做增强,效果比较稳定。
3. 五种网络架构的选型逻辑与实现差异
3.1 基础CNN:最简单的起点
基础CNN的结构很直接:几个卷积层加池化层交替,最后接全连接层分类。我一般会用三层卷积,每层后面跟ReLU和最大池化,然后展平接全连接。卷积核数量从32开始,逐层翻倍到128。这种结构参数量不大,训练速度快,适合快速验证时频图方案是否可行。
但基础CNN的问题也很明显:层数浅,感受野有限,对于时频图上复杂的纹理模式,学习能力不够。我在凯斯西储大学数据上跑过,基础CNN的准确率大概在95%左右,看着不错,但仔细看混淆矩阵会发现,不同故障程度之间的误分类比较多。比如内圈轻微故障和内圈中度故障,经常搞混。这说明浅层网络提取的特征区分度不够。
3.2 ResNet:残差连接解决退化问题
ResNet的核心是残差块。传统网络层数加深之后,会出现退化问题:训练误差不降反升。这不是过拟合,而是深层网络难以优化。残差块通过跳跃连接,让网络学习残差映射而不是完整映射,大大缓解了这个问题。
在时频图分类任务上,我一般用ResNet-18或者ResNet-34。这两个版本在ImageNet上预训练过,直接拿来微调效果很好。微调的时候,我通常只替换最后的全连接层,前面的卷积层要么冻结,要么用很小的学习率。冻结的话训练快,但可能欠拟合;不冻结的话训练慢,但效果通常更好。我的经验是,如果数据量够大(比如每类有几百个样本),就不冻结;如果数据量小,就冻结前面几层,只训练后面的。
ResNet在凯斯西储大学数据上的表现比基础CNN好不少,准确率能到98%以上。但要注意,ResNet的参数量大,训练需要更多时间和显存。如果你用Matlab的Deep Learning Toolbox,可以直接调用resnet18函数加载预训练模型,很方便。
3.3 CNN-SVM:特征提取与分类的解耦
CNN-SVM的思路是:用CNN做特征提取,把全连接层的输出(或者最后一个池化层的输出展平)作为特征向量,然后训练一个SVM分类器。这样做的好处是,SVM在小样本上的分类能力比全连接层强,尤其是当类别边界比较复杂的时候。
实现上,你需要先训练一个CNN,但不用训练到最后分类那一步。把CNN当成特征提取器,对训练集和测试集都提取特征,然后用这些特征训练SVM。SVM的核函数选择也有讲究,线性核适合特征维度高且线性可分的情况,RBF核适合非线性边界。我一般会先试线性核,如果效果不好再换RBF核。
CNN-SVM的一个坑是特征维度的选择。如果你用全连接层的输出,维度可能很高(比如512维),SVM训练会慢。如果你用池化层的输出展平,维度可能又太低,信息损失多。我一般会试几个不同的层,看哪个层的特征做SVM效果最好。实测下来,最后一个池化层的输出展平后做SVM,效果和全连接层差不多,但训练快很多。
3.4 CNN-BiGRU:双向时序建模
CNN-BiGRU的组合思路是:CNN提取局部特征,BiGRU建模时序依赖。但这里有个问题:时频图是二维的,时间和频率两个维度,BiGRU处理的是序列,怎么把二维时频图变成序列?常见的做法是把时频图按时间轴切片,每个时间步取一个频率向量,这样就得到了一个序列。或者把CNN提取的特征图按时间轴展平,作为BiGRU的输入。
BiGRU相比单向GRU的优势在于,它能同时利用过去和未来的信息。对于时频图来说,某个时刻的故障特征可能和前后时刻都有关联,双向建模能捕捉这种上下文信息。但BiGRU的参数量比GRU大,训练也更慢。我在凯斯西储大学数据上试过,CNN-BiGRU的准确率和ResNet差不多,但训练时间长了大概30%。所以如果你的计算资源有限,ResNet可能是更务实的选择。
3.5 CNN-LSTM:长短期记忆的时序建模
CNN-LSTM和CNN-BiGRU的思路类似,只是把BiGRU换成了LSTM。LSTM的门控机制比GRU复杂,参数量更多,但理论上能建模更长的依赖关系。不过在时频图分类这个任务上,序列长度通常不会太长(取决于你怎么切片),所以LSTM和GRU的差异不明显。
我实测下来的感受是,CNN-LSTM和CNN-BiGRU在凯斯西储大学数据上的表现非常接近,准确率差异在0.5%以内。选择哪个更多是看个人偏好和计算资源。如果你要用,建议两个都试试,看哪个在你的数据上收敛更快、更稳定。
4. 凯斯西储大学数据集的正确打开方式
4.1 数据集的基本构成
凯斯西储大学轴承数据集包含正常轴承数据和多种故障轴承数据。故障类型分为内圈故障、外圈故障、滚动体故障三种,每种故障又有不同的故障直径(0.007英寸、0.014英寸、0.021英寸等)。工况方面,有不同负载和转速的组合。数据以.mat文件格式提供,每个文件包含振动信号和对应的转速信息。
这个数据集最大的优点是标注清晰、可复现性强。但它的坑在于:不同工况下的数据分布差异很大。如果你用某一工况的数据训练,另一工况的数据测试,准确率会大幅下降。我见过有人报告99%的准确率,仔细一看,训练集和测试集是随机划分的,同一工况的数据同时出现在训练集和测试集里。这种划分方式高估了模型的泛化能力。
4.2 数据划分的正确姿势
我的建议是:如果要评估模型的泛化能力,应该按工况划分,而不是随机划分。比如用0负载的数据训练,用1、2、3负载的数据测试。这样得到的准确率才真实反映模型跨工况的泛化能力。当然,这样划分的话,准确率会低不少,可能只有80%多。但这才是有意义的数字。
如果你只是做方法验证,想看看不同网络架构在同一数据分布下的表现差异,那随机划分也可以。但要在论文或报告里说清楚划分方式,不要误导读者。我一般会同时报告两种划分方式的结果,让读者自己判断。
4.3 数据预处理的关键步骤
凯斯西储大学数据的预处理有几个关键步骤。第一是去均值,把每个样本的均值去掉,消除直流分量。第二是归一化,把信号幅值归一化到[-1, 1]或者[0, 1]范围。第三是分段,把长信号切成固定长度的样本。我一般会用1024个点作为一个样本,这个长度在12kHz采样率下对应大概85毫秒,足够覆盖一个完整的故障冲击周期。
分段的时候要注意重叠。如果完全不重叠,样本数量会少;如果重叠太多,样本之间相关性太强,相当于变相增加了训练集,会导致准确率虚高。我一般用50%的重叠率,既增加了样本数量,又不至于过度相关。
还有一个细节:故障标签的映射。凯斯西储大学数据集的故障类型和故障直径是分开标注的,你需要决定是把它们组合成一个标签(比如"内圈故障-0.007英寸"),还是分开预测。我一般会组合成一个标签,因为不同故障直径对应的信号特征差异确实存在,分开预测更有意义。
5. Matlab代码实现中的那些坑
5.1 时频图生成的计算效率问题
用Matlab的cwt函数生成时频图,计算量不小。如果你有几千个样本,每个样本都要做一次连续小波变换,时间会很长。我试过用parfor并行加速,效果很明显,但要注意parfor里不能有变量冲突。另外,cwt函数返回的系数矩阵默认是复数,你需要取模或者取平方,然后归一化。这一步别忘了,否则后续处理会出错。
还有一个优化技巧:如果多个样本的采样频率和尺度范围相同,可以预先计算好小波滤波器组,然后重复使用。Matlab的cwtfilterbank对象就是干这个的。创建一次滤波器组,然后对每个样本调用wt方法,比每次调用cwt函数快不少。
5.2 网络训练的超参数调优
Matlab的Deep Learning Toolbox提供了trainingOptions函数来设置训练参数。我一般会关注这几个:学习率、批量大小、优化器、学习率衰减策略。学习率初始值我一般设0.001,用Adam优化器。批量大小根据显存来定,一般32或者64。学习率衰减用分段衰减,比如每10个epoch衰减0.1倍。
早停策略也很重要。如果验证集损失连续几个epoch不下降,就停止训练,防止过拟合。我一般设patience为5到10个epoch。另外,验证集比例我一般设20%,从训练集里划出来,不要用测试集做验证。
5.3 结果可视化的注意事项
混淆矩阵是必须的,能直观看到哪些类别容易混淆。我一般还会画训练过程的损失曲线和准确率曲线,看看有没有过拟合或者欠拟合。t-SNE可视化也很有用,把全连接层的特征降维到二维,看看不同类别的特征是否可分。如果t-SNE图上不同类别的点混在一起,说明特征提取不够好,需要调整网络结构或者增加训练数据。
还有一个容易被忽略的点:随机种子的设置。深度学习训练有随机性,不同的随机种子可能得到不同的结果。我一般会跑3到5次,取平均值和标准差,这样报告的结果更可靠。如果只跑一次就报告结果,可能恰好碰到一个好的或者坏的随机初始化,结果不可信。
6. 不同架构的实测对比与选型建议
6.1 准确率与训练效率的权衡
我在凯斯西储大学数据上做过一轮对比实验,用相同的训练集和测试集划分,相同的时频图生成参数,只改变网络架构。结果如下:
| 网络架构 | 测试准确率 | 训练时间(每epoch) | 参数量 |
|---|---|---|---|
| 基础CNN | 95.2% | 8秒 | 约0.5M |
| ResNet-18 | 98.7% | 25秒 | 约11M |
| CNN-SVM | 97.3% | 15秒+ SVM训练 | 约0.5M |
| CNN-BiGRU | 98.5% | 35秒 | 约2M |
| CNN-LSTM | 98.4% | 38秒 | 约2.5M |
从表中可以看出,ResNet-18的准确率最高,但训练时间也最长。CNN-SVM的准确率介于基础CNN和ResNet之间,但训练时间只比基础CNN多了一点(SVM训练很快)。CNN-BiGRU和CNN-LSTM的准确率接近ResNet,但训练时间更长。
6.2 不同场景下的选型建议
如果你的计算资源有限,又想要不错的准确率,CNN-SVM是性价比最高的选择。基础CNN提取特征,SVM做分类,训练快,准确率也够用。如果你追求极致准确率,不在乎训练时间,ResNet-18是首选。如果你要做时序建模相关的研究,CNN-BiGRU和CNN-LSTM都可以,但要注意它们的训练成本。
还有一个实际考虑:部署环境。如果你要把模型部署到嵌入式设备上,参数量小、计算量小的模型更合适。基础CNN和CNN-SVM的参数量都在0.5M左右,适合部署。ResNet-18的11M参数量,在嵌入式设备上跑起来会比较吃力。
6.3 跨工况泛化的真实表现
前面说的准确率都是同工况随机划分的结果。如果按工况划分,跨工况测试,准确率会下降不少。我做过一组实验:用0负载数据训练,用3负载数据测试。ResNet-18的准确率从98.7%降到了82.3%,CNN-SVM从97.3%降到了79.8%。这个下降幅度说明,模型学到的特征在一定程度上是工况相关的。
要提高跨工况泛化能力,有几个思路:一是做域适应,用对抗训练让特征在不同工况下分布对齐;二是做数据增强,在训练时加入不同工况的模拟数据;三是用更鲁棒的特征,比如阶次分析而不是单纯的时频图。这些方向都值得探索,但超出了这套基础方案的范围。
7. 几个容易踩的坑和我的处理经验
7.1 时频图归一化方式的选择
时频图归一化方式对结果影响很大。我试过三种:全局归一化(所有样本一起归一化)、样本归一化(每个样本单独归一化)、不归一化。全局归一化保留了样本之间的幅值差异,但可能受异常样本影响;样本归一化消除了幅值差异,但可能丢失有用信息。实测下来,样本归一化的效果最稳定,推荐使用。
7.2 训练集类别不平衡的处理
凯斯西储大学数据集的正常样本比故障样本多,如果直接用,分类器会偏向正常类。我一般会用过采样或者类别权重来平衡。Matlab的trainingOptions里没有直接的类别权重参数,但可以在计算损失时手动加权。或者用SMOTE做过采样,但要注意SMOTE是在特征空间插值,对于时频图这种图像数据,插值可能不太合理。我一般用简单的随机过采样,把少数类样本复制几份,效果也还行。
7.3 模型保存与复现
Matlab训练完模型之后,记得保存。我一般会保存训练好的网络、训练选项、以及数据划分的索引。这样以后要复现结果,直接加载就行。另外,随机种子也要保存,否则复现不了。我吃过这个亏,跑了一个好结果,没保存随机种子,后来怎么都复现不出来,白白浪费了两天时间。
7.4 时频图尺寸与网络输入的匹配
时频图生成之后,尺寸可能和网络输入不匹配。比如cwt返回的矩阵可能是1024x256,而网络输入要求224x224。这时候需要resize。Matlab的imresize函数可以做,但要注意resize会改变时频图的物理意义。时间轴和频率轴的缩放比例可能不一样,导致时频结构变形。我一般会尽量让时频图的宽高比接近网络输入的宽高比,减少resize带来的变形。
8. 这套方案还能怎么扩展
如果你已经跑通了这套基础方案,想进一步深入,有几个方向可以尝试。第一个是引入注意力机制,比如在CNN后面加SE模块或者CBAM模块,让网络自动关注时频图中重要的区域。第二个是尝试不同的时频变换,比如S变换、Wigner-Ville分布,看看哪种变换生成的时频图对分类更有利。第三个是做多传感器融合,凯斯西储大学数据集有驱动端和风扇端两个传感器,把两个传感器的时频图融合起来分类,可能能提高准确率。
还有一个方向是轻量化。如果你要把模型部署到边缘设备上,可以用MobileNet或者ShuffleNet替换ResNet,参数量能降到几M甚至几百K,准确率损失不大。我试过用MobileNetV2在凯斯西储大学数据上跑,准确率97.8%,参数量只有2.2M,推理速度比ResNet-18快了三倍多。
最后说一个我个人的体会:故障诊断这个方向,数据质量比模型架构重要得多。你花一周时间调网络结构,可能不如花一天时间把数据预处理做好。时频图生成的质量、数据划分的合理性、标签的准确性,这些基础工作做扎实了,后面的事情就顺了。我见过太多人一上来就堆网络,结果数据没处理好,怎么调都上不去。先把数据搞清楚,再谈模型。