滚动轴承故障诊断实战:从数据切分到模型部署的完整避坑指南
2026/9/23 23:02:23 网站建设 项目流程

简介:面向滚动轴承外圈故障诊断的MATLAB脚本集合,涵盖故障信号生成、CEEMD分解与频谱分析等环节,适合机械工程、自动化、物联网及设备健康管理方向的学习者与工程技术人员。资源以completeu42方法为核心思路,结合CEEMD(完全集成经验模态分解)与频谱分析技术,对人工模拟的滚动轴承外圈故障信号进行特征提取与识别,能够帮助读者建立起从故障模拟、信号分解到特征频率判断的完整诊断流程。CEEMD是针对非线性和非平稳振动信号的有效分析手段,在轴承故障诊断中尤为实用,可清晰突出故障特征,对外圈故障的早期发现与设备安全运行至关重要。包内共3个文件,全部为MATLAB脚本(.m),分别对应故障信号生成、CEEMD分解结果处理与频谱包络谱分析等关键环节,整体压缩包仅1KB,轻量便捷,便于直接上机运行与代码研读。目前已有143人学习下载,对于希望理解滚动轴承故障机理与诊断流程的初学者,这套资源提供了可操作的实验脚本,可用作课程设计、课题验证或工程参考,辅助提升设备状态监测与故障预判能力,整体代码结构简明,适合作为滚动轴承故障诊断方向的起始练习素材。

1. 滚动轴承故障诊断:为什么同一套代码在不同现场差出一个数量级

滚动轴承故障诊断这个方向,看着门槛不高,数据拿去跑个分类器就能出 90% 以上的准确率,可真把模型往现场一放,往往立刻原形毕露。我在好几个项目里见过同一种现象:实验室里对照实验做得漂漂亮亮,转速恒定、载荷恒定、故障是人为加工出来的,模型表现接近完美;换到实际机泵或电机上,转速波动、负载变化、噪声来源复杂,原来那套模型的准确率能掉到六成以下。很多人第一反应是“模型不行”,但真正的问题多数出在数据切分和特征提取上——训练集和验证集被切“脏”了,模型学到的不是故障特征,而是运行工况的标签。

这篇文章我就按自己实际做轴承故障诊断的流程来拆:从数据组织、信号预处理、特征工程,到模型训练和现场部署前必须做的验证。无论你拿到手的压缩包叫什么名字,里面是 CWRU 这类公开数据集还是自己采集的振动数据,主线都逃不开这几步。适合谁看?刚入门不知道从哪下手的初学者,以及跑通了一个 demo 但现场表现不稳定的从业者。前者能照着把流程搭起来,后者能在避坑章节里找到自己翻车的原因。

2. 数据与工况组织:开始建模前,先把数据集切分的规矩立住

2.1 数据集命名里的信息量:先看懂工况再动手

像“completeu42”这种后缀,如果原始数据来源于实验台,通常不是随机的字符串,而是某种记录习惯的残留:u 可能指代某类工况(unit/under load),42 可能是电机负载档位、采样批次或者传感器通道编号。不同实验室、不同数据包的命名规则千差万别,但有一个原则是通用的——先花半小时把每个文件对应的转速、负载、故障类型、故障尺寸弄清楚,再开始写任何代码。跳过这一步,后面所有统计分析都可能是错位的。

常见做法是建一个数据清单表,把每个文件的元信息列出来,至少包含四列:工况编号、转速、负载、故障类型。如果你拿到的压缩包里有 README 或 Excel 说明文件,以它为准;没有说明文件,就按文件名的规律去推断,推断不出来就按采集顺序分组。这一步看着笨,却是后期排查问题时最可靠的锚点。

