ARTICLE DETAIL

资讯详情

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

基于卷积神经网络的滚动轴承故障诊断:从振动信号到故障标签

基于卷积神经网络的滚动轴承故障诊断:从振动信号到故障标签 简介这份PDF文献面向机械故障诊断、深度学习方向的研究生与工程技术人员针对滚动轴承故障特征难以准确表征、传统奇异值分解与经验模态分解等方法仅能部分反映故障信息的问题提出基于振谱图与深度卷积神经网络的诊断方案。全文围绕振动信号分帧、加窗、DFT与图像编码构建振谱图设计DCNN完成特征学习与故障识别并以美国凯斯西储大学公开实测振动信号验证识别准确率达到100%。资源包共1个PDF文件大小约1.28MB内容为完整论文正文含摘要、引言、基本原理、网络结构设计与实验分析等章节可帮助读者理解短时傅里叶分析与卷积网络在故障建模中的结合思路掌握从信号预处理到网络训练、故障识别的完整技术路线适合作为课题入门与方案复现的参考。目前已有571人学习。1. 从振动信号到故障标签卷积神经网络做滚动轴承诊断到底在解决什么产线上最让人头疼的往往不是轴承彻底抱死而是它带着早期剥落、点蚀继续跑振动信号里已经出现周期性冲击但人耳和阈值报警都还没反应。基于卷积神经网络的滚动轴承故障诊断研究核心就是把这层“早期征兆”从原始振动波形里自动抠出来直接映射成故障类型和严重程度。它适合手里有加速度传感器、能采到振动数据又不想手工设计几十个时频特征的工程师。传统做法靠人工算峭度、裕度、包络谱峰值换一个转速或换一台设备就得重调阈值卷积神经网络把特征提取和分类揉进一个可训练结构里用一维卷积直接吃时域序列省掉大量特征工程。读完你能判断自己的数据够不够、该用 1D-CNN 还是先转时频图以及怎么把模型训到能上测试台。2. 一维卷积神经网络为什么比手工特征更适合轴承振动2.1 从滚动体冲击到卷积核信号里到底有什么可学的轴承出现局部损伤后滚动体每碾过一次缺陷就会产生一次冲击冲击激发轴承座和传感器的高频共振形成一串幅值调制脉冲。外圈故障的冲击间隔由外圈通过频率决定内圈故障还叠加轴的旋转调制滚动体故障则更复杂。这些脉冲在时域上表现为周期性尖峰在频域上表现为特征频率及其谐波在包络谱里最干净。手工特征的问题在于你得先知道看哪个频段、哪个阶次转速一变特征频率就漂固定带通滤波很容易把故障信息滤掉。一维卷积神经网络1D-CNN的卷积核本质上是一组可学习的带通滤波器加非线性变换。第一层卷积核长度通常取几十到几百个采样点正好覆盖一次冲击的持续时间多层堆叠后浅层学到冲击边缘和局部波形深层学到冲击的周期性和调制模式。这跟轴承故障的物理生成机制是对得上的所以它比通用手工特征更抗转速波动。常见做法是把原始振动按固定长度切片每片直接送进 1D-CNN标签用故障类别端到端训练。2.2 用 PyTorch 搭一个能跑通的最小 1D-CNN下面这段代码是一个最小可复现结构输入是单通道振动片段输出是故障类别。先跑通再谈调参。import torch import torch.nn as nn class Bearing1DCNN(nn.Module): def __init__(self, num_classes4, in_channels1): super().__init__() # 第一层卷积核较长用来捕捉单次冲击波形 self.features nn.Sequential( nn.Conv1d(in_channels, 16, kernel_size64, stride2, padding32), nn.BatchNorm1d(16), nn.ReLU(inplaceTrue), nn.MaxPool1d(kernel_size2, stride2), nn.Conv1d(16, 32, kernel_size32, stride1, padding16), nn.BatchNorm1d(32), nn.ReLU(inplaceTrue), nn.MaxPool1d(kernel_size2, stride2), nn.Conv1d(32, 64, kernel_size16, stride1, padding8), nn.BatchNorm1d(64), nn.ReLU(inplaceTrue), nn.AdaptiveAvgPool1d(1) # 把时间维压成1避免全连接层参数爆炸 ) self.classifier nn.Linear(64, num_classes) def forward(self, x): x self.features(x) # [B, 64, 1] x x.squeeze(-1) # [B, 64] return self.classifier(x) if __name__ __main__: model Bearing1DCNN(num_classes4) dummy torch.randn(8, 1, 2048) # 批大小8单通道2048个采样点 out model(dummy) print(out.shape) # torch.Size([8, 4])逻辑说明第一层kernel_size64对应冲击持续时间stride2做初步降采样后面两层卷积核逐步变短学更抽象的周期模式AdaptiveAvgPool1d(1)把任意长度的时间维压成一个值这样输入片段长度变化时不用改全连接层。参数说明in_channels1是单轴振动如果三轴同时采就改成 3num_classes按你的故障标签数改输入长度 2048 是常见起点采样率 12kHz 时约 170ms足够覆盖几个冲击周期。训练时用交叉熵损失、Adam 优化器学习率从 1e-3 起步。2.3 数据切片、归一化和标签怎么定原始振动不能整段丢进去要切成固定长度片段。常见做法是用滑动窗口窗口长度取 1024 到 4096 个采样点重叠率 50% 左右既能增加样本量又不会让相邻片段太像。归一化按片段做 z-score也就是减均值除标准差这样不同负载下的幅值差异不会干扰模型。标签定义要跟你的诊断目标一致如果只分正常、外圈、内圈、滚动体四类num_classes4如果要分故障直径类别数要相应增加。注意别把同一段连续信号切出的片段同时放进训练集和测试集否则测试准确率会虚高这是最常见的翻车点之一。3. 把公开轴承数据跑成可复现基线从 CWRU 到自定义数据集3.1 公开数据集怎么选、怎么读、怎么切做滚动轴承故障诊断起步最稳的是凯斯西储大学CWRU轴承数据它包含正常、内圈、外圈、滚动体故障不同故障直径和负载采样率有 12kHz 和 48kHz 两档。读取时注意.mat文件里的变量名驱动端和风扇端要分清。下面是一个读取并切片的脚本骨架。import scipy.io as sio import numpy as np def load_cwru(mat_path, keyX108_DE_time): data sio.loadmat(mat_path) signal data[key].ravel() # 取驱动端振动序列 signal (signal - signal.mean()) / (signal.std() 1e-8) return signal.astype(np.float32) def slice_signal(signal, win2048, step1024): segments [] for start in range(0, len(signal) - win 1, step): segments.append(signal[start:start win]) return np.stack(segments) # [N, win] sig load_cwru(108.mat) segs slice_signal(sig, win2048, step1024) print(segs.shape)逻辑说明load_cwru负责读.mat并做全局 z-scoreslice_signal用滑动窗口切片step1024即 50% 重叠。参数说明win建议先取 2048采样率 12kHz 时约 170ms如果故障特征频率很低可以加到 4096。切片后每个样本是[2048]送模型前要加通道维变成[1, 2048]。3.2 训练/验证/测试划分与类别不平衡处理CWRU 各类样本数量不一定均衡正常样本往往远多于故障样本。划分时按片段随机打乱后 7:1.5:1.5 分但同一段连续信号切出的片段要整体分到同一集合避免泄漏。类别不平衡可以用加权交叉熵权重取类别频率的倒数。下面给出训练循环的关键部分。from torch.utils.data import DataLoader, TensorDataset import torch.optim as optim # X: [N, 1, 2048], y: [N] dataset TensorDataset(torch.tensor(X), torch.tensor(y)) loader DataLoader(dataset, batch_size64, shuffleTrue) model Bearing1DCNN(num_classes4) criterion nn.CrossEntropyLoss(weighttorch.tensor([1.0, 3.0, 3.0, 3.0])) optimizer optim.Adam(model.parameters(), lr1e-3) for epoch in range(30): model.train() for xb, yb in loader: optimizer.zero_grad() loss criterion(model(xb), yb) loss.backward() optimizer.step()逻辑说明weight用来缓解正常样本过多导致的偏向batch_size64是常见起点显存不够就降到 32。参数说明学习率 1e-3 配 Adam 通常能收敛若损失震荡就降到 3e-4训练轮数先跑 30 轮看验证准确率曲线早停可以防止过拟合。3.3 用混淆矩阵和 t-SNE 验证模型真的学到了故障准确率不够要看混淆矩阵。把测试集预测结果按类别统计能看出模型是把内圈误判成外圈还是把早期故障判成正常。再进一步把倒数第二层特征抽出来做 t-SNE 降维可视化如果同类样本聚成一团、不同类分开说明特征有判别力如果混在一起多半是切片长度或归一化有问题。常见做法是每训完几轮就画一次混淆矩阵别等最后才看。4. 调参与排错1D-CNN 在轴承诊断里的避坑清单4.1 采样率、窗口长度和卷积核的匹配关系采样率决定你能看到多高的频率窗口长度决定频率分辨率。如果采样率 12kHz窗口 2048 点频率分辨率约 5.86Hz对常见轴承故障特征频率够用但如果转速很低特征频率只有十几赫兹就要加长窗口。卷积核长度要和冲击持续时间匹配冲击越短第一层核可以短一些冲击衰减慢核就要长。常见错误是直接套用图像分类的 3×3 小核结果第一层根本抓不到冲击波形训练损失降不下去。4.2 避坑清单现象、原因、解决现象一训练准确率很高测试准确率断崖式下跌。原因同一段连续信号切出的片段被同时分到训练和测试集模型记住了片段而不是故障特征。解决按原始信号段划分再做切片确保训练集和测试集来自不同记录。现象二验证损失震荡不收敛。原因学习率太大或者 BatchNorm 在批大小太小时统计量不稳。解决学习率降到 3e-4批大小至少 32如果还震荡把 BatchNorm 换成 GroupNorm。现象三模型把所有样本都判成正常类。原因类别不平衡严重正常样本占绝大多数模型学到“全判正常”就能拿高准确率。解决用加权交叉熵或者对故障类做重采样同时看召回率而不是只看准确率。现象四换一个转速后准确率明显下降。原因模型学到了和转速相关的频率成分而不是故障冲击的周期结构。解决做转速归一化或者用阶次分析把时域信号重采样到角度域再送 1D-CNN。现象五输入片段长度改了以后全连接层报错。原因用了固定尺寸的全连接层输入长度一变特征维度就对不上。解决用AdaptiveAvgPool1d(1)或全局最大池化把时间维压掉分类层只依赖通道数。4.3 训练不动的排查顺序先查数据归一化有没有做、标签有没有错位、切片有没有重叠泄漏。再查模型第一层卷积核长度是否合理、有没有用 BatchNorm、池化是不是太激进把时间维压没了。最后查训练学习率、批大小、损失函数权重。按这个顺序走大部分问题能在半小时内定位。别一上来就换网络结构多数翻车都在数据环节。5. 从实验室到产线迁移学习、边缘部署和持续验证5.1 用迁移学习把公开数据模型搬到自己的设备公开数据训出的模型直接用到自己设备上准确率通常会掉因为传感器安装位置、负载、转速都不同。常见做法是冻结前两层卷积只微调后面层和分类层用自己设备上少量带标签样本做 fine-tune。如果连标签都没有可以先用无监督方法做域适应比如用最大均值差异MMD对齐源域和目标域的特征分布。我一般会先采一批正常数据确认模型不会把正常误报成故障再逐步加入故障样本。5.2 边缘部署时的模型压缩与推理速度产线上往往要在边缘设备上跑推理模型不能太大。1D-CNN 参数量通常比图像 CNN 小但第一层卷积核长、通道多时也会膨胀。压缩手段包括把卷积核换成深度可分离卷积、剪枝掉贡献小的通道、用 int8 量化。推理速度方面输入片段 2048 点、模型三层卷积在普通 ARM 上单次推理可以做到毫秒级。部署前一定要用真实产线数据做一轮验证看误报率和漏报率别只看实验室准确率。5.3 一个具体技巧用包络谱做后处理校验模型输出故障类别后别直接信。对判为故障的片段算一下包络谱看特征频率处有没有明显峰值。如果模型说是外圈故障但包络谱在对应外圈通过频率处没有能量那大概率是误报。这个后处理能挡掉不少玄学误判。实现上先做希尔伯特变换取包络再对包络做 FFT看目标频率及其谐波。下面是一个最小示例。import numpy as np from scipy.signal import hilbert def envelope_spectrum(x, fs12000): analytic hilbert(x) env np.abs(analytic) env env - env.mean() spec np.abs(np.fft.rfft(env)) freq np.fft.rfftfreq(len(env), d1/fs) return freq, spec freq, spec envelope_spectrum(segs[0], fs12000) peak_idx np.argmax(spec[1:]) 1 print(包络谱主峰频率:, freq[peak_idx])逻辑说明hilbert取解析信号np.abs得包络去均值后做 FFT。参数说明fs要和实际采样率一致看主峰是否落在轴承特征频率附近。这个校验不参与训练只在推理后做成本低但很实用。我自己的习惯是每换一批数据先跑一遍包络谱看物理特征在不在再决定要不要重训模型。模型可以骗人包络谱不太会。希望帮到你。本文还有配套的精品资源点击获取
返回列表