卷积神经网络如何重塑齿轮箱状态监测:从振动信号到故障诊断

发布时间:2026/9/19 16:24:21
卷积神经网络如何重塑齿轮箱状态监测:从振动信号到故障诊断 简介面向风力发电运维、设备健康管理及工业智能诊断方向这份PDF聚焦基于卷积神经网络的齿轮箱状态监测方法利用SCADA数据与振动信号构建状态矩阵参考VGGNet设计规模更小的CNN结构以3×3卷积核、最大池化和softmax分类器完成特征提取与状态判断实测识别精度达96.3%并验证模型可迁移至同风场其他机组具备较强泛化能力。文档还对比了线性调频小波分解、VMD、BP神经网络、SVM等传统方法的局限便于读者理解深度学习在工业数据建模中的优势。这类方法有助于从运行数据中提早发现齿轮箱异常减少停机损失对风电场智能运维具有参考价值。资源为单份PDF文档共1个文件压缩包大小351KB内容精炼适合快速通读。目前已有171人学习适合相关专业研究生、风电运维工程师及对深度学习状态监测感兴趣的技术人员参考。1. 为什么齿轮箱状态监测要把赌注压在卷积神经网络上风电齿轮箱是整机传动链里故障成本最高的部件换一台大兆瓦齿轮箱的费用往往抵得上机组小半年的发电收益。过去靠振动幅值、油液颗粒度做阈值报警误报和漏报交替出现根本原因是齿轮箱振动信号在变转速、变负载工况下高度非平稳传统特征量守不住边界。卷积神经网络的价值在于把特征提取和分类做成一个端到端的映射从原始振动波形或时频图里自动学出齿面磨损、断齿、轴承点蚀对应的模式不再依赖人工经验去挑选特征频段。这篇文章按实际工程落地的顺序展开讲清楚数据怎么准备、网络怎么选、参数怎么调、结果怎么验证适合已经跑过传统信号处理、想往深度学习监测方向转的工程师。2. 从振动信号到训练集卷积神经网络状态监测的数据准备2.1 行星齿轮箱数据集与故障类型标签齿轮箱状态监测训练数据的来源无非三条路试验台实测、机组SCADA振动数据、仿真数据。试验台数据是首选因为故障类型和退化程度是已知的。常见做法是用行星齿轮箱试验台在齿根、齿面、轴承座布置加速度传感器采样率设在20kHz到50kHz之间转速从额定转速的60%到110%分档采集负载按额定扭矩的25%、50%、75%、100%切换。这样采集得到的数据才能覆盖机组实际运行时的工况范围模型才不会只在某个转速下有效。数据标注要明确到故障位置和损伤级别一般按以下方式组织标签故障位置损伤程度样本建议量0正常无2000段以上1齿面磨损轻微/中度/严重每级800段以上2齿根裂纹早期/扩展期每级600段以上3行星轮轴承点蚀早期/中期每级600段以上4输入级断齿完全断裂500段以上样本量不足时把每段原始信号按重叠比例切片是扩大样本量的有效手段。仿真数据可以作为补充用动力学模型生成不同故障状态下的振动响应但要注意仿真信号和实测信号之间存在频响差异直接用仿真数据训练的模型在真实机组上会打折扣迁移学习是后话这里先把实测数据做足。2.2 滑动窗口切分与二维时频图生成拿到原始振动数据后第一件事不是建模型而是切窗。切窗要同时考虑两个约束窗口长度至少要覆盖齿轮轴回转周期的整数倍这样故障冲击的周期性才能完整保留窗口太短则频率分辨率不够窗口太长则样本数骤减。经验值是窗口长度取0.5秒到1.5秒相邻窗口重叠率50%到75%。import numpy as np def sliding_window(data, fs, win_sec1.0, overlap0.5): 对长序列振动数据进行滑窗切分 data: 一维振动信号数组 fs: 采样率单位Hz win_sec: 窗口时长单位秒 overlap: 重叠率0~1之间 win_len int(fs * win_sec) step int(win_len * (1 - overlap)) if step 1: raise ValueError(overlap过大会导致步长小于1) samples [] for start in range(0, len(data) - win_len 1, step): samples.append(data[start:start win_len]) return np.array(samples) # 示例对一段30秒的20kHz振动数据切窗窗口1秒重叠50% # raw_signal 为已读入的numpy数组 # windows sliding_window(raw_signal, fs20000, win_sec1.0, overlap0.5)切窗之后要决定喂给卷积神经网络的输入形式。原始一维波形直接输入1D-CNN是最简单的路径但2D-CNN配合时频图往往能获得更好的抗噪能力。from scipy.signal import spectrogram import matplotlib.pyplot as plt import numpy as np def save_spectrogram(data, fs, save_path): 将一维振动信号转换为时频图并保存为灰度图 供二维卷积神经网络使用 f, t, Sxx spectrogram(data, fsfs, nperseg1024, noverlap512) # 转换为对数刻度并归一化到0~255 Sxx_db 10 * np.log10(Sxx 1e-12) Sxx_norm (Sxx_db - Sxx_db.min()) / (Sxx_db.max() - Sxx_db.min() 1e-12) img (Sxx_norm * 255).astype(np.uint8) plt.imsave(save_path, img, cmapgray)时频图用短时傅里叶变换生成nperseg设为1024在20kHz采样率下对应频率分辨率约19.5Hz对于齿轮啮合频率和边频带的观察足够了。适配热词“行星齿轮箱数据集”的直觉判断在这里公开的行星齿轮箱数据集常以原始振动波形形式发布你需要自己切窗、生成时频图不要指望数据集自带可直接训练的图片格式。3. 一维卷积还是二维卷积CNN模型选型与结构设计3.1 1D-CNN处理原始振动序列的典型结构先用1D-CNN直接处理原始振动波形它最贴合热词“cnn卷积神经网络”的基本结构直觉输入层、卷积层、池化层、全连接层、输出层。对振动信号这类一维时间序列卷积核沿时间轴滑动自动学习不同尺度的局部波形特征。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv1D, MaxPooling1D, Flatten, Dense, Dropout def build_1dcnn(input_len20000, num_classes5): 构建1D-CNN振动状态分类模型 input_len: 输入窗口长度 num_classes: 故障类别数 model Sequential([ Conv1D(filters64, kernel_size64, strides8, activationrelu, input_shape(input_len, 1)), MaxPooling1D(pool_size4, strides4), Conv1D(filters32, kernel_size32, strides4, activationrelu), MaxPooling1D(pool_size4, strides4), Flatten(), Dropout(0.4), Dense(100, activationrelu), Dense(num_classes, activationsoftmax) ]) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) return model第一层卷积核的kernel_size值得细说。振动冲击信号的持续时间通常在毫秒级20kHz采样率下1毫秒对应20个采样点所以kernel_size64能覆盖约3.2毫秒的波形足以捕捉一次冲击的完整轮廓。strides设为8相当于在保持感受野的同时压缩序列长度。池化层用最大池化因为故障冲击在时域表现为幅值突跳取局部最大值比取平均更能保留冲击特征。3.2 2D-CNN时频图与加入注意力机制的改进如果按2.2节把数据转化成了时频图那么模型的输入从一维序列变成二维图像。齿轮箱的正常与故障状态在时频图上的纹理差别比在时域波形上更直观正常状态下能量集中在啮合频率及其谐波上故障后边频带变密、能量扩散。2D-CNN擅长捕捉图像的空间纹理模式所以这类做法通常比1D-CNN更稳健。from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout from tensorflow.keras.layers import GlobalAveragePooling2D, Reshape, Dense def build_2dcnn(img_shape(256, 256, 1), num_classes5): inputs Input(shapeimg_shape) x Conv2D(32, (3, 3), paddingsame, activationrelu)(inputs) x MaxPooling2D((2, 2))(x) x Conv2D(64, (3, 3), paddingsame, activationrelu)(x) x MaxPooling2D((2, 2))(x) x Conv2D(128, (3, 3), paddingsame, activationrelu)(x) x MaxPooling2D((2, 2))(x) x Flatten()(x) x Dropout(0.5)(x) outputs Dense(num_classes, activationsoftmax)(x) model Model(inputs, outputs) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) return model对2D-CNN的改进方向热词“3d卷积神经网络”给了提示。当状态监测从单一工况扩展到多工况时可以把不同转速、不同负载下的时频图叠加成三维张量用3D卷积同时学习频率、时间、工况三个维度的特征。不过3D卷积极易过拟合参数量大在工程上要谨慎使用。更实用的方案是在2D-CNN的卷积层后加一个全局平均池化和注意力权重层让网络自适应地关注与故障高度相关的时频区域而不是均匀地看待整张图。1D-CNN和2D-CNN的选型边界做一个对照对比维度1D-CNN2D-CNN输入形式原始振动波形时频图预处理代价低只需切片归一化高每次都要做STFT故障类型区分度与工况相关性大时波动对边频带变化更敏感模型参数量较小训练快较大训练慢在线推理耗时微秒级到毫秒级毫秒级到十毫秒级4. 训练状态监测模型的关键参数与防过拟合设置4.1 损失函数与类别不平衡处理故障样本天然稀缺正常样本永远占多数齿轮箱状态监测是典型的类别不平衡问题。如果直接拿原始数据训练模型会学成一个把所有样本都判为正常的偷懒分类器准确率看着很高但毫无监测价值。解决这个问题的第一步是把损失函数从普通的交叉熵换成加权交叉熵给少数类更高的误分类代价。import tensorflow as tf from sklearn.utils.class_weight import compute_class_weight def get_class_weight(y_train): 根据训练集标签计算类别权重 少数类获得更大权重避免模型偏向多数类 classes np.unique(y_train) weights compute_class_weight(balanced, classesclasses, yy_train) class_weight dict(zip(classes, weights)) return class_weight # 训练时传给fit方法 # model.fit(x_train, y_train, class_weightclass_weight, epochs100)热词“lenet5卷积神经网络”提示了一个常见误区照搬LeNet-5结构做振动分类。LeNet-5的输入是32x32小图而时频图通常在几百乘几百像素直接resize到32x32会丢掉大量频率细节。可以参考LeNet-5的层间组合方式但输入尺寸要按频谱分辨率保留。另一个常用的损失函数改进是Focal Loss它对难分样本给予额外权重在断齿和早期裂纹这类容易被混淆的类别上比加权交叉熵表现更稳。4.2 优化器、学习率与早停策略优化器首选Adambeta_1设0.9、beta_2设0.999初始学习率从1e-3起步。但Adam不等于万能齿轮箱振动数据噪声大训练中后期容易在损失曲面振荡配合ReduceLROnPlateau可以自动降低学习率。from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau callbacks [ EarlyStopping(monitorval_loss, patience15, restore_best_weightsTrue), ReduceLROnPlateau(monitorval_loss, factor0.5, patience5, min_lr1e-6) ] # 使用20%的数据作为验证集 # model.fit(x_train, y_train, # validation_split0.2, # batch_size64, # epochs100, # callbackscallbacks, # verbose1)EarlyStopping的patience不能设太小。振动信号本身有随机性验证损失在几个epoch内小幅波动属于正常现象patience设10到20较为稳妥。关键超参数参考值如下超参数1D-CNN推荐值2D-CNN推荐值初始学习率1e-31e-3batch_size6432Dropout率0.40.5卷积核尺寸64/323x3最大训练轮数100120Dropout率在振动数据上可以适当调大。原因是采集自不同工况窗口的分布差异大模型容易记住某些工况片段的噪声模式Dropout的随机丢弃相当于隐式数据增强。实验中发现L2正则化对卷积层的效果不如Dropout明显主要是因为齿轮箱振动特征局部性强权重的绝对大小不是过拟合主因。5. 模型输出到运维动作阈值设定与在线监测流程5.1 健康指标构造与报警阈值神经网络输出softmax概率但运维系统不能直接看概率值做报警。故障概率在0.7和0.8之间怎么处理从正常态到故障态是渐变的过程概率值本身会缓慢攀升直接二值化容易在阈值附近来回跳变。常见做法是构造一个平滑的健康指标把正常类别的概率或故障类别的最大概率做指数移动平均。def health_score_from_prob(prob_normal, alpha0.9): 将模型输出的正常类别概率转换为平滑健康指标 prob_normal: 当前窗口判为正常的概率 alpha: 平滑系数越大表示历史权重更高 # 实际使用中 health 作为全局变量保存上一时刻的值 health alpha * health (1 - alpha) * prob_normal return health健康指标区间状态等级建议运维动作0.90 ~ 1.00健康定期巡检按原计划0.75 ~ 0.90关注缩短巡检周期对比同一机组最近7天趋势0.50 ~ 0.75预警安排振动测试专项检测调取润滑系统数据0.00 ~ 0.50报警申请计划停机检修窗口阈值设定不是拍脑袋要在验证集上分析健康指标的分布。正常样本的健康指标应落在0.95以上故障样本应落到0.7以下中间留出的过渡带就是阈值空间。如果两个分布重叠严重说明模型区分度不足需要回到特征工程或数据质量排查而不是硬调阈值。5.2 多传感器融合和迁移学习齿轮箱内部测点通常不止一个。高速轴、低速轴、行星级壳体、齿轮箱输出端各有一个加速度传感器每路信号单独跑模型容易互相矛盾。常见做法是在模型输入端做特征融合把各测点信号的时频图拼接成多通道图像2D-CNN的输入通道数变为测点数量。# 假设有3个测点每个测点生成一张256x256的灰度时频图 # 合成一个3通道的图像 # fused_input np.stack([spec_ch1, spec_ch2, spec_ch3], axis-1) # fused_input.shape (256, 256, 3) # 然后送入build_2dcnn(img_shape(256, 256, 3))训练多通道融合的代价是数据量需求成倍上升且某一测点传感器损坏时模型直接失效。工程上更稳健的做法是单测点模型独立训练在决策层做投票融合至少两个测点同时报警才触发预警降低单传感器故障引起的误报。迁移学习在风电机组齿轮箱上的价值体现在新机组部署环节。不同机组之间的齿轮箱型号、传感器安装位置、采样参数都存在差异直接用已有模型部署往往掉点。常见做法是保留已训练模型的卷积层权重在新的机组数据上用少量样本继续训练全连接层。def transfer_finetune(base_model, num_classes, fine_tune_layers2): 基于已有模型做迁移微调 冻结前面大部分卷积层只微调靠近输出的几层 model Sequential() for layer in base_model.layers[:-3]: layer.trainable False model.add(layer) # 重新加全连接层 model.add(Flatten()) model.add(Dense(100, activationrelu)) model.add(Dense(num_classes, activationsoftmax)) model.compile(optimizertf.keras.optimizers.Adam(1e-4), losssparse_categorical_crossentropy, metrics[accuracy]) return model6. 验证监测效果的三个具体技巧6.1 用混淆矩阵追溯误报与漏报的具体来源状态监测模型不能只看准确率要把测试集预测结果输出成混淆矩阵。from sklearn.metrics import confusion_matrix, classification_report # y_true: 测试集真实标签 # y_pred: 模型预测标签 cm confusion_matrix(y_true, y_pred) print(classification_report(y_true, y_pred, digits3)) # 找出最容易混淆的类别对 import numpy as np cm_norm cm / (cm.sum(axis1, keepdimsTrue) 1e-12) for i in range(len(cm)): for j in range(len(cm)): if i ! j and cm_norm[i, j] 0.1: print(f类别{i}有{cm_norm[i,j]:.1%}被误判为类别{j})混淆矩阵的行是真实标签列是预测标签。如果齿面磨损经常被误判为正常说明早期磨损的振动特征幅值过低模型没有学到足够敏感的判别特征如果断齿和轴承点蚀互相混淆说明两种故障在时频图上的分布区域有重叠。根据误判来源决定下一步动作增加对应故障的数据量、扩大时频图尺寸、或加入转速相位信息。6.2 特征分布可视化检查把模型倒数第二层输出的特征向量用t-SNE或UMAP投影到二维平面直观检查聚类效果。正常样本的特征点应聚成一团故障样本应分散成不同簇且簇间距要明显大于类内散度。如果不同故障类别在降维图里纠缠在一起说明卷积层学到的特征区分度不够。这种检查可以在训练集和测试集上各做一次对比是否出现过拟合造成测试集特征散乱。6.3 模拟故障注入测试鲁棒性在验证集上叠加不同信噪比的高斯白噪声观察模型在噪声干扰下的稳定程度。# 给振动信号加噪测试模型抗噪性 def add_noise(signal, snr_db): snr_db: 信噪比单位dB越大噪声越小 signal_power np.mean(signal ** 2) noise_power signal_power / (10 ** (snr_db / 10)) noise np.random.normal(0, np.sqrt(noise_power), signal.shape) return signal noise # 对SNR 5dB、10dB、20dB分别测试准确率 # 用低SNR下准确率下降幅度衡量模型鲁棒性注意不能用加入噪声的照片时频图直接测试模型必须是原始信号加噪之后再做STFT生成时频图。加噪后准确率掉到80%以下时优先考虑在训练阶段扩充噪声数据把不同SNR的带噪样本按比例混入训练集而不是简单增加网络深度。本文还有配套的精品资源点击获取