公开数据里最常用的是西储大学轴承数据中心那套振动数据,故障类型覆盖滚动体、内圈、外圈,故障尺寸有 0.007、0.014、0.021 英寸三档,负载从 0 到 3 hp 四档。这套数据胜在标注齐全,适合做算法验证。但它也有明显局限:采样率偏高(12 kHz 和 48 kHz 两档)、转速相对稳定、故障是电火花加工的规则损伤,和真实工况下的剥落、磨损、点蚀有本质区别。所以公开数据只能用来验证方法和调参,不能作为“模型在现场可用”的证据。

2.2 标签规范和样本组织:不要让故障类型与工况强相关

轴承故障诊断的分类任务,标签体系一般按“正常 + 内圈 + 外圈 + 滚动体”划分,故障尺寸如果有多档,可以当成独立类别,也可以合并成大故障和小故障两类。我建议第一版模型只用四分类,把故障尺寸合并,因为尺寸差异反映的是故障严重程度,不是故障位置,混在类别里会让特征学习变得不稳定。

样本组织是这里最容易埋雷的环节。原始振动信号是一条长序列,需要切片成样本。切片参数有两个:单个样本长度和重叠率。常见做法是取转频对应周期的整数倍,比如转频 30 Hz,每圈约 0.033 秒,采样率 12 kHz 下一圈约 400 个点,一个样本取 4 圈就是 1600 个点,再补到 2048 点方便后续做 FFT。重叠率一般设在 50% 到 75% 之间,目的是在有限的数据量里增加样本数量,但重叠率过高会让相邻样本高度相似,训练集和验证集之间容易串样本,这一点在 2.3 里会专门说。

2.3 数据切分纪律:按工况划分,而不是按样本随机划分

这是整篇文章里最重要的一条原则。很多人习惯用 sklearn 的 train_test_split 直接把所有样本随机分成两份,这在轴承故障诊断里是典型的错误做法。原因很简单:同一个故障、同一段信号切出来的相邻样本,波形几乎一样,随机切分后训练集和验证集里会出现来自同一原始片段的近亲样本,验证集准确率虚高得吓人,但模型一到独立工况就歇菜。

正确做法是按工况组切分,即把同一转速、同一负载下的所有样本视为一个整体,整个工况组只能出现在训练集或验证集中。代码上可以用 GroupShuffleSplit 实现:

from sklearn.model_selection import GroupShuffleSplit # X: 样本特征矩阵, y: 标签, groups: 每个样本所属的工况组编号 splitter = GroupShuffleSplit(n_splits=1, test_size=0.3, random_state=42) train_idx, val_idx = next(splitter.split(X, y, groups=groups)) X_train, X_val = X[train_idx], X[val_idx] y_train, y_val = y[train_idx], y[val_idx]

这段代码的逻辑核心是groups参数——它告诉切分器“哪些样本属于同一个组”,切分时整个组被完整保留在训练侧或验证侧,而不是把组打散后随机分配。test_size=0.3表示验证集占 30%,但这 30% 是按组数量计算而不是按样本数量计算的,所以组的总数量至少要 10 个以上,否则验证集的代表性不足。random_state固定下来是为了实验可复现,调参时不要频繁改动。

更严格的验证方式是“留一工况”验证:假设有 8 个工况组,每次拿 7 组训练、1 组验证,轮流 8 次取平均。这种方式最接近现场真实条件,因为现场部署时模型面对的往往是训练数据里从未出现过的工况组合。代价是训练次数成倍增加,适合在模型定稿前做一次最终评估,日常调参用 GroupShuffleSplit 就够了。

3. 信号预处理与特征工程:时频特征和包络谱的参数到底怎么设

3.1 采样率与样本长度:先算清楚物理量,再定参数

特征提取的第一件事是确认采样率。12 kHz 采样率下能分析的最高频率是 6 kHz(奈奎斯特频率),对于大多数工业轴承,故障特征频率集中在几百赫兹到几千赫兹,12 kHz 够用;48 kHz 的公开数据能覆盖更高的共振频带,但数据量大,训练更慢。现场采集时采样率通常取 25.6 kHz 或 51.2 kHz,这是工业采集仪的常见档位,因为便于与转速同步采集模块配合。

