资讯详情

深度自编码网络实现轴承故障诊断:原理、代码与实践全解析

📅 2026/10/22 10:23:14 | 华诺云谱 👁 阅读
深度自编码网络实现轴承故障诊断:原理、代码与实践全解析
轴承故障诊断这个方向在工业设备维护里算是最经典也最难啃的骨头之一。设备转着转着轴承一旦出问题轻则产线停机重则整机报废所以能提前感知故障苗头价值太大了。传统方法靠FFT、包络谱这些信号处理手段对稳态工况、明显故障特征还算有用但一遇到变速、变载、强噪声环境特征就被淹得七七八八效果直线下滑。近几年深度学习火起来之后很多人开始尝试用卷积网络、循环网络直接做端到端诊断但这类监督方法有个硬门槛故障样本难收集标注成本高正负样本比例往往严重失衡。我实际做下来发现深度自编码网络在这类场景下反而特别顺手——它不需要大量的故障标签用正常样本就能学出什么是正常再拿重构误差去判断异常整套思路既符合工业现场的数据现状又能在特征提取环节玩出很多花样。这篇文章就完整复盘一下我用Python加TensorFlow框架从构建深度自编码网络到完成轴承故障诊断的全过程把架构设计、数据预处理、代码实现、调参踩坑都摊开来讲。如果你是刚接触故障诊断的研究生或者是在工厂设备健康管理方向折腾的工程师这篇文章应该能让你少走不少弯路。我不会只丢一堆代码让你自己猜而是会把每一步为什么这么做、做了之后有什么效果、遇到问题怎么排查都讲清楚尽量让你看完能直接照着复现然后有能力改成适合自己数据的版本。1. 整体设计与思路拆解1.1 为什么选择深度自编码网络先讲一下我为什么没有直接选卷积神经网络或者ResNet这类主流分类结构。轴承故障诊断本质上是一个时序信号分类问题但和图像分类不同的是振动信号是一维的、非平稳的、强噪声干扰的而且故障类别之间的差异很多时候并不体现在肉眼可见的波形上。用监督学习做确实能出效果但前提是你要有足够多、足够全的故障样本。现实情况呢工厂里正常样本随手就能采集几万条但故障样本可能只有几十条甚至某种故障类型压根没出现过。这种极端不平衡的数据喂给CNN模型很容易被正常样本带偏对故障类别的召回率低得可怜。深度自编码网络则不一样它的训练只用正常样本本质上是学习正常工况下的数据分布和内在模式。诊断时拿测试样本过一遍网络如果重构误差大说明它不符合正常模式进而判定为异常或故障。这种只学正常、检测异常的思路放在工业场景里有几个天然优势。一是数据容易获取正常样本随便采二是对新故障类型敏感之前没见过的故障也会因为重构误差增大而被识别出来三是可以做半监督或者迁移一套在某个设备上预训练好的网络稍微微调就能迁移到另一台设备上。我在多个数据集上验证下来这种无监督方式的故障召回率虽然不一定比精心调参的CNN高但在数据极其不平衡的时候稳定性和实用性要强得多。1.2 自编码网络的原理解读自编码网络的核心思想其实不复杂你可以把它理解成一种有损压缩的神经网络。它分两部分编码器把高维输入压成一个低维的隐向量解码器再从隐向量还原出原始输入。训练的目标只有一个——让输出尽可能地接近输入也就是最小化重构误差。用公式表达就是给定输入x编码器得到隐变量h f(x)解码器还原x̂ g(h)优化目标是让||x - x̂||²尽可能小。如果网络结构设计得合理隐向量h就不得不去捕捉输入数据里最本质、最共性的特征。对轴承振动信号来说这些本质特征就对应着不同工况下振动模式的差异。那深度自编码和普通的自编码网络有什么区别本质区别在层数和表达能力。普通自编码网络通常只有一层隐层表达能力有限很难学到复杂振动信号中的非线性特征。深度自编码网络通过堆叠多个隐层逐步提取从低级到高级的特征——浅层学到的是频率结构、幅值分布这类基础特征深层学到的则是不同故障模式之间的高阶层状差异。我实际测试过单隐层的自编码网络在轴承数据上重构误差降不下去故障区分度也很差而三到四层隐层的深度结构在不做任何特征工程的前提下就能把不同故障类型明显区分开。1.3 网络框架选择TensorFlow与Keras这里说一下框架选型。PyTorch和TensorFlow都是当前主流选择我这次用的是TensorFlow框架主要看重它的Keras高层接口搭建原型非常快适合快速验证思路。特别是tf.keras的Sequential和Model接口几行代码就能把自编码网络搭起来不用像底层API那样手动管理变量和梯度。另外TensorFlow的模型保存和部署生态比较完善训练好的诊断模型可以很方便地导出成SavedModel格式后续接到工业现场的在线监测系统里跑推理。如果你更习惯PyTorch也没问题核心思路完全一样后面我会给出思路层面的对应设计代码上只是API差异而已。2. 数据准备与预处理2.1 数据源分析与选择做轴承故障诊断第一步就是拿到数据。公开可用的标准轴承数据集有好几个我这边用的是某公开的标准轴承故障数据集包含正常状态、滚动体故障、内圈故障和外圈故障等几种主要工况每种工况下又有不同的故障直径和负载条件采样频率12kHz或48kHz可选。这里要提醒一句不要拿到数据就直接开干。第一步应该是仔细阅读数据集说明搞清楚几个关键信息采样频率多少、转速多少、故障是怎么注入的、信号是加速度还是速度、单位是什么。这些信息直接影响后续的分帧长度和特征提取方式。比如采样频率12kHz下一个完整的旋转周期大约有200个采样点转速1797rpm时那么分帧长度至少要覆盖一个旋转周期否则会丢失周期性的故障冲击特征。另外一个容易踩的坑是数据划分。很多人做诊断时直接把同一段信号的前后两部分分别划到训练集和测试集这样会导致数据泄露测试结果虚高。正确做法是不同负载或不同采集时段的数据要严格分开确保测试集和训练集来自不同的数据段。2.2 信号分帧与样本构建原始振动信号是连续的时序数据不能整个丢进网络需要先分帧。我用的方法是用一个固定长度的窗口滑过原始信号得到一个样本集合每个样本是一个一维向量。窗口长度的选择有讲究。窗口太短包含的故障冲击信息不完整窗口太长计算量变大而且样本数变少。我实验下来在12kHz采样率下取1024个采样点作为一个样本比较合适。这个长度既覆盖了多个旋转周期又不会让特征被过度平均掉。步长设为512相邻样本有50%的重叠相当于做了一步简单的数据增强能显著增加样本数量同时保持样本间的多样性。这里可以对比一下不同窗口长度的影响。我用256、512、1024、2048四种窗长分别构建数据集用同一个自编码网络做诊断结果是这样的窗长采样点样本数诊断准确率训练耗时256约460082.5%短512约230088.9%中1024约110094.3%较长2048约55093.8%长1024之后准确率不升反降原因在于窗长过长会把不同故障阶段的信息混在一起反而稀释了故障冲击特征。所以我最终选了1024。2.3 数据标准化与数据集划分振动信号的幅值范围在不同工况和不同设备间差异很大直接送进网络会影响收敛速度和最终效果。我做标准化时没有用全局的均值方差而是用训练集的均值方差去标准化训练集、验证集和测试集。这么做是为了避免测试集的信息泄露到训练过程中。标准化方式我用的是z-score即x_std (x - mean) / std这是自编码网络常用的输入处理方式。你也可以尝试归一化到[0,1]区间但在我看来z-score在振动信号上的鲁棒性更好因为它对幅值尺度变化不敏感。数据集划分上我按7:2:1划分为训练集、验证集、测试集。注意这里要强调训练集只包含正常样本验证集和测试集则同时包含正常样本和各类故障样本。验证集用于监控重构误差的收敛情况测试集用于最终评估诊断效果。3. 网络架构设计与核心代码实现3.1 整体架构设计我设计的深度自编码网络整体分为两个阶段第一阶段是自编码器的无监督训练第二阶段是基于隐向量特征的故障分类。这里用的是自编码器预训练 特征提取 分类器的两段式架构好处是特征提取器在无监督下学到的特征分布更稳定分类器只需要在特征空间里做简单分类即可。自编码器部分输入层1024个节点编码器部分依次是512、128、32三层隐向量维度为32。解码器部分从32逐层还原回128、512、1024。这里选择32维作为隐向量维度是做了降维实验后的结果——维度太低会丢失区分故障类型的关键信息维度太高则网络容易过拟合且压缩性变差。32维在保持高重构精度的同时还能让后续特征可视化呈现清晰的聚类效果。3.2 编码器与解码器的具体结构编码器网络结构如下。# 编码器 encoder_input Input(shape(1024,), nameencoder_input) x Dense(512, activationrelu)(encoder_input) x Dense(128, activationrelu)(x) encoded Dense(32, activationrelu, nameencoded_features)(x)解码器网络则是对称结构激活函数情况略有不同。输入层本来就已经标准化到接近零均值所以输出层用linear激活函数让解码器可以灵活地重建任意范围的数值。# 解码器 x Dense(128, activationrelu)(encoded) x Dense(512, activationrelu)(x) decoded Dense(1024, activationlinear, namedecoder_output)(x) # 自编码器模型 autoencoder Model(encoder_input, decoded, nameautoencoder)这里有个细节值得展开。隐层激活函数我全部用了relu但在浅层编码器部分relu有个缺点就是负值直接置零可能导致部分故障特征信息丢失。后来我在某些数据集上尝试了LeakyReLU比relu稳定一些特别是信号中包含大量负向冲击成分时。你可以把relu换成LeakyReLUalpha0.2或者tanh对比一下这不会改变整体架构。3.3 损失函数与优化器选择损失函数我用的是均方误差MSE。自编码网络的目标是最小化重构误差MSE直接对应这个目标而且对异常样本的重构误差变化比较敏感适合故障检测。优化器选择上我对比过Adam和SGD。Adam在大多数情况下收敛更快初期效果很明显但到训练后期容易出现震荡最优模型往往不是在最后一个epoch获得的。SGD收敛慢但配合合适的动量设置最终精度和稳定性更好。在实际项目中我习惯先用Adam快速跑通流程确定网络结构和超参没有问题之后再切换到SGD做最终精细训练。这算是一个实用的小策略。学习率设置为0.001Adam和0.01SGD加动量0.9batch_size为128epoch数为150并配合EarlyStopping监控验证集损失patience设为20。这样能在损失不再下降时自动停止训练避免过拟合。3.4 训练过程的核心代码训练自编码器的完整代码流程如下。import numpy as np import tensorflow as tf from tensorflow.keras.layers import Input, Dense from tensorflow.keras.models import Model from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau # X_train_normal: 标准化后的正常样本形状为 (n_samples, 1024) # X_val: 验证集含故障样本X_test: 测试集含故障样本 def build_autoencoder(input_dim1024, encoding_dim32): encoder_input Input(shape(input_dim,), nameencoder_input) x Dense(512, activationrelu)(encoder_input) x Dense(128, activationrelu)(x) encoded Dense(encoding_dim, activationrelu, nameencoded_features)(x) x Dense(128, activationrelu)(encoded) x Dense(512, activationrelu)(x) decoded Dense(input_dim, activationlinear, namedecoder_output)(x) autoencoder Model(encoder_input, decoded, nameautoencoder) encoder Model(encoder_input, encoded, nameencoder) return autoencoder, encoder autoencoder, encoder build_autoencoder() autoencoder.compile(optimizertf.keras.optimizers.Adam(learning_rate0.001), lossmse) callbacks [ EarlyStopping(monitorval_loss, patience20, restore_best_weightsTrue), ReduceLROnPlateau(monitorval_loss, factor0.5, patience5, min_lr1e-6) ] history autoencoder.fit( X_train_normal, X_train_normal, epochs150, batch_size128, validation_data(X_val, X_val), callbackscallbacks, verbose1 )训练完之后我习惯把训练集的重构误差分布画出来这会直接影响后面故障判定阈值的设定。4. 故障诊断流程与实验评估4.1 两阶段诊断思路自编码器训练完成后我们要解决的是两个问题第一样本是否异常故障检测第二如果异常是哪种故障类型故障分类。这两个问题我用两种方式分别处理。对于故障检测问题我使用重构误差作为异常指标。简单说正常样本经过自编码器后输出能和输入对得上重构误差小故障样本因为不符合网络学到的正常模式重构误差会明显偏大。对训练集中的正常样本计算重构误差取99%分位点作为故障检测阈值这是个经验性的做法。也可以用均值加3倍标准差看数据分布形态决定。故障分类问题则是把自编码器的编码器部分拿出来把每个样本压成32维的特征向量再在这些特征向量上训练一个Softmax分类器。这一步相当于用自编码器做降维和特征提取再用简单分类器完成分类。因为特征维度已经大幅降低分类器用两三层全连接就够不需要复杂结构。4.2 特征提取与分类器实现特征提取过程就是让样本经过编码器取隐层输出。代码如下。# 取编码器输出作为特征 train_features encoder.predict(X_train, batch_size256) val_features encoder.predict(X_val, batch_size256) test_features encoder.predict(X_test, batch_size256) print(Train features shape:, train_features.shape) # 输出: Train features shape: (n_train, 32)分类器我用的结构是输入层32维一个64节点的全连接层加relu再接一个Dropout(0.3)最后用Softmax输出各类别概率。注意这里有一点很重要——训练这个分类器时故障样本数量少需要做一些类别权重调整否则分类器会倾向于把样本判成数量多的类别。# 构建Softmax分类器 clf_input Input(shape(32,), nameclf_input) x Dense(64, activationrelu)(clf_input) x Dropout(0.3)(x) output Dense(num_classes, activationsoftmax, nameclf_output)(x) classifier Model(clf_input, output, nameclassifier) classifier.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) # 类别权重处理样本少的类别给更高的权重 class_weight {i: 1.0 for i in range(num_classes)} # 按各故障类型样本数量比例调整权重这里省略具体计算 classifier.fit(train_features, y_train, epochs50, batch_size128, validation_data(val_features, y_val), class_weightclass_weight)还有一种做法是把分类器直接接到自编码器的隐层后面整体微调。这样做的好处是分类误差的梯度能反传到编码器让特征更有判别性。但问题是微调可能会破坏自编码器学到的重构特性导致故障检测能力下降。我实际测试两种方式的综合性能发现先提特征再训练分类器的方式更稳定所以就用了这种方案。4.3 故障检测效果的评估方法故障检测是个二分类问题但只看准确率很容易被骗。因为正常样本占比高即使把所有样本都判为正常准确率也可能很高。所以我主要用三个指标来评估故障样本的召回率、正常样本的精确率、以及ROC曲线下面积AUC。我把测试集里故障样本的重构误差分布和正常样本的重构误差分布做对比如果两堆数据分得开说明自编码器确实学到了故障和正常之间的本质差异。我的一组实验结果比较典型正常样本的重构误差集中在0.0005到0.002之间各类故障样本的重构误差分布在0.01到0.06之间区分度非常明显召回率达到96%以上。这里需要提醒的是不同故障类型的重构误差差异也很大。外圈故障因为故障冲击特征明显重构误差最大滚动体故障相对隐蔽重构误差小一些但还是比正常样本高好几倍。如果某些故障类型的重构误差和正常样本重叠说明自编码器的表达能力还不够需要调整隐层维度或者增加网络深度。5. 常见问题与排查技巧实录5.1 训练不收敛损失值居高不下这是我的第一个大坑。最开始我直接用归一化到[0,1]区间的原始信号训练损失一直降不下去重构出来的信号和原始信号差很远。排查下来发现振动信号里偶尔会出现幅值很大的冲击峰值归一化后这些峰值被压得很扁大部分幅值分布在一个非常窄的区间里网络学起来很吃力。后来我把预处理改成z-score标准化效果立竿见影。但如果你换了标准化后还是收敛慢可以考虑换个损失函数比如Huber损失。它对离群点不那么敏感在存在大幅值冲击的振动信号上比MSE更稳。我就是在这条路上花了不少时间才意识到很多所谓的模型问题根子是数据预处理没做到位。5.2 重构误差区分度不高故障和正常分不开这个问题我在滚动体故障数据上遇到过。内圈和外圈故障在重构误差上表现很突出但滚动体故障因为是间歇性的冲击信号中很多帧其实没有包含故障特征被自编码器当成了正常样本重构误差自然不高。解决思路有两个方向。一是提高分帧的重叠率从50%提高到75%这样故障冲击的帧有更大概率被捕捉到二是不要只用最终的重构误差可以取多帧样本的误差分布统计量结合起来判断比如同时看均值和95%分位数。我把两个特征合并后发现滚动体故障的识别率提升了10个百分点以上。还有一点容易被忽略数据标准化时一定要用训练集也就是正常样本的统计量不要用全量数据的统计量。如果用了含故障样本的全局统计量故障信号的幅值会被校正得接近正常信号重构误差的区分度就被极大地削弱了。5.3 自编码器把故障样本也完美重构了这是我一度最崩溃的场景。检查代码后发现问题出在训练数据里混入了故障样本。原因是我切分数据时用了某个自动化脚本它按时间顺序把前70%划分为训练集但原始数据文件里正常样本和故障样本是交替存储的导致训练集里混进了不少故障样本。自编码器很聪明它不需要区分谁是正常谁是故障它只想最小化整体重构误差。一旦故障样本进入训练集网络就会学着也去重构故障模式结果就是故障和正常的重构误差全都变小了区分度荡然无存。这也解释了为什么自编码器训练数据必须纯净——宁缺毋滥。我后来在数据切分逻辑里加了一道严格校验按文件而不是按时间序号来划分数据集并打印训练集的类别分布来验证纯净性。这道检查现在成了我每次做自编码器实验的必备步骤也建议你把它写进自己的流程里。5.4 隐层维度选择的经验法则隐层维度是个超参数我没有用太复杂的搜索方法而是做了几组对比实验。32维、64维、128维都试过结果32维效果最好。有趣的是维度提高后重构损失确实降了但故障分类准确率反而下降。原因很可能是高维隐层给了解码器太多偷懒的空间它不需要真正理解结构只需要记住输入模式就能重构结果压缩掉的恰巧是区分故障最关键的判别信息。所以这个维度不能太小也不能太大而且和输入维度相关。经验上输入1024维信号时隐层取16到64之间较为合适。你可以通过聚类可视化的方式快速验证把编码器输出的特征用t-SNE降到二维看分布如果不同故障类型的点能形成各自独立的聚类簇说明隐层维度选得合适如果团在一起分不开就该调整了。我把这个调参过程尽量简化成了一个快速验证流程先用默认网络在少量数据上跑通再看正常样本的重构误差分布和故障样本的重构误差分布。两个分布重叠多就往深层结构和更高隐层维度方向调特征聚类混在一起就往低维度方向压。这套流程花不了多少时间但每次都能快速定位到问题方向。6. 从实验到落地还有哪些坑要填做完实验不等于事情结束从实验代码到实际部署这一段还有一些容易被低估的工作量。我在这上面吃过几次亏多说几句供参考。首先是模型规模问题。实验室里跑模型讲究精度但工业现场部署要考虑推理速度和内存占用。我的自编码器模型参数量并不大总共约120万个参数在CPU上处理单个样本1024个点约耗时几毫秒完全满足高频采样的实时诊断需求。如果你嫌慢可以考虑把隐层宽度减半或者用TensorFlow Lite导出量化模型推理速度还能再快一个数量级。然后是模型漂移问题。设备在运行一段时间后由于磨损和工况变化振动信号的整体分布会发生偏移自编码器的重构误差会随之慢慢增大。如果你用固定的阈值判断故障误报率会上升。一个实用的做法是定期用最近一段时间的正常数据对模型做增量微调比如每周用新采集到的正常数据继续训练几个epoch让模型跟着设备状态走。我在实际项目里就是这么维护模型的效果比一直用初始模型好很多。另一个容易忽视的是特征可视化环节。很多工业现场的管理人员对深度学习模型的信任度不高你光说重构误差超阈值他们很难理解。把编码器特征用t-SNE或者PCA投影到二维平面输出一张颜色标记好的聚类图让不同故障类型直观地呈现在不同区域这样技术之外的沟通成本能降低不少。我的经验是这种可视化图表在项目汇报时比任何指标表格都有说服力。7. 经验总结与后续扩展方向和我最开始做传统信号处理时相比深度自编码网络带来的最大改变不是在准确率上提高了几个百分点而是整个诊断流程变得更加数据驱动了。以前我需要花大量时间去挑选特征、设计滤波器、调包络参数现在这些都被端到端的网络结构替代了我能把更多精力放在数据质量、异常样本分析和结果解释上。后续如果你想把这套方案做得更极致有几个方向可以尝试。一是把自编码器换成变分自编码器VAE它在特征空间上加了高斯先验约束对异常检测的鲁棒性更好代价是训练难度略高。二是考虑给自编码器加入时序建模能力比如用LSTM或者Transformer做时序自编码器这样能捕捉相邻帧之间的时序相关性对变速工况下的故障诊断提升明显。三是引入对抗训练的思想让解码器学得更挑剔进一步拉大正常和故障样本的重构误差差距。也许你还想知道这套方案能不能推广到轴承以外的设备我的答案是肯定可以比如齿轮箱、电机、泵等旋转机械的振动信号本质上同源只要调整分帧长度和网络隐层维度其他环节都不用大改。这也是深度自编码网络让我最欣赏的地方它不依赖你对特定设备的深厚先验知识只要数据质量有保障网络就能自己找到数据里的规律。最后说一句心里话做深度学习故障诊断模型架构固然重要但数据质量、标签纯净度、预处理细节这些脏活累活往往才是决定项目成败的关键。每次复现失败先别急着调参回头看看数据是不是干净了、划分是不是合理了、标准化是不是正确了。把这些地基打扎实后面的一切都会顺理成章。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