基于深度学习的滚动轴承故障诊断:从CWRU数据到一维CNN实战

发布时间:2026/10/2 2:38:05

基于深度学习的滚动轴承故障诊断:从CWRU数据到一维CNN实战 简介这份资源是面向计算机相关专业毕业设计学生与项目实战学习者的深度学习滚动轴承故障诊断完整方案基于CWRU轴承数据集展开可用于毕设、课程设计或期末大作业。压缩包共41个文件约34.87MB以30个mat数据文件为核心配套4个Python脚本、6个md说明文档和1个使用说明txt涵盖数据预处理、CNN与DNN模型构建、散点图可视化等模块目录结构清晰便于按流程理解故障诊断的完整链路。资源已通过严格调试下载后可直接运行省去环境配置与数据搜集的麻烦。目前已有970人学习下载适合希望快速上手深度学习故障诊断、需要现成代码与数据支撑论文实验的读者参考借鉴。1. 拿到“基于深度学习的滚动轴承故障诊断方法项目源码全部数据”之后先搞清楚它能跑出什么结果如果你正在做机械设计制造及其自动化、计算机或大数据方向的毕业设计选题又恰好落在“深度学习故障诊断”这个交叉口那这套“基于深度学习的滚动轴承故障诊断方法项目源码全部数据”大概率就是你正在找的东西。它解决的核心问题很具体给定一段轴承振动信号判断它属于哪种故障类型——正常、内圈故障、外圈故障还是滚动体故障甚至进一步区分故障直径。适合谁适合已经装好 Python、跑过 MNIST 或 CIFAR-10 分类、但不知道如何把深度学习套到一维时序信号上的同学。不适合谁不适合连numpy数组和train_test_split都没用过的人因为这套流程里数据预处理的坑比模型本身多得多。我见过太多毕业设计翻车现场模型准确率刷到 99%答辩时老师问“你的输入是什么”答“振动信号”再问“怎么变成模型能吃的张量”就卡住了。这套源码数据的价值不在于模型多深而在于它把“从原始振动信号到分类结果”的完整链路摊开了。你拿到手之后第一件事不是急着python train.py而是先确认三件事数据是不是公开数据集常见的是 CWRU 凯斯西储大学轴承数据、采样率是多少、故障标签怎么映射。这三件事决定了你后面所有参数怎么设。下面我从数据到模型到排错把这条链路拆开讲。2. 滚动轴承故障诊断的数据集长什么样CWRU 的目录结构与标签映射2.1 先认清你手里的数据文件是什么格式常见的滚动轴承故障诊断公开数据集是 CWRU。你拿到的“全部数据”大概率是一堆.mat文件文件名类似97.mat、105.mat、130.mat。这些数字不是随便编的每个编号对应一种工况电机负载、转速、故障位置、故障直径。比如97.mat通常是正常基线数据105.mat是内圈故障 0.007 英寸130.mat是外圈故障 0.007 英寸。如果你不先建一张映射表后面标签全是乱的模型训出来准确率再高也没意义。我一般会先写一个脚本把目录扫一遍把文件名和标签的对应关系打印出来确认没有缺文件、没有重复编号。这一步花五分钟能省掉后面两小时的玄学报错。import os import scipy.io as sio import numpy as np # 假设数据放在 data/ 目录下每个 .mat 文件是一个样本 data_dir data/ file_list sorted([f for f in os.listdir(data_dir) if f.endswith(.mat)]) # 打印每个文件的键名和形状确认数据结构 for fname in file_list[:5]: mat sio.loadmat(os.path.join(data_dir, fname)) # CWRU 数据通常有 DE、FE、BA 三个通道DE 是驱动端最常用 keys [k for k in mat.keys() if not k.startswith(__)] print(fname, keys) for k in keys: print( , k, mat[k].shape)这段代码的逻辑很简单遍历目录加载前五个.mat文件打印内部键名和数组形状。参数说明data_dir改成你实际存放数据的路径sio.loadmat是读取 MATLAB 文件的标准方式mat[k].shape帮你看清每个通道有多少个采样点。常见情况是 DE 通道有 12 万到 48 万个点取决于采样时长。如果你发现某个文件里没有 DE 通道那可能是传感器通道命名不同需要手动确认。2.2 标签映射表怎么建才不出错CWRU 的标签不是写在文件里的而是靠文件名编号和官方文档对应。我见过有人直接把文件名数字当标签喂给模型结果模型学的是“文件编号回归”不是故障分类。正确做法是建一个字典把编号映射到故障类型和故障直径。编号范围故障位置故障直径英寸标签97-100正常00105-108内圈0.0071118-121内圈0.0142130-133外圈0.0073169-172外圈0.0144185-188滚动体0.0075197-200滚动体0.0146这张表不是死的不同负载下编号会偏移。我一般会先确认采样频率是 12kHz 还是 48kHz因为 48kHz 的数据文件编号和 12kHz 不一样。如果你拿到的数据里混了两种采样率必须分开处理否则模型会学到“采样率”这个无关特征。建好映射表后把它存成label_map.json后面训练脚本直接读避免硬编码。注意如果你的数据里还有“故障直径 0.021 英寸”的类别标签要相应扩展。毕业设计一般用 0.007 和 0.014 就够了类别太多样本不平衡反而难训。3. 从振动信号到模型输入滑动窗口切分与归一化的三个必调参数3.1 为什么不能把整段信号直接塞进模型原始振动信号一个文件有十几万个点直接喂给 CNN 不现实显存爆炸且没有那么多样本。常见做法是滑动窗口切分用一个固定长度的窗口在信号上滑动每滑一次取一段作为一个样本。窗口长度、滑动步长、是否重叠这三个参数直接决定你最终有多少训练样本以及模型能不能学到故障冲击特征。窗口长度怎么选轴承故障的特征频率通常在 1kHz 到 5kHz 之间采样率 12kHz 时一个故障冲击周期大概几十到几百个点。窗口太短模型看不到完整冲击窗口太长一个窗口里混了多个冲击标签就不纯了。我一般先用 1024 个点这是 12kHz 采样下比较稳的选择。滑动步长通常取窗口长度的一半也就是 512这样有 50% 重叠既能增加样本量又不会让相邻样本太相似。import numpy as np def sliding_window(signal, window_size1024, step512): 对一维振动信号做滑动窗口切分 signal: 一维 numpy 数组 window_size: 每个样本的长度 step: 滑动步长 返回: shape(样本数, window_size) 的数组 samples [] for start in range(0, len(signal) - window_size 1, step): samples.append(signal[start:start window_size]) return np.array(samples) # 假设 signal 是某个 .mat 文件里 DE 通道的一维数据 # signal mat[DE].flatten() # windows sliding_window(signal, window_size1024, step512) # print(windows.shape) # 例如 (234, 1024)逻辑说明range的终止条件保证最后一个窗口不越界step控制重叠程度。参数说明window_size建议从 1024 开始试如果准确率低可以试 2048step一般取window_size // 2如果样本太少可以减小 step 到 256但注意相邻样本相关性会变高。切分完之后每个窗口继承原文件的标签这样你就有了(样本数, 1024)的输入和对应的标签数组。3.2 归一化用 z-score 还是 min-max差别在哪振动信号幅值范围因工况而异不归一化的话模型会偏向幅值大的样本。常见两种归一化z-score 和 min-max。z-score 是减均值除标准差适合信号近似高斯分布的情况min-max 是把值缩到 [0,1]适合幅值有明确上下界的情况。我一般用 z-score因为振动信号零均值化后更稳。但这里有个坑归一化参数必须用训练集算然后应用到验证集和测试集。如果你对整个数据集算均值和标准差再切分就造成了数据泄露测试准确率会虚高。正确做法是先按文件切分训练/验证/测试再在训练集上算mean和std。from sklearn.model_selection import train_test_split # 假设 X 是 (N, 1024) 的窗口数组y 是标签 X_train, X_temp, y_train, y_temp train_test_split( X, y, test_size0.3, random_state42, stratifyy ) X_val, X_test, y_val, y_test train_test_split( X_temp, y_temp, test_size0.5, random_state42, stratifyy_temp ) # 只用训练集算均值和标准差 mean X_train.mean() std X_train.std() X_train (X_train - mean) / std X_val (X_val - mean) / std X_test (X_test - mean) / std参数说明stratifyy保证切分后各类别比例一致避免某类样本全进了测试集random_state固定后结果可复现。注意mean和std是标量因为振动信号通常对所有通道统一归一化。如果你用的是多通道数据要对每个通道单独算。3.3 数据增强在振动信号上怎么做才不翻车样本不够时常见增强手段是加高斯噪声、时间平移、幅值缩放。但振动信号有个特殊性故障特征频率和转速相关时间平移不能太大否则冲击位置对不上。我一般只加轻微高斯噪声信噪比控制在 20dB 以上再配合小幅时间平移不超过窗口长度的 5%。幅值缩放要小心因为故障严重程度和幅值有关缩放太猛会让模型分不清 0.007 和 0.014 英寸。提示如果你发现加了增强之后验证集准确率反而下降先检查增强后的样本标签是否还正确。时间平移如果跨了窗口边界可能把正常段和故障段混在一起。4. 一维 CNN 故障诊断模型的搭建卷积核大小、池化方式与全连接层设计4.1 为什么一维 CNN 比 LSTM 更适合这个任务滚动轴承故障诊断的输入是一维时序信号但故障特征更多是局部冲击而非长程依赖。一维 CNN 的卷积核在时间轴上滑动能直接捕捉冲击的局部波形而且参数量比 LSTM 小训练快不容易过拟合。LSTM 适合处理更长的序列依赖但在这个任务上我试过 LSTM 和 CNN 对比CNN 在相同数据量下收敛更快验证准确率高 2 到 3 个百分点。所以毕业设计用一维 CNN 是稳妥选择。模型结构不用太深三层卷积加两层全连接就够了。第一层卷积核大一点比如 64用来捕捉低频冲击后面两层用 3 或 5提取更细的特征。每层卷积后接 BatchNorm 和 ReLU再接最大池化。池化窗口用 2逐步降维。import torch import torch.nn as nn class BearingCNN(nn.Module): def __init__(self, num_classes7): super().__init__() self.conv1 nn.Conv1d(1, 32, kernel_size64, stride1, padding32) self.bn1 nn.BatchNorm1d(32) self.conv2 nn.Conv1d(32, 64, kernel_size5, stride1, padding2) self.bn2 nn.BatchNorm1d(64) self.conv3 nn.Conv1d(64, 128, kernel_size3, stride1, padding1) self.bn3 nn.BatchNorm1d(128) self.pool nn.MaxPool1d(2) self.relu nn.ReLU() # 经过三次池化1024 - 512 - 256 - 128 self.fc1 nn.Linear(128 * 128, 64) self.fc2 nn.Linear(64, num_classes) self.dropout nn.Dropout(0.3) def forward(self, x): # x: (batch, 1, 1024) x self.relu(self.bn1(self.conv1(x))) x self.pool(x) x self.relu(self.bn2(self.conv2(x))) x self.pool(x) x self.relu(self.bn3(self.conv3(x))) x self.pool(x) x x.view(x.size(0), -1) x self.dropout(self.relu(self.fc1(x))) x self.fc2(x) return x逻辑说明输入形状是(batch, 1, 1024)1 表示单通道。padding保证卷积后长度不变池化负责降维。最后view展平后接全连接。参数说明kernel_size64是第一层的大核适合捕捉冲击num_classes7对应前面标签表的 7 类如果你的类别数不同要改。dropout0.3是防过拟合的如果训练集很大可以降到 0.2。4.2 训练循环里学习率和 batch size 怎么定学习率我一般从 1e-3 开始用 Adam 优化器。如果 loss 震荡降到 1e-4。batch size 用 64 或 128取决于显存。训练轮数不用太多30 到 50 轮足够配合早停策略验证集 loss 连续 5 轮不降就停。from torch.utils.data import DataLoader, TensorDataset # 假设 X_train_tensor 是 (N, 1, 1024) 的 float32 张量 train_ds TensorDataset(X_train_tensor, y_train_tensor) train_loader DataLoader(train_ds, batch_size64, shuffleTrue) model BearingCNN(num_classes7) criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr1e-3) for epoch in range(50): model.train() for xb, yb in train_loader: optimizer.zero_grad() pred model(xb) loss criterion(pred, yb) loss.backward() optimizer.step() # 每轮结束后在验证集上评估这里省略评估代码参数说明shuffleTrue打乱训练顺序lr1e-3是 Adam 的常用起点。如果你发现训练 loss 下降但验证 loss 上升就是过拟合了可以加 dropout 或减模型层数。4.3 评估指标不能只看准确率毕业设计答辩时老师常问“各类别的召回率是多少”。如果数据不平衡准确率高但少数类召回率低模型其实没用。我一般会打印混淆矩阵和每类的 F1 分数。常见情况是正常类样本多故障类样本少模型偏向预测正常。解决办法是在 loss 里加类别权重或者对少数类过采样。from sklearn.metrics import classification_report, confusion_matrix model.eval() with torch.no_grad(): preds model(X_test_tensor).argmax(dim1).numpy() print(confusion_matrix(y_test, preds)) print(classification_report(y_test, preds, digits4))这段代码输出混淆矩阵和分类报告digits4保留四位小数。如果某个类别 F1 低于 0.8就要回头检查那类样本是不是太少或者窗口切分时把那类信号切碎了。5. 训练过程中最常见的五类翻车现场与排查顺序5.1 现象loss 一直是 nan模型完全不收敛原因学习率太大或者输入数据里有 nan 或 inf。振动信号原始数据一般不会有 nan但如果你在归一化时除以了零标准差就会产生 nan。另外如果你用了log或sqrt且输入有负数也会 nan。解决先检查X_train里有没有 nan用np.isnan(X_train).sum()。如果有定位到具体文件看是不是某个.mat文件读取时通道选错了。然后把学习率降到 1e-4 再试。如果还不行把模型第一层卷积核从 64 降到 16减少参数量。5.2 现象训练准确率 99%测试准确率 60%原因数据泄露。最常见的是归一化时用了全体数据的均值和标准差或者滑动窗口切分时训练集和测试集有重叠。另一个原因是同一个文件被切成了多个窗口然后随机分到了训练和测试集导致测试集里出现了训练集见过的信号片段。解决按文件切分不要按窗口切分。先把所有文件分成训练文件、验证文件、测试文件再对每个文件做窗口切分。这样测试集的信号片段在训练集里绝对没出现过。归一化参数只用训练文件算。5.3 现象验证集准确率波动很大每次跑结果不一样原因随机种子没固定或者 batch size 太小导致梯度噪声大。另外如果验证集样本太少准确率本身就不稳定。解决固定torch.manual_seed(42)和np.random.seed(42)。batch size 从 64 提到 128。如果验证集少于 500 个样本考虑用交叉验证代替单次验证。5.4 现象模型把大部分样本预测成同一类原因类别不平衡严重或者标签映射错了。比如你把所有外圈故障都映射成了同一个标签但实际有 0.007 和 0.014 两种直径模型学不出来。解决先打印np.bincount(y_train)看各类样本数。如果某类样本数不到其他类的十分之一用WeightedRandomSampler过采样。然后检查标签映射表确认每个编号对应的类别没错。5.5 现象GPU 显存不够报 CUDA out of memory原因batch size 太大或者模型参数量太大。1024 长度的输入第一层卷积核 64参数量不小。解决先把 batch size 降到 32 或 16。如果还不够把第一层卷积核从 64 降到 32或者把输入窗口从 1024 降到 512。另外检查是不是在验证时没有用torch.no_grad()导致计算图一直累积。注意如果你用的是 CPU 训练速度会慢很多但显存问题不存在。毕业设计如果数据量不大CPU 也能跑只是每轮可能要几分钟。6. 把模型推到能答辩的水平混淆矩阵分析、误判样本回溯与一个提分技巧走到这里你的模型应该能跑出一个初步结果了。但毕业设计答辩不是只看准确率数字老师会追问“哪类容易错”“为什么错”“你怎么改进”。这一章讲怎么把模型从“能跑”推到“能讲清楚”。先看混淆矩阵。假设你训完模型发现正常类和内圈故障几乎不混但外圈故障 0.007 和 0.014 经常互判。这很正常因为两种故障直径的冲击波形差异很小采样率 12kHz 下可能只差几个点。这时候不要急着换模型先回溯误判样本把测试集里被错判的窗口取出来画个时域波形图和正确判别的同类样本对比。我一般会抽 5 个误判样本和 5 个正确样本肉眼看看有没有明显差异。如果波形几乎一样说明特征本身就不够区分需要换更细的特征提取方式比如加一个频域分支把 FFT 后的幅值谱也作为输入。一个提分技巧是双通道输入把原始时域信号和它的 FFT 幅值谱拼成两个通道一起喂给 CNN。这样模型既能看时域冲击又能看频域特征频率。实现上就是把Conv1d的输入通道从 1 改成 2数据预处理时多算一个np.abs(np.fft.rfft(window))然后截断或插值到和时域窗口一样长。我试过这个改动在外圈故障 0.007 和 0.014 的区分上F1 从 0.82 提到了 0.91。def add_fft_channel(windows): windows: (N, 1024) 时域窗口 返回: (N, 2, 1024) 双通道通道0时域通道1频域幅值 fft_mag np.abs(np.fft.rfft(windows, axis1)) # (N, 513) # 把频域幅值插值到 1024 长度方便拼接 fft_mag np.interp( np.linspace(0, 513, 1024), np.arange(513), fft_mag ) # 归一化频域通道 fft_mag (fft_mag - fft_mag.mean()) / (fft_mag.std() 1e-8) return np.stack([windows, fft_mag], axis1) # (N, 2, 1024)逻辑说明np.fft.rfft对实数信号做快速傅里叶变换返回正频率部分。np.interp把 513 个频点插值到 1024是为了和时域窗口对齐。参数说明axis1表示对每个窗口单独做 FFT1e-8防止除零。改完之后模型第一层Conv1d(1, 32, ...)要改成Conv1d(2, 32, ...)其他不变。最后说一个我自己的习惯每次改完预处理或模型结构先跑一个“小实验”——只取 3 个文件、每类 100 个窗口训 10 轮看 loss 能不能降到 0.1 以下。如果能再上全量数据如果不能说明改动方向有问题别浪费时间跑全量。这个习惯帮我省过很多次通宵。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/2 2:38:05