样本长度的选择要同时照顾频率分辨率和工况覆盖。FFT 的频率分辨率等于采样率除以点数,12 kHz 采样、2048 点,分辨率约 5.86 Hz。轴承的转速通常在 10 到 60 Hz 之间,外圈故障特征频率一般是转频的 3 到 5 倍,也就是 30 到 300 Hz 区间,5.86 Hz 的分辨率完全够用。但如果你的设备是低速重载轴承,转频只有 2 Hz,故障特征频率可能不到 10 Hz,这时 2048 点就不够了,应该把样本长度增加到 8192 甚至 16384 点。判断标准就一条:样本至少要覆盖 2 到 3 圈完整的转动周期。

3.2 特征计算的主流方案:时域、频域、包络域三件套

特征工程在轴承故障诊断里有两条路线:一条是手动提取时域、频域、包络域特征,交给传统机器学习分类器;另一条是直接用原始信号训练 1D-CNN,让网络自己学特征。我个人的习惯是先用手动特征建立基线,再用 CNN 去试,因为手动特征工程能帮你理解数据,而 CNN 的结果能反过来验证你对特征的理解是否正确。

手动特征最少要覆盖三组:时域的 RMS、峭度、峰值因子;频域的功率谱重心、谱峰能量占比;包络域的包络谱峰值频率和包络能量。RMS 对整体振动水平敏感,峭度对冲击性故障(早期剥落)敏感,频域重心反映能量分布。下面这段代码是一套可直接复用的特征提取函数:

import numpy as np from scipy import signal def extract_bearing_features(x, fs): # 时域特征:RMS、峭度、峰值因子 rms = np.sqrt(np.mean(x ** 2)) kurt = np.mean((x - np.mean(x)) ** 4) / (np.std(x) ** 4 + 1e-12) peak_factor = np.max(np.abs(x)) / (rms + 1e-12) # 频域特征:功率谱重心和谱峰对应频率 f, psd = signal.welch(x, fs=fs, nperseg=min(1024, len(x))) spectral_centroid = np.sum(f * psd) / (np.sum(psd) + 1e-12) peak_freq = f[np.argmax(psd)] # 包络域特征:先带通滤波再希尔伯特解调 low, high = 2000, 5000 b, a = signal.butter(4, [low, high], btype='bandpass', fs=fs) x_filtered = signal.filtfilt(b, a, x) envelope = np.abs(signal.hilbert(x_filtered)) f_env, psd_env = signal.welch(envelope, fs=fs, nperseg=min(2048, len(x))) env_peak_freq = f_env[np.argmax(psd_env)] return { 'rms': rms, 'kurtosis': kurt, 'peak_factor': peak_factor, 'spectral_centroid': spectral_centroid, 'fft_peak_freq': peak_freq, 'envelope_peak_freq': env_peak_freq, 'envelope_energy': np.sum(psd_env) }

参数说明:nperseg直接影响频率分辨率,1024 点对应约 11.7 Hz 分辨率,适合快速预览;如果后续发现峰值频率差异不明显,把它提高到 4096 会平滑谱线,但分辨率更高。带通滤波器的lowhigh参数需要按轴承的共振频带调整,2000 到 5000 Hz 是一个经验值,具体怎么选,第三节末尾展开。filtfilt是零相位滤波,不会引入相位偏移,这点对包络解调很重要——如果用普通的lfilter,包络谱峰值频率会出现偏移,导致计算结果与理论值对不上。

3.3 包络谱的中心频率:别拍脑袋,用谱峭度找共振频带

包络分析是轴承故障诊断里最有效的手段,原理是:轴承局部损伤产生的冲击会激励起结构的高频共振,把这段高频带通滤波出来,再求包络并做 FFT,就能在低频段看到清晰的故障特征频率。但这里有一个参数直接决定成败——带通滤波器的频率范围。如果滤波范围落在共振频带之外,包络谱里什么都看不到。

