ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

齿轮故障诊断大作业:Python振动信号分析与分类实战

齿轮故障诊断大作业:Python振动信号分析与分类实战 简介这份资源面向高校学生与Python初学者提供一套完整的齿轮故障诊断项目实践方案可用于毕业设计、课程设计或项目开发练手。压缩包共7个文件以3个py源码、2个csv数据集和2个txt特征说明为主整体约38KB体量轻便便于快速上手与二次修改。源码部分包含基于Adaboost与Logistic两种算法的齿轮故障诊断实现配套训练与测试数据以及数据处理脚本能够帮助读者理解从特征读取、模型训练到结果验证的完整流程。目前已有174人学习下载说明该方案在同类课程作业中具有一定参考价值。读者可据此掌握故障诊断的基本思路、分类模型调用方式与数据组织方法并在此基础上替换数据或调整算法延伸出更丰富的实验内容。1. 齿轮故障诊断大作业从振动信号到诊断结论一套能跑通的 Python 方案做机械故障诊断方向的期末大作业最头疼的往往不是算法本身而是手里只有一段振动信号不知道怎么把它变成一份能写进报告、能通过答辩的完整诊断流程。齿轮故障诊断这个题目尤其典型信号里既有啮合频率又有边频带还有噪声和转频调制光看时域波形几乎看不出问题。我见过太多同学卡在“数据从哪来、特征怎么提、模型怎么选、结果怎么解释”这四步上最后只能抄一段 FFT 代码交差。这套基于 Python 的方案核心目标就是把这四步串成一条可复现的流水线用仿真或公开数据生成齿轮振动信号提取时域和频域特征训练一个轻量分类器最后输出诊断结论和可视化图表。适合正在做机械故障诊断、信号处理或机器学习课程大作业的本科生和研究生也适合想快速验证齿轮诊断流程的初级工程师。下面按“信号怎么造、特征怎么提、模型怎么训、坑怎么避”的顺序展开。2. 齿轮振动信号从哪来仿真数据生成与公开数据集选用2.1 为什么大作业优先用仿真信号而不是硬找实测数据齿轮故障诊断的实测数据获取门槛很高需要故障齿轮、试验台、加速度传感器和采集设备普通学生实验室很难凑齐。常见做法是用动力学仿真生成振动信号或者直接使用公开的齿轮故障数据集。仿真信号的好处是标签干净、故障类型可控、信噪比可调适合验证算法流程缺点是真实度有限但作为期末大作业完全够用。我一般会先仿真出正常、断齿、磨损、点蚀四类信号每类生成 200 个样本采样频率设为 10 kHz采样时长 1 秒这样单样本 10000 个点数据量适中。齿轮振动信号的核心成分包括啮合频率及其谐波、转频调制边频带、以及故障冲击成分。啮合频率计算公式为 ( f_m z \cdot f_r )其中 ( z ) 是齿数( f_r ) 是转频。比如 20 个齿、转频 30 Hz啮合频率就是 600 Hz。故障特征通常表现为啮合频率两侧出现间隔为转频的边频带或者时域上出现周期性冲击。仿真时把这些成分叠加起来再加高斯白噪声就能得到接近真实的信号。import numpy as np def generate_gear_signal(fs10000, duration1.0, fr30, z20, fault_typenormal, noise_level0.5): 生成齿轮振动仿真信号 fs: 采样频率 duration: 采样时长 fr: 转频 z: 齿数 fault_type: normal / broken / wear / pitting noise_level: 噪声标准差 t np.linspace(0, duration, int(fs * duration), endpointFalse) fm z * fr # 啮合频率 signal np.sin(2 * np.pi * fm * t) # 基频啮合成分 signal 0.5 * np.sin(2 * np.pi * 2 * fm * t) # 二次谐波 if fault_type broken: # 断齿产生周期性冲击周期为转频倒数 impact_period int(fs / fr) for i in range(0, len(t), impact_period): signal[i:i50] 2.0 * np.exp(-np.linspace(0, 5, 50)) elif fault_type wear: # 磨损边频带增强 signal 0.3 * np.sin(2 * np.pi * (fm - fr) * t) signal 0.3 * np.sin(2 * np.pi * (fm fr) * t) elif fault_type pitting: # 点蚀随机冲击 n_impacts 20 for _ in range(n_impacts): idx np.random.randint(0, len(t) - 100) signal[idx:idx100] 1.5 * np.exp(-np.linspace(0, 8, 100)) signal noise_level * np.random.randn(len(t)) return t, signal这段代码的逻辑很直接先构造啮合频率基频和二次谐波再根据故障类型叠加不同的调制或冲击成分。断齿用周期性指数衰减冲击模拟磨损用边频带增强模拟点蚀用随机冲击模拟。参数说明fs决定频率分辨率duration决定样本长度fr和z共同决定啮合频率位置noise_level控制信噪比。实际使用时可以把noise_level从 0.1 调到 1.0观察不同信噪比下诊断准确率的变化这本身就是大作业里一个很好的对比实验。2.2 公开数据集怎么选以凯斯西储大学轴承数据为参照的迁移思路如果不想用仿真数据公开数据集里最接近齿轮诊断的是凯斯西储大学轴承数据集虽然它是轴承不是齿轮但振动信号的分析流程完全一致。常见做法是下载该数据集把不同故障直径的样本当作不同类别走一遍特征提取和分类流程然后在报告里说明“齿轮诊断可沿用相同方法论”。注意不要直接声称这是齿轮数据答辩时容易被追问。另一个选择是 PHM 2009 齿轮箱数据集但获取难度稍大需要注册申请。我一般建议大作业用仿真数据打底再用公开轴承数据做交叉验证这样既有可控性又有真实感。数据组织上建议按类别分文件夹存放每个样本保存为.npy或.csv格式。文件名包含类别和序号比如normal_001.npy、broken_001.npy。这样后续批量读取时不用再解析标签直接按文件夹名取标签即可。样本数量建议每类 200 到 500 个太少会导致模型过拟合太多则训练时间过长。如果做 4 分类总共 800 到 2000 个样本比较合适。3. 特征工程怎么做时域、频域和时频域特征提取3.1 时域特征12 个统计量里哪几个对齿轮故障最敏感时域特征是最容易上手的一类直接对原始信号做统计计算。常用的有均值、方差、均方根、峰值、峰峰值、偏度、峭度、波形因子、峰值因子、脉冲因子、裕度因子、清晰度因子。其中对齿轮故障最敏感的是峭度、峰值因子和脉冲因子因为故障冲击会显著改变这些高阶统计量。正常齿轮信号的峭度接近 3出现断齿或点蚀后峭度会明显增大。均方根反映能量水平磨损故障会导致均方根缓慢上升。from scipy.stats import kurtosis, skew def time_domain_features(signal): 提取 12 个时域特征 abs_signal np.abs(signal) mean_val np.mean(signal) std_val np.std(signal) rms np.sqrt(np.mean(signal ** 2)) peak np.max(abs_signal) peak_to_peak np.max(signal) - np.min(signal) skewness skew(signal) kurt kurtosis(signal) waveform_factor rms / np.mean(abs_signal) if np.mean(abs_signal) ! 0 else 0 peak_factor peak / rms if rms ! 0 else 0 impulse_factor peak / np.mean(abs_signal) if np.mean(abs_signal) ! 0 else 0 margin_factor peak / (np.mean(np.sqrt(abs_signal)) ** 2) if np.mean(np.sqrt(abs_signal)) ! 0 else 0 clarity_factor peak / (np.mean(np.sqrt(abs_signal)) ** 2) if np.mean(np.sqrt(abs_signal)) ! 0 else 0 return [mean_val, std_val, rms, peak, peak_to_peak, skewness, kurt, waveform_factor, peak_factor, impulse_factor, margin_factor, clarity_factor]这段代码返回 12 维特征向量。参数说明kurtosis默认计算的是超额峭度正态分布下为 0如果要得到经典峭度值需要加 3。skew计算偏度反映信号不对称性。实际使用时建议对每个样本都提取这 12 个特征然后拼成一个特征矩阵行是样本列是特征。注意均方根和峰值对量纲敏感如果信号幅值范围差异大最好先做归一化。3.2 频域特征啮合频率幅值和边频带能量怎么算频域特征是齿轮诊断的核心因为故障特征频率在频谱上非常直观。做法是先对信号做 FFT得到幅值谱然后提取特定频率点的幅值。关键频率包括啮合频率 ( f_m )、转频 ( f_r )、啮合频率两侧的边频带 ( f_m \pm k \cdot f_r )。正常齿轮的边频带能量很低出现故障后边频带能量会显著上升。可以定义边频带能量比为边频带幅值之和与啮合频率幅值的比值这个指标对早期故障很敏感。def freq_domain_features(signal, fs, fm, fr, n_sidebands3): 提取频域特征啮合频率幅值、边频带能量比、重心频率 n len(signal) fft_vals np.fft.rfft(signal) fft_mag np.abs(fft_vals) / n freqs np.fft.rfftfreq(n, 1/fs) def get_amplitude(target_freq): idx np.argmin(np.abs(freqs - target_freq)) return fft_mag[idx] fm_amp get_amplitude(fm) sideband_energy 0 for k in range(1, n_sidebands 1): sideband_energy get_amplitude(fm - k * fr) sideband_energy get_amplitude(fm k * fr) sideband_ratio sideband_energy / fm_amp if fm_amp ! 0 else 0 # 重心频率 centroid np.sum(freqs * fft_mag) / np.sum(fft_mag) if np.sum(fft_mag) ! 0 else 0 return [fm_amp, sideband_energy, sideband_ratio, centroid]参数说明n_sidebands控制取几阶边频带一般取 3 就够。get_amplitude用最近邻找目标频率对应的谱线因为 FFT 频率分辨率有限实际频率不一定正好落在谱线上。边频带能量比是核心指标正常状态下通常小于 0.5故障状态下可能超过 1.0。重心频率反映频谱能量分布故障冲击会让高频成分增加重心频率右移。注意做 FFT 前最好加汉宁窗减少频谱泄漏。3.3 时频域特征小波包能量熵为什么比单纯 FFT 更适合非平稳冲击齿轮故障冲击是非平稳信号单纯 FFT 只能给出全局频率成分无法定位冲击发生的时间。时频域特征可以同时保留时间和频率信息。常用方法有短时傅里叶变换、小波变换和小波包分解。小波包分解能把信号分解到不同频带然后计算各频带的能量熵。故障冲击会让某些频带的能量显著增加能量熵随之变化。相比 STFT小波包对高频段的频率分辨率更好更适合冲击类故障。import pywt def wavelet_packet_features(signal, waveletdb4, level3): 小波包能量熵特征 wp pywt.WaveletPacket(datasignal, waveletwavelet, modesymmetric, maxlevellevel) nodes [node.path for node in wp.get_level(level, natural)] energies [] for node_path in nodes: coeffs wp[node_path].data energies.append(np.sum(coeffs ** 2)) energies np.array(energies) total np.sum(energies) if total 0: return [0] * len(energies) [0] probs energies / total entropy -np.sum(probs * np.log(probs 1e-12)) return list(probs) [entropy]参数说明wavelet选db4是因为它对冲击类信号形状匹配较好level取 3 到 4 层层数越多频带划分越细但计算量越大。返回的probs是各频带能量占比entropy是能量熵。正常信号能量集中在低频啮合频率附近熵值较低故障信号能量向高频扩散熵值增大。注意小波包分解前信号长度最好是 2 的整数次幂不是的话可以截断或补零。4. 分类模型怎么选从 SVM 到轻量 CNN 的取舍4.1 特征向量加 SVM大作业最稳的基线方案把第 3 章提取的时域、频域、时频域特征拼成一个长向量比如 12 维时域 4 维频域 9 维小波包8 个频带能量加 1 个熵总共 25 维。然后用 SVM 做分类。SVM 在小样本上表现稳定训练快参数少非常适合期末大作业。核函数选 RBF惩罚系数 C 和 gamma 用网格搜索调。我一般会把数据按 7:3 划分训练集和测试集做 5 折交叉验证选参数。from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV, train_test_split from sklearn.metrics import classification_report, confusion_matrix # X: 特征矩阵 (n_samples, n_features) # y: 标签 (n_samples,) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3, stratifyy, random_state42) pipe Pipeline([ (scaler, StandardScaler()), (svm, SVC(kernelrbf, probabilityTrue)) ]) param_grid { svm__C: [0.1, 1, 10, 100], svm__gamma: [scale, 0.01, 0.1, 1] } grid GridSearchCV(pipe, param_grid, cv5, scoringaccuracy, n_jobs-1) grid.fit(X_train, y_train) y_pred grid.predict(X_test) print(classification_report(y_test, y_pred)) print(confusion_matrix(y_test, y_pred))逻辑说明StandardScaler做零均值单位方差归一化因为 SVM 对特征尺度敏感。GridSearchCV在 4×4 参数组合上做 5 折交叉验证选准确率最高的组合。classification_report输出每类的精确率、召回率和 F1confusion_matrix看哪类容易混。参数说明C越大对误分类惩罚越重容易过拟合gamma越大决策边界越复杂。如果准确率卡在 80% 上不去优先检查特征是否归一化、类别是否平衡。4.2 一维 CNN 直接吃原始信号什么时候值得上深度学习如果特征工程后准确率不理想或者大作业要求体现深度学习能力可以上一维 CNN 直接对原始信号做端到端分类。一维 CNN 的优势是自动提取特征不需要手工设计缺点是需要更多数据训练更慢调参更玄学。我一般建议样本量超过 2000 时才考虑 CNN否则容易过拟合。网络结构用 3 层卷积加 2 层全连接每层卷积后接批归一化和最大池化最后用 softmax 输出类别概率。import torch import torch.nn as nn class GearCNN(nn.Module): def __init__(self, n_classes4, input_len10000): super().__init__() self.conv1 nn.Conv1d(1, 16, kernel_size15, stride2, padding7) self.bn1 nn.BatchNorm1d(16) self.pool1 nn.MaxPool1d(2) self.conv2 nn.Conv1d(16, 32, kernel_size9, stride2, padding4) self.bn2 nn.BatchNorm1d(32) self.pool2 nn.MaxPool1d(2) self.conv3 nn.Conv1d(32, 64, kernel_size5, stride2, padding2) self.bn3 nn.BatchNorm1d(64) self.pool3 nn.AdaptiveAvgPool1d(1) self.fc nn.Sequential( nn.Linear(64, 32), nn.ReLU(), nn.Dropout(0.3), nn.Linear(32, n_classes) ) def forward(self, x): x torch.relu(self.bn1(self.conv1(x))) x self.pool1(x) x torch.relu(self.bn2(self.conv2(x))) x self.pool2(x) x torch.relu(self.bn3(self.conv3(x))) x self.pool3(x).squeeze(-1) return self.fc(x)参数说明kernel_size第一层取 15 是为了覆盖一个啮合周期的采样点后续层递减。stride2逐步降采样减少计算量。AdaptiveAvgPool1d(1)把每个通道压成一个值避免全连接层参数爆炸。Dropout(0.3)防止过拟合。训练时用 Adam 优化器学习率 1e-3批大小 32训练 50 轮早停耐心值设 10。注意输入信号要先归一化到 [-1, 1]否则批归一化层效果会打折扣。4.3 模型评估准确率之外必须看的两个指标大作业报告里只写准确率是不够的答辩老师很可能追问“哪类容易错、错在哪”。必须看混淆矩阵和 F1 分数。混淆矩阵能看出正常和磨损是否容易混断齿和点蚀是否容易混。F1 分数是精确率和召回率的调和平均比准确率更适合类别不平衡场景。如果某一类 F1 明显偏低优先检查该类样本是否太少或者特征是否对该类不敏感。我一般会在报告里放一张混淆矩阵热力图和一张各类 F1 柱状图比单纯写“准确率 95%”有说服力得多。5. 避坑与排查齿轮诊断大作业里最容易翻车的 5 个点5.1 现象准确率异常高但混淆矩阵全是一类原因标签泄露或数据泄露。常见情况是特征提取时用了全量数据的统计量做归一化或者训练集和测试集有重叠样本。解决归一化只能在训练集上 fit然后 transform 测试集划分数据前先打乱用stratify保证类别比例一致。5.2 现象FFT 频谱上找不到啮合频率原因采样频率或转频设置错误导致啮合频率超出奈奎斯特频率。比如转频 30 Hz、齿数 20啮合频率 600 Hz采样频率至少 1200 Hz 才能看到实际建议 10 倍以上。解决先确认fs 2 * fm再看频谱时用rfft只取正频率部分横轴用rfftfreq生成。5.3 现象小波包分解报错“信号长度不是 2 的幂”原因pywt.WaveletPacket要求信号长度能被 2 的 level 次方整除。解决对信号做截断或补零到最近的 2 的幂长度或者改用pywt.wavedec做普通小波分解它对长度要求更宽松。5.4 现象CNN 训练损失不下降准确率停在 25%原因输入信号没有归一化或者学习率太大导致梯度爆炸。解决对每个样本做零均值单位方差归一化学习率从 1e-4 开始试加梯度裁剪torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)。5.5 现象SVM 训练报错“特征维度不一致”原因不同样本提取的特征数量不同比如小波包分解时某些样本长度不够导致频带数少一个。解决统一信号长度或者在特征提取函数里加异常处理保证每个样本返回相同维度。建议先跑一个样本确认特征维度再批量处理。6. 进阶技巧用混淆矩阵反推特征改进方向最后一章说一个我反复用到的技巧不要等模型训完才看混淆矩阵而是在特征提取阶段就画一张“特征分布图”用 t-SNE 或 PCA 把 25 维特征降到 2 维按类别着色。如果正常和磨损在二维图上混在一起说明当前特征对这两类区分度不够需要补充对磨损敏感的特征比如边频带能量比或者均方根趋势。如果断齿和点蚀混在一起说明冲击类特征不够细可以加小波包高频段能量占比。具体操作先用sklearn.manifold.TSNE对特征矩阵做降维perplexity设 30n_iter设 1000然后用 matplotlib 散点图按类别画不同颜色。如果某两类重叠严重回到第 3 章针对性加特征。比如磨损故障的边频带能量比通常比正常高 2 到 3 倍把这个特征单独拎出来看分布如果重叠还是大就考虑加窗函数或改用包络谱分析。from sklearn.manifold import TSNE import matplotlib.pyplot as plt tsne TSNE(n_components2, perplexity30, n_iter1000, random_state42) X_2d tsne.fit_transform(X) plt.figure(figsize(8, 6)) for label in np.unique(y): mask y label plt.scatter(X_2d[mask, 0], X_2d[mask, 1], labelfClass {label}, alpha0.6) plt.legend() plt.title(Feature Distribution by t-SNE) plt.show()参数说明perplexity控制局部和全局结构的平衡小数据集取 5 到 30大数据集取 30 到 50。n_iter至少 1000 才能收敛。如果 t-SNE 跑得慢可以先用 PCA 降到 50 维再跑 t-SNE。这个图放进大作业报告里比单纯列准确率更能体现你对特征的理解。我自己的习惯是每次换特征组合先跑 t-SNE 看分布再跑 SVM 看准确率两者对照着调。如果 t-SNE 上分得开但 SVM 准确率低多半是参数没调好如果 t-SNE 上就混在一起换模型也救不了必须回去改特征。这个习惯帮我省了很多无效调参的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表