简介:振动信号分析是机械设备状态监测与故障诊断的核心手段,而高质量的公开数据集是算法验证和工程落地的基础。从最基本的时域特征(如均方根值、峭度)到频域包络谱分析,再到基于一维卷积神经网络的深度学习方法,都离不开规范、可复现的实验数据。CWRU、IMS、PHM2012等主流公开数据集为研究者提供了统一对比基准,覆盖轴承内圈、外圈、滚动体故障及全寿命退化数据,支撑故障分类、剩余寿命预测等典型任务。合理选择数据集、掌握信号预处理与滑动窗口切分技巧,并警惕数据泄露与变工况迁移问题,是提升诊断模型泛化能力的关键。本文系统梳理了公开数据集选型、特征工程、建模路线及常见避坑指南,帮助初学者快速上手机械故障诊断实战。 搞机械故障诊断这个方向,不管你是做学术研究的还是做工业落地项目的,第一个绕不过去的坎就是数据。我自己入坑那会儿,最发愁的不是算法不会写,而是找不到一套靠谱的“机械故障诊断公开数据集”用来验证方案。设备正常跑着的信号好采集,但故障状态下的信号真不是你想拿到就能拿到的——产线不能为了做实验就停摆,设备更不会按你的需求去坏。所以公开数据集在这个领域里地位一直很特殊,它既是学术研究公认的“比武擂台”,又是新手入行最快的“练习场”。
这篇东西我想认真聊一聊机械故障诊断公开数据集的那些事,包括主流的几个数据集到底怎么选、数据拿回来之后怎么预处理、怎么用它们训练出有效的诊断模型,以及我踩过的那些坑。内容偏向实操,代码和参数我都会给出来,适合刚接触这个方向的硕士生、转行做工业AI的工程师,以及想在企业内部快速搭建一套诊断验证流程的技术人员。我会尽量把当年自己摸索时浪费的时间帮你省掉。
1. 为什么故障诊断离不开公开数据集
1.1 工业现场数据为什么那么难获取
先说个现实问题。机械设备故障诊断要落地,本质上靠的是“数据 + 算法”,但数据这一环在真实工业场景里往往是最薄弱的部分。故障数据为什么稀缺?首先,设备发生故障是小概率事件,大部分轴承、齿轮在正常维护条件下能跑很久,你不可能为了采集故障样本故意把设备弄坏——那成本谁也扛不住。其次,即使现场真的发生了故障,完整的信号记录也不一定保得住:很多老产线根本没有在线监测系统,故障发生了才知道,运行过程中的振动信号、温度曲线早就没了。
就算运气好,企业有一套状态监测系统,也还有标签问题。设备是几点几分开始出现早期故障的?退化到哪个阶段就该停机?这些标签依赖老师的经验判断,不同人打出来的标签可能都不一样,标准很难统一。再加上很多工厂的数据涉及工艺参数、设备产能信息,在保密协议约束下,外部研究人员根本碰不到原始数据。我见过太多校企合作项目,前三个月全耗在数据对接和清洗上,真正做算法的只有一个多月,这就是工业数据现状的缩影。
1.2 公开数据集给这个领域带来了什么
公开数据集恰好在这个环节上补了位。它的价值可以从三个层面来看:
第一是提供统一对比基准。所有研究者用同一份数据、同样的故障类型、同样的工况参数,算法的优劣才能放在一个公平环境里比。没有这套基准,你说你的方法准确率99%,我说我的方法准确率99.5%,各自找的数据都不一样,讨论就没有意义。
第二是大幅降低入门门槛。做故障诊断这个方向,没必要每个人都有机会去现场拆一台电机、装一堆传感器。公开数据集把传感器布置方案、采样频率、加载工况和故障标签都标得清清楚楚,初学者拿回数据就能上手跑流程,理解整个诊断链路。
第三是支持算法的可复现性。论文里写“提出了一种基于某某网络的新型诊断方法”,如果用的公开数据,别人就能下载数据复现实验,这对学术交流和产业评估都有帮助,至少可以通过在同一数据集上的效果横向比较来判断一个算法到底行不行。
2. 主流数据集盘点与选型建议
2.1 CWRU:故障诊断圈的“MNIST”
如果你在故障诊断领域只听说过一个数据集,那大概率是西储大学(Case Western Reserve University,CWRU)的滚动轴承数据集。这个数据集的历史很悠久,由西储大学电气工程实验室搭建实验台采集,数据用加速度计分别在驱动端和风扇端采集振动信号,采样频率常见的有12kHz和48kHz两个档位。
CWRU数据集的故障类型涵盖滚动轴承最常见的几种失效模式:外圈故障(outer race)、内圈故障(inner race)和滚动体故障(ball),每种故障通过电火花加工设定了三种损伤尺寸,分别是0.007英寸、0.014英寸和0.021英寸,对应着故障从轻微到严重的变化。加上正常状态样本,一共能组合出十几种不同类别。电机负载则从0 HP到3 HP分了四档,可以研究不同工况对诊断的影响。
这个数据集最大的优点是结构清晰、文件命名规范、文档资料全,所以特别适合用来验证新算法。论文里你用CWRU跑出一个结果,审稿人都认,因为大家在同一个平台上见过太多方法了,效果好不好一对比就知道。它的不足也明显:数据来自实验室,故障是用人工加工复现的,损伤形态和真实自然磨损产生的故障有差异;而且故障类型只有轴承外圈、内圈、滚动体三类,齿轮故障、复合故障都没有覆盖。但作为入门和基础验证,CWRU的地位目前还是无法撼动的。
2.2 IMS轴承全寿命数据集:做退化预测的主流选择
IMS数据集来自美国国家科学基金会(NSF)资助的智能维护系统中心,它的特点在于提供了轴承从健康状态到完全失效的全寿命周期振动信号,而不是像CWRU那样只给“故障”和“健康”两类状态。全套数据由三组实验组成,每组实验用四颗轴承同轴安装,通过弹簧加载径向力,在转速2000 RPM、径向载荷6000磅的条件下连续运行,直到轴承出现明显失效。振动信号每10分钟采集一次,每次采样持续1秒,采样频率为20kHz。
这个数据集最适合干什么?剩余寿命预测(RUL)、退化趋势跟踪和早期故障预警。你能从数据中看到轴承振动幅值从小到大、从平稳到剧烈波动的完整退化过程,这是实验室台架测试独有的价值。我在做退化特征提取的时候,最喜欢用IMS数据来检验一个特征能不能“跟随”退化趋势——比如均方根值随运行时间单调上升、峭度在某个时刻开始突变,这些都能在IMS数据上验证。对做预测性维护(PdM)方向的朋友来说,IMS几乎是绕不开的数据集。
2.3 PHM2012轴承数据集:最贴近真实诊断逻辑的公开数据
PHM2012是IEEE PHM协会2012年预测与健康管理挑战赛发布的数据集,由法国FEMTO-ST研究所搭建实验台采集,采样频率25.6kHz。数据集包含三种工况下共17个轴承的全寿命振动数据,其中每工况的6个训练集和2个测试集是分开划分的。故障类型包括内圈故障、外圈故障和滚动体故障。
它的特别之处在于“训练集和测试集分开”这件事在工业界看似普通,但在公开数据集里其实很宝贵。你要在训练集上做特征、训练模型,然后拿测试集去验证,这个流程更接近真实比赛和实际部署的逻辑。想深入了解数据细节的话,可以看资料包里的PDF文档,写得很详细,连实验台的轴承型号、预紧力设置都有记录。如果你已经在CWRU上练过手,想进一步提高模型的泛化能力和对数据规模敏感度的认知,PHM2012是个不错的进阶选择。
2.4 值得关注的其他公开数据集
除了上面三个,这几年还有几个数据集也越来越多地出现在论文里,我简单列一下,免得你选型时漏掉:
- 东南大学(SEU)齿轮箱数据集:包含齿轮和轴承的复合故障,采样频率高,故障类别丰富,适合做多故障模式识别。
- 西安交通大学XJTU-SY轴承数据集:由西安交大与昇阳科技联合发布,15个轴承的全寿命数据,覆盖三种工况,信号质量不错,文档中给出的失效部位标注也比较清楚。
- 帕德博恩大学(Paderborn)轴承数据集:德国研究者发布的轴承数据集,包含大量真实损伤和人工损伤的轴承样本,还提供了电机电流信号与振动信号的双通道数据,适合多传感器融合研究。
- MFPT轴承数据集:美国MFPT(机械故障预防技术协会)提供的公开数据,故障类型包含内圈、外圈故障,数据量不算大,但胜在干净、方便快速验证。
我用一张表把这几个主流数据集的关键参数整理出来,方便你选型参考:
| 数据集 | 对象 | 采样频率 | 故障类型 | 数据特点 | 典型用途 |
|---|---|---|---|---|---|
| CWRU | 滚动轴承 | 12kHz / 48kHz | 内圈、外圈、滚动体,3种损伤尺寸 | 类别清晰,样本量大 | 算法验证、分类任务入门 |
| IMS | 滚动轴承 | 20kHz | 全寿命退化数据 | 从健康到失效的完整周期 | 寿命预测、趋势分析 |
| PHM2012 | 滚动轴承 | 25.6kHz | 内圈、外圈、滚动体 | 训练/测试集明确划分 | 预后与诊断结合 |
| SEU | 齿轮箱 | 多种 | 齿轮、轴承复合故障 | 故障模式多,信号复杂 | 复合故障诊断 |
| XJTU-SY | 滚动轴承 | 25.6kHz | 全寿命数据,多种失效部位 | 3种工况,15个轴承 | 退化趋势、迁移诊断 |
| Paderborn | 滚动轴承 | 64kHz | 真实损伤+人工损伤 | 包含电流+振动信号 | 多传感器融合 |
3. 实操:数据获取、预处理与特征工程
3.1 下载与文件格式解析
以CWRU为例,它的数据可以从西储大学官网免费下载。下载下来是mat文件,Matlab环境下直接用load就能加载,Python环境需要SciPy库的loadmat函数读取。我第一次用CWRU数据的时候踩过一个坑:官网文件名很长,比如“97.mat”、“105.mat”这种编号,不看文档根本不清楚对应什么状态。这里告诉你一个小技巧,CWRU数据集自带一个说明文档,里面列了每个文件编号对应的故障类型、损伤尺寸和负载情况,下载的时候一定把那个文档一起保存好,后面处理数据会省很多事。
读取mat文件的Python代码很简单,像这样:
from scipy.io import loadmat import numpy as np # 以CWRU数据为例,读取驱动端DE文件 data = loadmat('105.mat') print(data.keys()) # 通常会有 'DE', 'FE', 'BA' 等键,分别对应驱动端、风扇端、基座振动信号 vibration_signal = data['DE'].flatten() print('信号长度:', len(vibration_signal)) print('采样频率: 12000 Hz')信号读取出来后,我习惯先做一个可视化检查,看看时域波形长什么样。正常状态下的信号幅值均匀、无明显冲击,故障状态下会有周期性冲击成分,肉眼就能看出差别。这一步虽然很简单,但能帮助你建立对数据的直觉认知,后面做特征分析时心里有底。
3.2 信号预处理:去均值、滤波与降采样
原始振动信号一般不能直接送进模型,得先做预处理。第一步是去均值。加速度传感器在安装时会存在一定偏置,信号中会叠加一个直流分量,虽然对幅值影响不大,但会干扰后续频域分析,所以先减掉均值:
signal = vibration_signal - np.mean(vibration_signal)第二步是滤波。公开数据集的信号质量通常比较好,但采集过程中难免有环境噪声和高频干扰。工业诊断中常用的做法是带通滤波,保留设备运行的主要频带。拿轴承来说,故障特征频率通常在几千赫兹以下,高频噪声没有保留价值。代码里可以用SciPy的butter滤波器,设计一个带通范围比如20Hz到6000Hz。我自己做CWRU的时候一般不额外滤波,因为公开数据已经比较干净,但工业现场数据这一步省略不得。
降采样也是一个可选操作。如果原始采样频率是48kHz,而故障特征频率集中在低频段,降采样到12kHz可以减小计算量,加快训练速度。降采样前必须保证信号频带内没有混叠,最好先做低通滤波再降采样,用scipy.signal.resample_poly可以实现。
3.3 样本切分:滑动窗口怎么选
公开数据集里一条信号可能长达几秒甚至几分钟,但训练模型时通常不会整条塞进去,而是切成短片段,每个片段作为一个独立样本。这一步在深度学习方案里几乎是必做的,窗口长度和步长怎么选直接影响样本数量和模型效果。
我常用的窗口长度是1024、2048或4096个采样点,具体取多少要看采样频率。以12kHz采样为例,取1024个点对应约0.085秒的时长,这个时长内包含若干个旋转周期(假设转频30Hz,一个周期400个点),信息量是够的。步长取窗口长度的50%是一种常见做法,比如窗口1024、步长512,这样相邻样本之间有部分重叠,既扩充了样本数量,又不会让样本之间完全独立导致信息断裂。如果你的训练集中每类样本本来就多,也可以用不重叠的切分,减少样本之间的相关性。
切分的Python代码如下:
def sliding_window(signal, window_size=1024, stride=512): samples = [] for start in range(0, len(signal) - window_size + 1, stride): samples.append(signal[start:start + window_size]) return np.array(samples)注意,切分完之后要检查一下各类别的样本量是否均衡。CWRU数据集中不同故障类型和损伤尺寸的数据时长差不多,切出来样本量差异不大,但有些数据集里不同工况下的信号长度不均匀,切完以后类别不均衡,后面训练时要重点处理。
3.4 特征工程:时域、频域与包络谱
在深度学习方案普及之前,故障诊断的主流做法是“手工特征 + 机器学习分类器”。即便现在用深度学习,特征提取能力依然是理解问题本质的基础。
时域特征是最直观的一类,包括均值、均方根值(RMS)、峰值因子、峭度、波形因子等,每个特征反映信号某一个方面的性质。均方根值衡量信号的能量水平,旋转机械正常运转时RMS值相对稳定,出现故障后往往增大。峭度是一个无量纲指标,对冲击成分非常敏感,滚动轴承早期故障会让峭度值明显上升。你可能听说过“峭度越大,故障越重”的说法,但这句话有条件——早期故障阶段峭度确实增大,等故障发展到严重阶段,冲击淹没在强振动中,峭度反而可能下降,所以不能只靠单一特征做判断。
频域特征通过FFT变换得到频谱,从中可以观察故障特征频率及其谐波成分。比如轴承外圈故障特征频率BPFO、内圈故障特征频率BPFI可以通过轴承几何参数计算出来,如果频谱上对应位置出现峰值,就表明存在相应故障。包络谱是处理轴承故障的利器,它先对信号做带通滤波,再通过希尔伯特变换求包络,最后对包络做FFT,可以放大故障特征频率处的幅值,比直接看频谱更清晰。
特征计算的示例代码:
from scipy.fft import fft from scipy.signal import hilbert def extract_features(signal, fs): # 时域特征 rms = np.sqrt(np.mean(signal**2)) peak = np.max(np.abs(signal)) crest_factor = peak / rms kurtosis = np.mean((signal - np.mean(signal))**4) / (np.std(signal)**4) # 频域特征:FFT spectrum = np.abs(fft(signal)) freq = np.linspace(0, fs, len(spectrum)) dominant_freq = freq[np.argmax(spectrum[:len(spectrum)//2])] # 包络谱特征 envelope = np.abs(hilbert(signal)) envelope_spectrum = np.abs(fft(envelope)) return { 'rms': rms, 'crest_factor': crest_factor, 'kurtosis': kurtosis, 'dominant_freq': dominant_freq, 'envelope_peak_freq': freq[np.argmax(envelope_spectrum[:len(envelope_spectrum)//2])] }这一小节做下来,你已经把数据从原始振动信号变成了能喂给分类器的特征矩阵。这也是传统故障诊断流程的完整闭环。
4. 从特征到模型:两种主流建模方案
4.1 经典路线:特征 + 随机森林/SVM
传统建模方案的逻辑是把特征工程产出的特征向量作为输入,训练一个分类器完成故障类型识别。具体到我常用的做法,对每个窗口样本提取一组特征(时域+频域+包络谱,大约10到20个特征维度),组装成一个样本矩阵,然后交给分类器训练。
支持向量机(SVM)在样本量不大的时候表现稳定,尤其适合高维特征下的故障识别。需要注意的一点是SVM对特征尺度敏感,训练前一定要做标准化,否则量纲大的特征会主导分类结果。随机森林则对尺度不敏感,也不需要太多的参数调优,上手快、泛化能力不错。我自己调试CWRU分类任务时,随机森林在几百棵树的情况下准确率很快就能到95%以上,SVM用RBF核也能稳定在类似水平。
代码如下,直接用scikit-learn可以轻松完成:
from sklearn.ensemble import RandomForestClassifier from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # X_features 是特征矩阵,y_labels 是故障类别标签 scaler = StandardScaler() X_scaled = scaler.fit_transform(X_features) X_train, X_test, y_train, y_test = train_test_split( X_scaled, y_labels, test_size=0.3, random_state=42, stratify=y_labels ) rf_model = RandomForestClassifier(n_estimators=300, random_state=42) rf_model.fit(X_train, y_train) y_pred = rf_model.predict(X_test) print('随机森林准确率:', accuracy_score(y_test, y_pred))这时候要注意一个细节:train_test_split里我加了stratify=y_labels,也就是分层抽样,保证训练集和测试集中各个类别的比例和原始数据一致。如果不加这个参数,数据切分后某些类别在训练集中样本过少,模型容易出现偏向大类的问题。
4.2 深度学习路线:一维卷积网络直接处理原始信号
深度学习方案省去了手工设计特征的过程,让网络自己从原始信号里学习有用的特征表示,这在故障诊断领域已经是主流趋势。一维卷积网络(1D-CNN)是最常见的选择,它直接把切好的窗口样本作为输入,通过多层卷积和池化自动提取信号中的局部模式。
我的一个标准1D-CNN结构是这样设计的:输入层是1024×1的振动信号;第一层卷积核大小64、通道数16,加ReLU激活和最大池化;第二层卷积核大小32、通道数32;第三层卷积核大小16、通道数64;最后接全局平均池化和一个全连接分类层,输出类别数。这个结构的核心理念是先用大卷积核捕捉信号中的局部冲击特征,再用小卷积核细化特征,逐步压缩时间维度、增加通道维度。用PyTorch实现如下:
import torch import torch.nn as nn class FaultCNN(nn.Module): def __init__(self, num_classes): super().__init__() self.conv1 = nn.Sequential( nn.Conv1d(1, 16, kernel_size=64, stride=4, padding=32), nn.ReLU(), nn.MaxPool1d(2) ) self.conv2 = nn.Sequential( nn.Conv1d(16, 32, kernel_size=32, stride=2, padding=16), nn.ReLU(), nn.MaxPool1d(2) ) self.conv3 = nn.Sequential( nn.Conv1d(32, 64, kernel_size=16, stride=2, padding=8), nn.ReLU(), nn.AdaptiveAvgPool1d(1) ) self.fc = nn.Linear(64, num_classes) def forward(self, x): x = x.unsqueeze(1) # 添加通道维 x = self.conv1(x) x = self.conv2(x) x = self.conv3(x) x = x.squeeze(-1) x = self.fc(x) return x model = FaultCNN(num_classes=10)训练时我常用的配置是:优化器用Adam,学习率设0.001,批次大小64,训练轮数50到100轮。数据量够大的时候,这个模型在CWRU上很容易跑到97%以上准确率。但注意,高准确率不代表万事大吉——测试集和训练集来自同一工况、同一负载时,模型可以学到很多“数据集特有”的规律,换个工况准确率就会掉得很惨。
4.3 两条路线怎么选
| 对比维度 | 特征 + 分类器 | 1D-CNN直接吃原始信号 |
|---|---|---|
| 特征工程 | 需要手工设计,依赖经验 | 不需要,网络自动学习 |
| 数据量要求 | 少量样本即可 | 需要较多样本 |
| 计算开销 | 低,CPU可跑 | 高,建议GPU训练 |
| 可解释性 | 特征有明确物理意义 | 特征抽象,解释性弱 |
| 工业落地难度 | 相对容易,部署简单 | 模型较重,需要专门部署框架 |
我的建议是:如果你刚入行,或者项目周期紧、缺乏标注数据,先用特征+随机森林这类轻量方案跑通流程;如果你想冲击更高准确率,或者要在论文里展示方法的先进性,深度学习方案是必然选择。两条路线不是互斥的,实际项目中可以先做传统特征分析确定关键特征,再用深度模型进一步提取特征,形成互补。
5. 常见问题与避坑技巧实录
5.1 数据泄露:你练出来的高准确率很可能是假的
这是新手最容易犯的错误,也是最致命的。很多人做完滑窗切分后,把所有样本丢进train_test_split随机切分,表面看没问题,但实际上训练集和测试集里可能包含来自同一条原始信号的不同窗口样本。这些窗口彼此之间只差几毫秒甚至几十毫秒,高度相似,模型相当于在“背答案”而不是“学规律”,测试准确率虚高,换个独立采集的数据马上就露馅。
正确的做法是按“原始信号段”划分数据,即属于同一条连续信号的窗口要么全部进训练集,要么全部进测试集,绝不交叉。在代码上可以通过GroupShuffleSplit实现分组切分,或者把不同故障样本的编号作为分组依据。我在给实验室同学做代码评审时,经常会问一句“你的数据分组分组了吗?”——这一问就能拦住一半以上准确率虚高的问题。
5.2 类别不平衡怎么办
公开数据集虽然比工业现场数据规范,但类别不平衡问题一样存在。比如某些数据集中,正常状态的样本远多于故障状态样本,或者某些故障类型因为损伤尺寸小、信号微弱,难以准确识别。这时候如果直接按原始比例训练,模型会把弱类别忽略掉,整体准确率看起来很高,但强类别主导了结果。
处理方式有几种:一是欠采样,从多数类中随机抽取部分样本,让各类数量接近;二是过采样,对少数类使用SMOTE等方法合成新样本;三是代价敏感学习,在损失函数里给少数类错误分类更高的权重。实操中我倾向于先用过采样保证类别均衡,然后配合分层抽样做训练测试划分,两个步骤结合使用效果比较稳。
5.3 变工况迁移:实验室效果好,现场怎么就不行
这是公开数据集应用中最容易被忽视的一点。在CWRU上训练的模型,换个负载条件(比如从0 HP换成3 HP)测试,准确率就会下降;如果换到另一个数据集上,下降更明显。原因很简单:不同工况下设备的转速、载荷不同,振动信号的幅值和频率分布都会改变,模型学到的特征在新条件下失去适用性。
解决思路通常是迁移学习,包括领域自适应、对抗训练等方向。工程上更实际的先做数据增强:把训练数据中的信号添加轻微噪声、随机缩放幅值、改变相位,让模型对工况变化不那么敏感。但说实话,公开数据集上做的变工况实验,距离真正工业多工况部署还有不少差距,这点要有清醒认知。
5.4 别被“公开数据集跑分”迷惑
最后说一个心态问题。很多人看到某个方法在公开数据集上准确率99.8%,就不假思索地跟风复现,然后拿来用在自己的数据上,结果惨不忍睹。公开数据集有一个共性特点:数据是精心整理过的,故障类型明确、标签准确、信号清晰,而真实工业数据往往噪声大、故障模式复杂、标签不完整甚至错误。公开数据集适合做方法验证和学术对比,但绝不能把它等同于真实工业现场的复杂度。
我现在拿到任何一篇论文,先看它用什么数据集验证,再看它有没有做跨工况实验,最后才看准确率数字。公开数据集跑分可以说明方法的潜力,但真正决定方法价值的是它能不能在你自己收集的现场数据上泛化。所以我的建议是:公开数据集用来训练基本功、验证算法思路、建立对比基准,同时一定要想办法接触真实的工业现场数据,哪怕数据很脏、标签很乱,处理那些数据的过程中学到的经验,才是这个领域最值钱的部分。
综合我自己这几年的体会,公开数据集像是一根拐杖,学走路的时候离不开,但最终要能自己走。在CWRU上把整个流程从数据读取、预处理、特征提取到模型训练完整走一遍,你会对机械故障诊断有个整体认知;再用IMS和PHM2012做进阶练习,理解全寿命周期数据和工况对模型的影响。到这个时候,你再看真实工业场景里的数据问题,就会多一分从容。
本文还有配套的精品资源,点击获取