经验做法是先做一次快速谱峭度分析来定位共振频带。谱峭度可以理解成“每个频率分量上的峭度分布”,冲击信号会在共振频带处呈现明显的峭度峰。Python 生态里没有现成的快速谱峭度实现,常见做法是用scipy的短时傅里叶变换配合手动筛选,或者直接用经验值:多数电机轴承的共振频带在 2 到 6 kHz 之间,先试 2000 到 5000 Hz,如果包络谱峰值频率和理论故障特征频率对不上,再把频带向高频方向移动,500 到 1000 Hz 地试探。

判断包络谱好不好用的是理论故障特征频率。内圈、外圈、滚动体的特征频率可以用轴承的节径、滚动体数量和接触角计算出来,实际做的时候一般直接查轴承手册,或者用诊断软件自动匹配。如果包络谱的峰值频率恰好落在理论值附近(误差小于 1%),这条频带选对了;对不上就调整滤波范围重来。这一步是纯经验活,也是做久了之后最容易跟新人拉开差距的地方,遇到疑难故障时多花半小时做频带扫描,比换任何高级模型都管用。

4. 模型训练与审查:从经典基线到 1D-CNN 的最小可复现流程

4.1 为什么先跑传统机器学习基线

很多人一上来就上深度学习,觉得 SVM 老掉牙。但我的经验是:传统机器学习在轴承故障诊断里从来不过时。特征维度低、样本量不大、对算力要求低,随机森林跑一次只要几秒钟,却能给你一个足够可靠的性能天花板参考。如果一个特征集连随机森林都训不明白,那问题大概率出在特征工程上,换成卷积神经网络也一样学不到东西。

基线模型推荐先跑随机森林,因为它对特征尺度不敏感、不需要归一化、能输出特征重要性,方便你检查哪些特征在起作用。特征重要性这个输出特别关键——如果 RMS 的重要性排第一,而峭度重要性几乎为零,可能说明你的故障类型以磨损类为主,冲击性特征不明显;反过来如果峭度和包络峰值频率排第一,说明故障处于早期点蚀剥落阶段。这一步分析的价值在于,它能验证你的特征工程是否符合物理直觉,而不是把特征一股脑丢给模型然后看准确率。

用随机森林时不需要做特征归一化,但建议把特征统一成float32类型,减少内存占用。优秀的特征集配合随机森林,在公开数据上通常能达到 95% 以上的分类准确率,这份基线就是你后面所有模型对比的标尺。如果 CNN 的结果还不如随机森林,别急着堆网络层数,先回头看数据和特征。

4.2 1D-CNN 最小可复现:网络结构、训练参数与调用细节

当基线稳定在 95% 附近,并且你确认验证集的切分方式没有泄漏问题之后,再上 1D-CNN。1D-CNN 直接吃原始信号,卷积核在时间轴上滑动,自动提取局部冲击模式和周期性特征,省去了手动设计特征的工作量。下面是能直接跑通的一个最小结构:

import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv1D, MaxPooling1D, Flatten, Dense, Dropout from tensorflow.keras.optimizers import Adam from tensorflow.keras.utils import to_categorical from sklearn.model_selection import GroupShuffleSplit def build_1d_cnn(input_length, num_classes, conv_filters=32, kernel_size=64): model = Sequential([ Conv1D(filters=conv_filters, kernel_size=kernel_size, strides=4, activation='relu', input_shape=(input_length, 1)), MaxPooling1D(pool_size=2), Conv1D(filters=conv_filters * 2, kernel_size=3, activation='relu'), MaxPooling1D(pool_size=2), Flatten(), Dense(128, activation='relu'), Dropout(0.5), Dense(num_classes, activation='softmax') ]) model.compile(optimizer=Adam(learning_rate=1e-3), loss='categorical_crossentropy', metrics=['accuracy']) return model X = np.load('signal_samples.npy') # 形状: (n_samples, n_points) y = np.load('labels.npy') # 形状: (n_samples,) groups = np.load('group_ids.npy') # 工况组编号数组 # 数据形状调整为 (n_samples, n_points, 1) X = X.reshape(X.shape[0], X.shape[1], 1) splitter = GroupShuffleSplit(n_splits=1, test_size=0.3, random_state=42) train_idx, val_idx = next(splitter.split(X, y, groups=groups)) y_train = to_categorical(y[train_idx], num_classes=4) y_val = to_categorical(y[val_idx], num_classes=4) model = build_1d_cnn(input_length=X.shape[1], num_classes=4) history = model.fit(X[train_idx], y_train, validation_data=(X[val_idx], y_val), epochs=30, batch_size=64, verbose=1)

