
简介振动信号分析是机械设备状态监测与故障诊断的核心手段而高质量的公开数据集是算法验证和工程落地的基础。从最基本的时域特征如均方根值、峭度到频域包络谱分析再到基于一维卷积神经网络的深度学习方法都离不开规范、可复现的实验数据。CWRU、IMS、PHM2012等主流公开数据集为研究者提供了统一对比基准覆盖轴承内圈、外圈、滚动体故障及全寿命退化数据支撑故障分类、剩余寿命预测等典型任务。合理选择数据集、掌握信号预处理与滑动窗口切分技巧并警惕数据泄露与变工况迁移问题是提升诊断模型泛化能力的关键。本文系统梳理了公开数据集选型、特征工程、建模路线及常见避坑指南帮助初学者快速上手机械故障诊断实战。 搞机械故障诊断这个方向不管你是做学术研究的还是做工业落地项目的第一个绕不过去的坎就是数据。我自己入坑那会儿最发愁的不是算法不会写而是找不到一套靠谱的“机械故障诊断公开数据集”用来验证方案。设备正常跑着的信号好采集但故障状态下的信号真不是你想拿到就能拿到的——产线不能为了做实验就停摆设备更不会按你的需求去坏。所以公开数据集在这个领域里地位一直很特殊它既是学术研究公认的“比武擂台”又是新手入行最快的“练习场”。这篇东西我想认真聊一聊机械故障诊断公开数据集的那些事包括主流的几个数据集到底怎么选、数据拿回来之后怎么预处理、怎么用它们训练出有效的诊断模型以及我踩过的那些坑。内容偏向实操代码和参数我都会给出来适合刚接触这个方向的硕士生、转行做工业AI的工程师以及想在企业内部快速搭建一套诊断验证流程的技术人员。我会尽量把当年自己摸索时浪费的时间帮你省掉。1. 为什么故障诊断离不开公开数据集1.1 工业现场数据为什么那么难获取先说个现实问题。机械设备故障诊断要落地本质上靠的是“数据 算法”但数据这一环在真实工业场景里往往是最薄弱的部分。故障数据为什么稀缺首先设备发生故障是小概率事件大部分轴承、齿轮在正常维护条件下能跑很久你不可能为了采集故障样本故意把设备弄坏——那成本谁也扛不住。其次即使现场真的发生了故障完整的信号记录也不一定保得住很多老产线根本没有在线监测系统故障发生了才知道运行过程中的振动信号、温度曲线早就没了。就算运气好企业有一套状态监测系统也还有标签问题。设备是几点几分开始出现早期故障的退化到哪个阶段就该停机这些标签依赖老师的经验判断不同人打出来的标签可能都不一样标准很难统一。再加上很多工厂的数据涉及工艺参数、设备产能信息在保密协议约束下外部研究人员根本碰不到原始数据。我见过太多校企合作项目前三个月全耗在数据对接和清洗上真正做算法的只有一个多月这就是工业数据现状的缩影。1.2 公开数据集给这个领域带来了什么公开数据集恰好在这个环节上补了位。它的价值可以从三个层面来看第一是提供统一对比基准。所有研究者用同一份数据、同样的故障类型、同样的工况参数算法的优劣才能放在一个公平环境里比。没有这套基准你说你的方法准确率99%我说我的方法准确率99.5%各自找的数据都不一样讨论就没有意义。第二是大幅降低入门门槛。做故障诊断这个方向没必要每个人都有机会去现场拆一台电机、装一堆传感器。公开数据集把传感器布置方案、采样频率、加载工况和故障标签都标得清清楚楚初学者拿回数据就能上手跑流程理解整个诊断链路。第三是支持算法的可复现性。论文里写“提出了一种基于某某网络的新型诊断方法”如果用的公开数据别人就能下载数据复现实验这对学术交流和产业评估都有帮助至少可以通过在同一数据集上的效果横向比较来判断一个算法到底行不行。2. 主流数据集盘点与选型建议2.1 CWRU故障诊断圈的“MNIST”如果你在故障诊断领域只听说过一个数据集那大概率是西储大学Case Western Reserve UniversityCWRU的滚动轴承数据集。这个数据集的历史很悠久由西储大学电气工程实验室搭建实验台采集数据用加速度计分别在驱动端和风扇端采集振动信号采样频率常见的有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_size1024, stride512): 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_size0.3, random_state42, stratifyy_labels ) rf_model RandomForestClassifier(n_estimators300, random_state42) rf_model.fit(X_train, y_train) y_pred rf_model.predict(X_test) print(随机森林准确率:, accuracy_score(y_test, y_pred))这时候要注意一个细节train_test_split里我加了stratifyy_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_size64, stride4, padding32), nn.ReLU(), nn.MaxPool1d(2) ) self.conv2 nn.Sequential( nn.Conv1d(16, 32, kernel_size32, stride2, padding16), nn.ReLU(), nn.MaxPool1d(2) ) self.conv3 nn.Sequential( nn.Conv1d(32, 64, kernel_size16, stride2, padding8), 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_classes10)训练时我常用的配置是优化器用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做进阶练习理解全寿命周期数据和工况对模型的影响。到这个时候你再看真实工业场景里的数据问题就会多一分从容。本文还有配套的精品资源点击获取