中文命名实体识别实战:BERT-BiLSTM-CRF从原理到调优

简介:本资源面向中文命名实体识别(NER)方向的初学者与毕业设计、课程设计开发者,提供一套基于PyTorch实现的BERT-BiLSTM-CRF完整项目。项目将预训练BERT、双向LSTM与条件随机场CRF串联,覆盖数据加载、模型构建、训练、…

2026/10/2 2:38:05

YOLOv8行人检测实战:数据集处理与PyQt界面集成全流程

简介:面向有深度学习基础的行人检测开发者,这套YOLOv8行人检测工程包整合了标注数据集、训练权重与图形界面三个核心部分,基于YOLOv8算法在数千张街道和交通场景图像上训练,平均精度均值达90%以上,可直接用于行人识别&…

2026/10/2 2:38:05

CTF战队内部工具箱搭建指南:从目录结构到实战脚本

简介:这份资源是面向CTF竞赛选手与网络安全学习者的内部工具集合,聚焦于密码学与杂项题型的快速解题需求。包内共92个文件,以23个java源码、16个jar可执行库、13个sample样例、4个png与4个fxml界面文件为主,另含pcap流量包、多语言…

2026/10/2 3:28:08

Windows下VS2022+Intel oneAPI编译LSMLIB完整指南