几个参数的设置逻辑需要单独说明。kernel_size=64不是随手写的:输入信号采样率 12 kHz,一个 64 点的卷积核正好覆盖约 5.3 毫秒的时间窗,对于 30 Hz 转频对应的 33 毫秒周期来说,足够捕获一次冲击的上升沿。strides=4是为了下采样,等效于在时间维度上压缩信号,减少后续层的计算量。第一个卷积层的通道数conv_filters=32是起点,如果训练集样本量在几千级别,32 通道足够学出有效特征;通道数翻倍到 64 或 128 只会增加过拟合风险,除非样本量到了数万。

训练轮次epochs=30是经验值,配合早停回调更好——当验证集准确率连续 5 轮不涨就提前终止,避免过拟合。batch_size=64在大多数机器上都稳定,显存或内存紧张时可以降到 32。训练完成后必须检查验证集准确率和随机森林基线的差距,如果 CNN 只比基线高 1% 到 2%,那说明手动特征已经抓住了主要信息,CNN 的价值主要体现在部署时省去特征提取环节,而不是准确率碾压。

4.3 评估指标与报告解读:准确率之外还要看哪些

分类任务大家习惯性只看准确率,但在轴承故障诊断里,准确率会骗人。如果数据集里正常样本占 80%,故障样本占 20%,一个“永远预测正常”的模型也能拿到 80% 准确率,看起来不错,实际上对故障完全没感知。正确的评估方式是看混淆矩阵和每一类的精确率、召回率。内圈故障漏检成正常,和外圈故障被错分成内圈故障,在工程上的代价完全不同——前者是漏报,会造成设备损坏风险;后者只是类型判断错误,影响检修备件的准备。

from sklearn.metrics import confusion_matrix, classification_report y_pred = model.predict(X[val_idx]) y_pred_class = np.argmax(y_pred, axis=1) y_true_class = np.argmax(y_val, axis=1) print(classification_report(y_true_class, y_pred_class, target_names=['normal', 'inner', 'outer', 'ball'])) print(confusion_matrix(y_true_class, y_pred_class))

classification_report会输出每个类别的精确率和召回率,重点关注“normal”这一行的召回率——它代表正常样本被误报成故障的比例,也就是误报率。现场设备误报率太高会触发频繁停机检查,维护团队很快就会失去对诊断系统的信任。一般要求正常样本召回率不低于 95%,故障类别的召回率不低于 90%,低于这个水平就得回头查特征或数据。confusion_matrix用于看故障类别之间的混淆模式,如果内圈和外圈互相混淆严重,大概率是特征没有区分度,可以尝试补充包络域特征或调整频带范围。

5. 避坑排查:五个让轴承故障诊断现场翻车的典型原因

5.1 训练验证准确率 99%,换一个工况就崩

现象:模型在公开数据集上测试准确率接近 99%,部署到现场设备后,面对不同负载或转速工况,诊断准确率直接掉到 60% 上下。排查发现没有报错,模型推理正常,但输出结果明显不对。

