ARTICLE DETAIL

资讯详情

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

深度学习轴承故障诊断平台实战:从数据准备到模型调优全指南

深度学习轴承故障诊断平台实战:从数据准备到模型调优全指南 简介基于深度学习的轴承故障诊断平台融合深度学习与机械故障诊断面向毕业设计、课程设计及人工智能应用方向的学习者与开发者。针对传统诊断依赖专家经验、效率低且难以应对复杂工况的问题提供了一套涵盖数据预处理、特征提取、模型训练与故障识别的完整工程方案。压缩包共63个文件包含11个Python功能脚本覆盖数据处理、模型训练、诊断输出与绘图等、10个MAT格式轴承数据集、34张模型训练与评估图表以及依赖说明、README文档和界面布局文件整体仅14.85MB结构清晰便于按模块查阅。目前已有59人学习适合需要复现完整流程或在此基础上改进算法的初学者和进阶者。平台整合了CNN、LSTM、GRU、MCNN-LSTM及YOLO等多个深度学习模型并附带混淆矩阵、ROC曲线、分类报告等结果可直接支撑故障分类与实时检测场景的复现与扩展。1. 拿到“基于深度学习的轴承故障诊断平台.zip”之前先想清楚一个问题手头有振动数据、需要快速得出“这台设备是正常还是故障”的工程师或者正在选深度学习毕设题目的学生见到这个包的第一反应通常是解压、装环境、跑通、看准确率。但真正决定这个平台值不值得用的不是训练集上那 99% 的准确率而是换到自己的设备、自己的采样率、自己的工况下它还能不能稳定输出结论。基于深度学习的轴承故障诊断平台本质上是一条从原始振动信号到故障类别标签的流水线数据读取、信号切分、模型训练、推理输出。它把传统诊断里“看频谱、找特征频率、定阈值”的专家流程变成了“喂波形、出类别”的端到端方案。适合两类人一类是设备状态监测工程师想快速搭识别原型再替换自己的数据另一类是深度学习实战学习者需要一个能完整拆解的案例。本文把这条流水线的原理、部署步骤和常见翻车点一次讲透让你拿到任何同类 zip 包都能独立玩明白。2. 深度学习凭什么做轴承故障诊断先看懂信号再判断平台方案2.1 振动信号里的故障痕迹特征频率、调制与深度学习的切入点轴承故障诊断的传统逻辑建立在转动机械的动力学规律上。当滚动轴承的内圈、外圈、滚动体出现局部损伤时每次滚动体经过损伤点都会产生冲击这个冲击会以故障特征频率的形式周期性出现在振动信号里。外圈故障频率 BPFO、内圈故障频率 BPFI、滚动体故障频率 BSF 的计算公式如下外圈故障BPFO (n / 2) × fr × (1 - d / D × cos α)内圈故障BPFI (n / 2) × fr × (1 d / D × cos α)滚动体故障BSF (D / (2d)) × fr × (1 - (d / D × cos α)²)其中 n 是滚动体数量fr 是转频d 是滚动体直径D 是节圆直径α 是接触角。实际采到的振动信号不是干净的等间隔冲击而是被设备固有频率调制、被环境噪声污染、被其他振源叠加的复杂波形。传统诊断专家会先做包络解调再在包络谱里找 BPFO 附近有没有峰值——这个过程需要经验而且转速波动、负载变化都会让特征频率偏移。深度学习切入的方式完全不同它不依赖你手算特征频率而是直接从原始波形或者简单的频谱输入里学习故障模式。一维卷积网络可以自动学到“大约每隔多少毫秒出现一次冲击”这类时间规律也可以学到“高频段能量分布变化”这类频率规律。理解特征频率公式仍然有价值因为它能帮你判断平台的数据标注是否合理如果训练数据的采样率、转速范围和你现场设备差太远模型学到的“规律”就迁移不过去。2.2 一维卷积、二维时频图与序列模型这个平台大概率选哪条路输入形态决定了模型结构。振动信号故障诊断平台里最常见的三种输入方案对比输入形态数据预处理常用模型优点缺点原始一维波形滑动窗口切分归一化1D CNN、ResNet1D端到端预处理简单对噪声和转速变化敏感频域幅值谱FFT 后取幅值MLP、1D CNN去掉了相位信息特征稳定丢失时域冲击位置信息二维时频图CWT / STFT 生成灰度图2D CNNResNet、VGG同时保留时间和频率信息计算量大预处理复杂面向工业落地和毕设场景的 zip 平台大多选择第一种原始一维波形 一维卷积。原因很实际预处理最简单不需要懂小波变换也能跑通而且一维卷积参数量小CPU 都能训练。少部分平台会提供短时傅里叶变换生成频谱图再喂给二维 CNN效果通常更好但生成时频图的计算时间和磁盘占用都成倍增长。模型主干方面最常见的是一维 ResNet 或者带注意力机制的一维 CNN。残差连接解决深层网络退化问题注意力机制让模型关注冲击发生的时段。如果你在解压后的目录里看到model.py或者net.py打开后大概率是Conv1d BatchNorm1d ReLU MaxPool1d的堆叠结构辅以跳跃连接。这类结构对振动信号的平移有一定鲁棒性但注意它不像图像识别那样天然对平移不变性做了大量数据增强所以训练时最好自己加随机裁剪和时间轴扰动。2.3 标签体系与数据集的对应关系四分类、十分类还是回归轴承故障诊断平台的标签设计需要和训练数据来源对齐。最经典的开源数据是凯斯西储大学CWRU轴承数据集它在驱动端和风扇端分别采集了正常、内圈故障、外圈故障、滚动体故障的信号每种故障又分 0.007、0.014、0.021 英寸几档损伤直径。因此你会看到两种常见标签方案四分类正常、内圈故障、外圈故障、滚动体故障。粗粒度类间差异大容易训练工业初筛够用。十分类左右在三类故障基础上叠加损伤直径级别比如“内圈故障 0.007 英寸”“内圈故障 0.014 英寸”。细粒度更贴近损伤程度评估但相似损伤尺寸之间的差异很小模型容易混淆需要更大数据量和更仔细的数据增强。判断一个 zip 平台是粗粒度还是细粒度直接看它的标签配置文件或者类别文件夹数量。如果训练脚本里num_classes是 4 而你的场景只需要判断“坏没坏”直接跑如果源数据集是 CWRU 的 10 类而你的现场只有“正常/异常”两类需求建议把标签重新映射合并而不是硬着头皮做 10 分类。另外注意少部分平台把任务做成回归——输出损伤尺寸的预测值而不是类别概率。回归任务的评估指标是 MAE 而不是准确率如果你看到脚本里 loss 是 MSE 而不是 CrossEntropy说明它走的是这条线别用分类的思维去调它。3. 拆开 zip 包从压缩包到第一条训练日志的完整流程3.1 解压前先做三个检查避免进入排错地狱拿到“基于深度学习的轴承故障诊断平台.zip”先别急着双击解压。压缩包在传输和拷贝过程中损坏是这类资源最常见的翻车原因检查顺序如下# 1. 检查 zip 完整性输出 No errors detected 才继续 unzip -t BearingFaultDiagnosisPlatform.zip # 2. 查看压缩包内文件列表确认没有明显的缺失 unzip -l BearingFaultDiagnosisPlatform.zip | head -30 # 3. 解压到指定目录避免中文路径和空格路径 mkdir -p ~/projects/bearing_platform unzip BearingFaultDiagnosisPlatform.zip -d ~/projects/bearing_platformunzip -t会逐个文件做 CRC 校验任何一文件损坏都会明确报错。见到could not find end of central directory或者invalid zip archive这类提示基本可以断定文件没有下载完整或者二次压缩时出了问题重新下载比尝试修复更省时间。解压路径建议用全英文、无空格的路径因为很多训练脚本里的路径拼接逻辑没有做兼容处理中文目录在某些 Windows Python 组合下会直接报编码错误。另一个值得留意的现象是“伪加密”。有些压缩包打开时提示需要密码但文件本身并没有真正加密只是 zip 的通用位标志被修改了。unzip -l能看到文件名但unzip解压时要求输入密码。Windows 自带资源管理器遇到伪加密会直接判定要密码换成 7-Zip 或 macOS 自带的归档工具往往能直接解开。这不是破解密码而是绕过错误的加密标志位。3.2 目录结构与运行环境收到包后的十分钟体检解压完成后先对整个项目做一次目录体检。这类平台的标准目录形态大致如下bearing_platform/ ├── configs/ # 训练参数配置yaml 或 json │ └── bearing.yaml ├── data/ # 原始数据和切分后的样本 │ ├── raw/ # 原始振动信号可能按类别分子目录 │ └── processed/ # 切分好的 npy 或 npz 样本 ├── models/ # 网络结构定义 │ └── cnn1d.py ├── utils/ # 数据加载、指标计算、可视化 ├── train.py # 训练入口 ├── predict.py # 推理入口 ├── requirements.txt # Python 依赖清单 └── README.md # 说明文档先打开requirements.txt看依赖范围再打开README.md看作者写的运行方式——这两个文件能让你避开 90% 的环境问题。常见的深度学习平台依赖组合是 PyTorch 系torch、torchvision或者 TensorFlow 系tensorflow、keras外加 numpy、scipy、pandas、matplotlib、scikit-learn 这些常规库。安装时不要一股脑pip install -r requirements.txt先确认你的显卡驱动和 CUDA 版本再装 PyTorch否则装完发现 GPU 用不了还得卸载重来。# 创建独立虚拟环境Python 3.8 到 3.10 是这个生态比较稳的区间 python -m venv ~/venvs/bearing_env source ~/venvs/bearing_env/bin/activate # 先装 PyTorch再装其余依赖以 Linux CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txt # 验证 GPU 可用 python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))如果输出True和你的显卡型号环境就齐了。输出False也不一定废轴承故障诊断的一维卷积模型参数量通常在几十万到几百万之间纯 CPU 训练小数据集也能出结果只是慢。训练脚本里一般有device参数没有的话在train.py开头手动改成device torch.device(cuda if torch.cuda.is_available() else cpu)。3.3 最小训练命令与核心启动参数环境就绪后先不改任何代码用平台默认配置跑一次完整训练。这一步验证的是“代码能不能跑通”而不是“效果好不好”。主流平台的训练入口是train.py通过命令行参数覆盖配置文件# 最小训练命令读默认配置训练 20 个 epoch python train.py --config configs/bearing.yaml --epochs 20 --batch_size 32 # 如果平台支持断点续训通常带 --resume 参数 python train.py --resume runs/best_model.pth --epochs 50训练启动后重点观察三样东西。第一日志里有没有输出每个 batch 的 loss第二每个 epoch 结束后的验证集准确率是否在稳步上升第三训练完成后runs/目录下是否生成了权重文件和日志文件。如果 loss 一开始就在 2.3 附近不动多分类交叉熵的随机初始值大约是 ln(num_classes)且准确率始终徘徊在随机水平先怀疑数据加载环节别急着调模型。核心启动参数的作用如下--epochs控制训练轮数20 轮只够验证跑通--batch_size是每批样本数显存不足时报 CUDA out of memory 就把它调小--lr是学习率平台默认值一般在 1e-3 到 1e-4 之间--seed固定随机种子复现结果时必设。跑通之后再逐步把 epochs 拉回平台推荐的 100 到 200 轮。训练过程中如果发现验证集准确率上去了但训练集准确率几乎满点说明过拟合已经开始如果两者都低先检查数据归一化。振动信号的量纲五花八门加速度传感器输出可能是 m/s²、g 或 mV不做归一化会让模型训练极不稳定。看utils/里的数据加载代码确认有没有做标准化或归一化没有就自己加一层StandardScaler。3.4 推理脚本与结果输出拿一条真实信号验证模型训练完模型下一步是用predict.py对没见过的数据做推理。推理脚本的常见用法是给一个文件路径输出故障类别和置信度python predict.py --checkpoint runs/best_model.pth --input data/raw/内圈故障_样本_0001.csv --output result.json输出结果通常是 JSON 格式包含predicted_class、confidence和各类别概率。拿到结果后不要只看预测标签要同时看各类别概率分布如果“内圈故障”和“外圈故障”的概率都在 0.45 左右说明模型在这两个类别边界上严重不确定这时候硬选最大概率做决策很危险后面第 6 章会专门讲阈值校准。推理阶段最容易踩的坑是输入格式不一致。训练时平台把原始信号切成了固定长度窗口比如每段 1024 点、2048 点推理时如果输入是一条任意长度的 CSV数据加载器可能会直接报维度错误或者静默地截断/补齐导致结果失真。正确做法是先看训练脚本里窗口长度window_size是多少推理前把输入信号按同样的窗口长度切分或者对过长信号做滑窗推理后对结果做多数投票。少数平台会把推理封装成“输入一条 CSV 输出一个标签”的便捷模式但内部也做了滑窗投票这类平台更接近可用的产品形态。4. 换自己的数据数据划分、滑动窗口参数与训练调优4.1 自建数据集的目录组织按类别分子目录是最稳的结构把平台默认数据集换成你自己的振动数据是决定这套方案能否落地的关键一步。最稳妥、最不容易出错的目录组织方式是按类别分文件夹my_data/ ├── train/ │ ├── normal/ # 正常状态信号每个文件是一段连续采集 │ ├── inner_race/ # 内圈故障 │ ├── outer_race/ # 外圈故障 │ └── rolling_element/ # 滚动体故障 ├── val/ # 结构同 train └── test/ # 结构同 train各目录下每个文件是一段连续采集的原始信号格式可以是 CSV、TXT 或 npy。平台的数据加载器通常自带按目录读取的功能你只需要把文件放对位置。如果平台要求的是标签文件CSV 里一列路径、一列标签那就手动生成一张映射表。工程上推荐目录方式而不是单一 CSV因为新增样本不用改标签文件而且目录结构本身就是可审计的标签记录。数据量的最低要求每个类别至少 200 到 300 个训练窗口。一个窗口如果切 1024 点在 25.6 kHz 采样率下对应 40 毫秒信号也就是每个类别有 200 段 40 毫秒的样本。少于这个量模型极易过拟合准确率再高也不可信。现场采集时注意记录设备的转速和负载这些元信息以后做模型迁移和诊断结论分析都用得上。4.2 滑动窗口切分window_size 与 stride 的搭配逻辑原始信号不是直接喂给模型的要做滑动窗口切分。窗口长度决定模型能看到的“时间范围”步长决定样本数量和重叠度。下面是实际可用的切分脚本import numpy as np def sliding_window_split(signal, window_size1024, stride512, sample_rate25600): 滑动窗口切分原始振动信号 signal: 1D numpy array原始信号 window_size: 每个样本的点数1024 点 0.04s25.6kHz 采样率 stride: 窗口滑动步长小于 window_size 时样本有重叠 返回: (num_windows, window_size) 的二维数组 num_windows (len(signal) - window_size) // stride 1 windows np.zeros((num_windows, window_size), dtypenp.float32) for i in range(num_windows): start i * stride windows[i] signal[start:start window_size] return windows # 示例把一段 10 秒、25.6kHz 的信号切成 1024 点窗口重叠 50% signal np.loadtxt(normal_001.csv, delimiter,) windows sliding_window_split(signal, window_size1024, stride512) print(f切出 {windows.shape[0]} 个样本形状 {windows.shape})代码逻辑不复杂但参数选择有讲究。window_size至少要覆盖一个故障冲击周期。低速设备转频低、冲击间隔大窗口要长高速设备可以短一些。经验值是至少包含 5 到 10 个完整的冲击间隔比如转频 30 Hz、外圈故障特征频率约 100 Hz冲击间隔 10 毫秒窗口取 0.1 秒25.6kHz 下就是 2560 点比较稳。stride控制重叠率stride window_size / 2是常用起点重叠 50%过小的 stride 会让相邻样本高度相关相当于人为放大训练集验证集准确率虚高过大的 stride 会浪费数据。切分之后必须做归一化。每个窗口独立归一化到零均值单位方差还是整段信号一起归一化推荐按窗口独立归一化因为推理时你拿到的就是一条实时片段不可能先看未来数据算出全局均值。代码里加上# 每个窗口独立标准化符合在线推理场景 for i in range(windows.shape[0]): mean, std windows[i].mean(), windows[i].std() if std 1e-8: # 防止静默段除零 windows[i] (windows[i] - mean) / std4.3 训练必调参数批次大小、学习率与早停策略数据准备好之后回到train.py做参数调整。默认参数是在原数据集上调出来的换到自己的数据时重点调四个参数。学习率是最敏感的。默认 1e-3 如果训练震荡loss 上下乱跳、准确率忽高忽低直接降到 3e-4 或 1e-4。一维 CNN 对小数据集相当敏感学习率稍高就会在最优解附近来回横跳。把学习率调成阶梯下降或者余弦退火比固定学习率省心得多。batch_size在显存允许范围内尽量用 32 或 64太大的 batch256 以上会让梯度方向过于平均小数据集上收敛变慢。epochs不要死磕默认值配一个早停# 伪代码示意在训练循环里做早停patience 表示容忍多少次验证集不提升 best_val_acc 0.0 patience 15 bad_epochs 0 for epoch in range(epochs): train_one_epoch() val_acc evaluate() if val_acc best_val_acc: best_val_acc val_acc bad_epochs 0 torch.save(model.state_dict(), best_model.pth) else: bad_epochs 1 if bad_epochs patience: print(fEpoch {epoch}: 验证集 {patience} 轮未提升停止训练) break早停不是玄学是防止你把测试集“看”太多遍。平台默认训练 200 轮你的数据量少的话 50 轮就过拟合了硬跑完 200 轮只会记住训练集的噪声。模型保存策略也有讲究只保存验证集最好的那一次不要保存最后一个 epoch最后一个 epoch 大概率不是最优的。类别不平衡几乎是轴承故障诊断里的常态。现场设备绝大多数时间正常故障样本稀缺滚动体故障的冲击特征比内圈外圈弱更难学。处理办法有两种一是用WeightedRandomSampler给少数类加权采样让每个 epoch 里少数类出现的次数和多数类相当二是在损失函数里给少数类加大权重。前者更稳因为后者如果类别数多、权重设置不当会把损失值搞得很不稳定。做加权采样时记得验证集保持原始分布否则验证准确率会被少数类样本数量“撑高”和实际现场表现对不上。4.4 训练过程的监控指标别只盯准确率轴承故障诊断场景里准确率是最容易被骗的指标。如果故障样本只占 5%模型把所有样本都判成正常准确率也有 95%。所以要同时看每个类别的召回率和精确率特别是故障类别的召回率——漏报一台故障设备比多报一次误警的成本高得多。平台如果自带了混淆矩阵输出直接用没有的话用sklearn.metrics.classification_report打印出来from sklearn.metrics import classification_report # y_true 和 y_pred 分别是验证集真实标签和模型预测标签 print(classification_report(y_true, y_pred, target_names[normal, inner, outer, rolling]))输出里每一行的 recall 是“这个故障类别的样本有多少被找出来了”precision 是“模型说它是这个类别时有多可信”。两个都低说明模型没学会这个类别precision 低、recall 高说明模型这个类别判得过于激进recall 低、precision 高说明模型这个类别判得过于保守。后面第 6 章会把这个问题落到决策阈值上细讲。监控训练过程还要留意验证集和训练集的分布一致性。滑动窗口切分时如果按“所有类别的窗口全部混在一起再随机切训练/验证”同一个原始信号切出来的窗口可能同时落在训练集和验证集里验证集准确率会虚高 5 到 10 个百分点。正确做法是按“段”划分先把每段完整信号划到训练域或验证域再做窗口切分保证同一段信号的两个窗口不会跨域。这也是常见的数据泄漏之一。5. 避坑与排查压缩包、文件编码、显存与类别失衡的高频问题5.1 解压报错 “invalid zip archive: could not find end of central directory”现象unzip提示找不到中央目录结尾标记Windows 资源管理器双击解压直接失败。原因zip 包的 EOCD 记录位于文件末尾找不到它只有两种可能——文件下载不完整或者文件被二次传输时截断。这个“基于深度学习的轴承故障诊断平台.zip”如果是通过网盘、聊天软件等渠道传过一手的极容易出这个问题。可以理解为压缩包的“索引”在尾部数据没下载完索引自然缺失。解决先看文件大小和你拿到的资源描述是否一致不一致直接重新下载。如果大小一致仍报错运行zip -F archive.zip --out repaired.zip尝试修复修复后先解压出README.md或代码文件看是否完整。注意修复只能找回部分数据模型权重这类二进制文件修复后很可能损坏但解压不报错训练时加载 checkpoint 会莫名报尺寸不匹配——这时只能重下没有后悔药。5.2 解压后中文文件名乱码Windows 编码与 Linux 编码打架现象在 Linux 或 macOS 下解压代码文件里的注释正常但数据文件名变成了ڹ.csv这样的乱码。原因Windows 下打包 zip 时文件名用 GBK 编码而 Linux 的unzip默认按 UTF-8 解码两边对不上。数据目录里的故障类别名字一旦乱码数据加载器按文件名匹配标签时就会把样本全部跳过或报错。解决解压时指定编码Linux 用unzip -O GBK archive.zipmacOS 用ditto -x -k archive.zip dest_dir系统会自动探测编码Windows 上用 7-Zip 打开后手动选择编码。解压完成后立刻检查数据目录的类别文件夹名是不是能正确读出来的中文或英文。为避免后续麻烦建议把所有数据目录重命名成英文的normal、inner_race、outer_race、rolling_element再改配置里的路径。5.3 训练时 CUDA out of memory但模型明明很小现象一维 CNN 参数量只有几十万一跑训练就显存溢出别人同样模型能跑你的跑不了。原因显存占用的大头往往不是模型权重而是中间激活值。输入窗口长度过长、batch_size 过大、或者数据加载器里做了过多的数据增强都会让激活值暴涨。比如输入从 1024 点改成 8192 点激活值直接涨 8 倍显存自然爆。解决第一步把 batch_size 降到 16 或 8 重试第二步检查输入信号长度找到训练脚本里window_size参数并逐步减半第三步用自动混合精度训练PyTorch 里一句话的事scaler torch.cuda.amp.GradScaler() with torch.cuda.amp.autocast(): outputs model(inputs) loss criterion(outputs, labels) scaler.scale(loss).backward()注意混合精度对一维 CNN 的加速有限但它能实打实省一半显存。如果这三步做完还爆多半是数据加载器在__getitem__里把整段信号一次性读进了内存改成按需读取。5.4 验证集准确率 99%现场实测频繁误报现象模型在自己的验证集上接近满分拿到车间新采的数据一测正常设备报故障、故障设备报正常完全没法用。原因这是领域偏移问题也叫分布外问题。实验室数据集比如 CWRU是在恒定转速、恒定负载、单一传感器的条件下采的现场设备的转速波动、负载变化、背景噪声、传感器安装位置全都不一样。模型学到的是“实验室条件下的故障模式”不是“物理上的故障本质”。解决第一步用现场数据做微调只微调最后两层全连接层冻结前面的卷积层通常能保住大部分已学特征并适配现场分布。第二步做数据增强给训练信号加白噪声、做幅值随机缩放、对时间轴做小幅拉伸让模型不那么依赖精确的采样率和幅值。第三步是前向校验把现场数据的工况参数转速、载荷也作为模型输入的一部分而不是只用原始波形。不要轻信“预训练模型直接就能泛化”的说法工业现场的数据分布永远比你想象的更复杂。5.5 滚动体故障类别精度崩塌其他类别都正常现象混淆矩阵里 normal、inner_race、outer_race 都超过 95%唯独 rolling_element 的召回率只有 60%。原因滚动体故障的振动特征确实比内圈和外圈弱。内圈和外圈故障是滚动体直接撞击固定损伤点冲击能量大、周期规律强滚动体故障是损伤点跟着滚动体旋转冲击方向不断变化信号被随机调制特征在频域里是“扩散”的。同时如果不做类别加权模型优化目标天然偏向样本多的类别滚动体故障如果样本还少就被模型“牺牲”掉了。解决先用上一章说的class_weight或WeightedRandomSampler把数据喂平衡再把滚动体故障样本按住不放地扩增——对原始信号做不同信噪比的加噪复制或者用短时傅里叶变换后的时频图训练一个并列的二维 CNN 做集成。经验上时频图对滚动体故障的区分度比原始波形好不少因为故障特征在时间和频率两个维度上都有表现二维卷积更能抓住它。如果平台不支持时频图输入改起来工作量不小但值得试。6. 让平台真正可信混淆矩阵、决策阈值校准与特征可视化模型训练完、准确率也过了 95%离“能投入使用”还差最后一步验证模型在什么条件下会失效以及把决策边界调到符合你现场的成本结构。这步不做前面的 95% 只是一个数字。先做混淆矩阵的细读。平台自带的训练日志如果只打印了 accuracy补一段可视化代码import matplotlib.pyplot as plt from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix cm confusion_matrix(y_true, y_pred) disp ConfusionMatrixDisplay(cm, display_labels[normal, inner, outer, rolling]) disp.plot(cmapBlues) plt.savefig(confusion_matrix.png, dpi150)看混淆矩阵不能只看对角线要看“错到哪去了”。如果内圈故障被错判成外圈故障说明模型在区分两类故障时依赖的特征不稳定——这两种故障的冲击频率不同但模型可能只学到了“高频冲击”这个共性。如果正常样本被错判成故障说明模型把某个转速下的常规振动当成了故障模式这是过拟合了训练数据的工况。然后是决策阈值校准。平台的推理默认取概率最大的类别这在类别不平衡的现场是危险的。假设模型对一条样本输出“正常 0.48 / 外圈故障 0.52”直接判外圈故障但误报一次意味着停机检查而漏过一次外圈故障可能意味着整条产线瘫痪。正确的做法是不要用 0.5 作为阈值而是用验证集画出召回率和误报率的权衡曲线再根据现场成本选阈值import numpy as np # 假设模型输出所有验证样本的外圈故障概率 prob_pos # y_true 中 1 表示该样本确实为外圈故障 thresholds np.linspace(0.3, 0.95, 20) for thr in thresholds: y_pred (prob_pos thr).astype(int) recall (y_pred[y_true 1] 1).mean() # 故障样本被抓住的比例 fpr (y_pred[y_true 0] 1).mean() # 正常样本被误报的比例 print(f阈值 {thr:.2f} | 召回率 {recall:.3f} | 误报率 {fpr:.3f})这条曲线会告诉你想抓住 95% 的故障你要容忍多少误报想做到零误报你会漏掉多少故障。把这组数据拿给现场决策的人看比报一个 99% 的准确率有用得多——决策阈值本质上是钱的问题不是模型的问题。最后做一次特征可视化也顺便给自己一个解释模型的抓手。取一两条故障样本把模型最后一个卷积层的输出做全局平均池化再对所有验证集样本做 t-SNE 降维。如果同一类别的点聚成明显的簇而不同类别界限清晰说明模型学到的特征是有物理意义的如果类别完全混杂但训练准确率很高说明模型在硬背样本泛化能力存疑。这个检查 10 分钟就能做完但它决定了你敢不敢把这个模型从实验室带到现场。我个人的习惯是任何平台拿到手第一周只做两件事——跑通默认配置、换自己的数据做一次完整的阈值校准实验不去碰网络结构、不去调复杂的训练技巧。平台的结构是别人验证过的但你的数据分布和决策成本是只有你自己知道的。校准完阈值、看过混淆矩阵和可视化你才有资格说“这套基于深度学习的轴承故障诊断方案在我的场景里可用”。数据分布一变阈值和结论都要跟着变这就是把模型当工程做而不是当论文做的区别。希望这些步骤能帮你在自己的数据上少走一段弯路。本文还有配套的精品资源点击获取
返回列表