编译LSMLIB这件事,光是搜资料就够折腾半天。网上关于这个库的资料不算少,但大多数都是Linux下的教程,到了Windows上基本就是一片空白。我自己在vs2022加intel oneAPI这套组合下把LSMLIB完整编译通过,还跑通了自带示例程序&#xf…

2026/10/2 3:28:08

IEEE39节点模型仿真搭建:从数据文件到暂态稳定分析

简介:这份资源面向电力系统分析、稳定性研究与教学场景,提供IEEE 39节点标准测试系统的MATLAB建模数据,适合从事电力系统仿真、控制策略设计及软件验证的工程师与高校师生使用。压缩包内共1个文件,为m脚本类型,整体约3…

2026/10/2 3:28:08

MODIS地表温度产品MOD11A2实用指南:数据处理与质量控制详解

做气候变化、生态遥感和陆面过程研究的朋友,估计都跟地表温度打过不少交道。真正常用、精度可查、延续性又好的全球一公里级地表温度产品,绕不开NASA发布的MODIS全球地表温度与发射率8天合成数据,也就是我们常说的MOD11A2。这个产品我从读研到…

2026/10/2 3:28:08

SkeyeWebPlayer九宫格视频调度系统深度解析

1. 这不是普通播放器,而是一套面向安防与工业场景的Web端视频调度系统SkeyeWebPlayer这个名字在安防、交通、能源、园区管理等行业的技术群里其实早就不陌生了。它不是那种点开就能播MP4的轻量级H5播放器,而是专为大规模视频流接入、多路实时预览、低延迟…

2026/10/2 3:28:08

电热综合能源市场双层出清模型与能源集线器建模实践

1. 为什么要把电和热放进同一个市场出清1.1 传统“电热分账”模式的尴尬前一阵子我在做一个园区级综合能源项目的仿真,任务是把电热综合能源市场的出清逻辑跑通。这个方向看似小众,实际上在综合能源系统、区域能源规划、电力市场机制设计里都是绕不开的核…

2026/10/2 3:23:07

个人量化交易系统落地指南:从数据回测到风控闭环

简介:一套基于Python的个人量化交易系统源码,面向个人投资者和量化爱好者,覆盖从行情数据采集、因子计算、策略生成到回测、模拟交易与风险监控的完整流程。压缩包大小约457KB,共91个文件,其中包括79个Python源文件、C…

2026/10/1 5:21:14

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/1 17:09:46

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