原因:训练集和验证集被随机切分,同一段信号的相邻样本同时出现在两侧。由于相邻样本高度相似,模型实际上记住了样本的时序模式,而不是学习到故障的物理特征。换到独立工况后,那些时序模式不复存在,模型瞬间失灵。这个问题在使用了高重叠率(75% 以上)切片时尤其严重。

解决:严格按工况组切分训练集和验证集。把同一次采集、同一转速、同一负载下的所有样本绑定为一个组,用GroupShuffleSplit切分;最终评估用“留一工况”法,确保每个工况都当过验证集。同时降低切片重叠率到 50%,减少样本间的近亲程度。改完后准确率通常会下降几个百分点,这才是真实水平的反映——不要觉得数字变低了就是模型变差了,那是数据泄漏被堵住了。

5.2 模型学到的不是故障,而是转速

现象:训练时验证集表现不错,但把所有样本按转速分组统计后发现,高转速样本的预测几乎全偏向某一种故障,低转速样本偏向另一种故障。即使同一类型的故障,不同转速下的预测结果也大相径庭。

原因:振动信号的幅度与时域特征(RMS、峰值等)和转速直接相关。转速升高,振动能量整体上升,RMS 变大;如果训练集里高转速工况下恰好全是内圈故障样本,低转速下全是外圈故障样本,模型就会把“转速高”当成“内圈故障”的充分条件。这类特征工程里典型的隐含变量问题,特征是工况的代理变量,而不是故障的代理变量。

解决:特征层面,把 RMS、峰值等绝对量值归一化,转成与转频无关的相对指标,比如各频段能量占比、RMS 与总能量的比值、峭度这类无量纲指标保留,有量纲指标全部按工况分段统计后做 Z-score 标准化。数据层面,确保每个故障类型都在多个转速负载下出现,让模型无法用工况区分故障。最后用特征重要性检查——如果特征重要性最高的前三个都是对转速敏感的量值特征,就要警惕上述问题。

5.3 包络谱里看不到故障特征频率

现象:跑完包络分析,频谱图上只有一片平坦噪声,或者峰值频率和理论故障特征频率差得很远。主轴转动明显异常,但诊断算法告诉你是正常的。

原因:带通滤波的频率范围设错了。轴承的共振频带随结构变化,同一型轴承装在泵上和装在电机上,共振频带都可能不同。用固定的 2000 到 5000 Hz 频带去处理所有数据,在部分结构上直接滤掉了冲击能量。另一个常见原因是滤波范围太窄,把故障特征频率的低次谐波全部滤掉了。

解决:做一次频带扫描。把带通范围从 500 Hz 开始,以 500 Hz 为步长向上滑动,每个频带都计算包络谱峰值频率和理论故障频率的偏差,偏差最小时对应的频带就是当前设备的最佳共振频带。这个扫描过程用脚本自动化,每次换设备重新扫描一次,不要复用旧参数。扫描代码不复杂,核心就是循环调用 3.2 节里的特征提取函数,比较输出的envelope_peak_freq是否接近理论值。

5.4 样本长度不够,低速轴承诊断失效

现象:低速重载设备的轴承故障诊断准确率始终上不去,更换模型结构也没用。看原始波形,冲击特征隐约存在,但算法就是提取不出来。

原因:低速轴承一转的时间长,比如转频 5 Hz,一圈需要 0.2 秒。采样率 12 kHz 下一整圈是 2400 点,如果样本长度还是 2048 点,连一圈都覆盖不了,故障冲击特征在样本内出现的概率不稳定——有时这段样本里有一个冲击,有时一个都没有。模型学到的是“有没有冲击”的随机性,而不是稳定的周期性模式。

解决:样本长度按转频计算,至少覆盖 2 到 3 圈。低速轴承的样本长度要加到 8192 到 16384 点,卷积核相应增大或增大步长。如果训练样本数量因此减少,可以适当增加重叠率到 75%,弥补样本数量的不足。记住一个规律:先保证每段样本至少包含 2 圈完整周期,再谈其他参数优化。

5.5 换了采集设备性能就掉,数值精度不是玄学

现象:同一套模型,用实验室采集卡采集的数据训练,部署到现场便携式采集仪上,诊断准确率下降明显,而且错误样本集中在某几类故障。两次采集用的是同一型号传感器,采样率设置也相同。

原因:不同采集设备的模数转换精度、输入量程、抗混叠滤波器截止频率不同。实验室采集卡常配置 24 位 ADC 和宽输入量程,现场采集仪可能用 16 位 ADC,信号量化噪声更大。如果传感器的灵敏度系数不同、单位不同(如 mV/g 与 mV/(m/s²)),特征值全部偏移,模型投票边界被打乱。

解决:部署前对采集链路做一次标定。用同一振动源同时接入新旧采集设备,对比波形幅度和频谱分布,标定增益差。模型训练时对输入信号做最大最小值归一化,而不是只做标准化——这样能大幅降低采集设备量程差异的影响。如果两套系统的采样率不同,训练前将信号重采样到统一采样率,千万不要直接输入不同时间间隔的数据。

6. 边缘部署前的验证:用一次全流程回放确认模型真实可用

模型训练完成、指标达标,并不代表可以部署。上边缘设备之前,我习惯做一次“全流程回放验证”:把验证集里的原始信号按照现场设备的真实流程走一遍——从采集链路的量程设置、信号切片的代码逻辑、特征提取或推理的前处理,到最终输出分类结果,每一步都用目标设备上的真实代码执行,而不是用训练时的 Python 脚本。这个习惯帮我挡下过好几次部署事故,最典型的一次是训练脚本里用了np.float64,而边缘设备的推理框架只支持float32,数值精度下降后,原本正确的样本有 3% 被误判。后来我在训练阶段就把所有输入统一转成float32,提前模拟推理环境。

import numpy as np import time def deployment_replay(model, raw_signal, fs, sample_len=2048): # 模拟边缘设备真实处理流程:float32 + 固定长度切片 raw_signal = raw_signal.astype(np.float32) n_samples = (len(raw_signal) - sample_len) // (sample_len // 2) + 1 predictions = [] for i in range(n_samples): start = i * (sample_len // 2) segment = raw_signal[start:start + sample_len].reshape(1, sample_len, 1) start_time = time.time() proba = model.predict(segment, verbose=0) elapsed = time.time() - start_time predictions.append((np.argmax(proba), elapsed, float(np.max(proba)))) return predictions predictions = deployment_replay(model, raw_test_signal, fs=12000, sample_len=2048)

这段回放代码有三个关键点。第一,astype(np.float32)强制模拟边缘设备的数值环境,发现精度问题可以在训练阶段就修正;第二,切片步长与训练时保持一致,验证集用 50% 重叠,回放也用 50% 重叠,现场推理的切片逻辑必须和训练时严格一致,否则模型看到的输入分布会偏移;第三,记录每段样本的推理耗时elapsed,如果耗时超过设备的控制周期(比如 PLC 需要 10 毫秒内返回结果),就必须换轻量模型或走量化。

做完回放后,还要统计输出结果中的最大置信度分布。如果大量样本的置信度集中在 0.5 到 0.7 之间,说明模型对现场信号的整体信心不足,哪怕分类结果碰巧对了,也不稳定——这时需要回看训练数据和现场信号的分布差异,而不是强行部署加大阈值。阈值设置上,一般把最低置信度阈值定在 0.85 以上,低于阈值的判为“不确定”交给人工复核,比硬性输出一个可能错的类别更实用。

这套流程走完,才算一个诊断模型真正达到可部署状态。我自己前两年的做法比较粗糙——训练完看两眼测试报告就直接上设备,翻过几次车以后,现在每次训练完都要先做一遍回放再谈部署。这已经成了固定动作,虽然多花半天时间,但换来的是现场少跑好几趟。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询