基于BP神经网络的滚动轴承剩余寿命预测方法研究 📅 发布时间:2026/9/19 21:11:19 👁 浏览次数: 简介一份发表于《海军航空工程学院学报》的学术论文PDF面向故障诊断、健康管理与数据建模方向的工程师与研究者系统讲解基于神经网络的轴承故障预测方法。论文从传统修复性与预防性维修的局限切入对比基于失效物理与数据驱动两类预测模型并重点围绕BP神经网络展开详细阐述神经元结构、正向传播与误差反向传播算法结合轴承全寿命监测数据完成特征提取与剩余寿命评估实验验证。资源为单个PDF文件大小约273KB已有202人浏览学习。对于希望快速掌握神经网络在轴承剩余寿命预测中的应用原理、理解BP算法建模与验证流程的读者这份资料提供了理论推导与实验设计兼备的浓缩参考。1. 轴承故障预测为什么要选 BP 神经网络这条数据驱动路线滚动轴承一旦在高速运转中失效轻则产线停机重则引发安全事故。传统的修复性维修是坏了再换预防性维修则是按固定周期换件看似稳妥但周期定短了浪费寿命定长了又可能扛不住突发失效。真正的出路是把“定期保养”改成“按健康状态保养”也就是视情维修。视情维修的核心是一个量化指标——剩余使用寿命RUL而轴承振动信号里恰好埋着衰退趋势。问题在于振动数据高度非线性、强波动物理建模几乎推不出一个通用的失效方程。所以这两年工业界的共识是走数据驱动让神经网络直接从监测数据里学出“健康状态→RUL”的映射。这篇论文的思路正是如此用 BP 神经网络对轴承全寿命振动数据做特征提取和回归建模在实验数据上验证了后期预测精度。对做设备健康管理PHM的人来说这是一个结构不大但流程完整的基线方案尤其适合入门故障预测时先跑通特征工程、训练、滤波这一整条链路。2. BP 神经网络结构与前向/反向传播推导2.1 BP 神经元与前馈连接方式BP 神经网络是一种多层前馈网络信号从输入层逐层传到输出层不跨层连接。论文中给出的神经元结构很典型上一层的输出作为当前神经元的输入每个输入乘一个权重累加后加上阈值并且经过传递函数得到该神经元输出。公式上神经元的净输入是$$s_j \sum_{i1}^{n} w_{ji} x_i \theta_j W_j^T X_j$$其中 $X_j [x_1, x_2, \cdots, x_n, 1]^T$$W_j [w_{j1}, w_{j2}, \cdots, w_{jn}, \theta_j]^T$。这里的阈值 $\theta_j$ 被统一写成 $w_{j0}$ 且对应输入 $x_01$好处是梯度推导时阈值可以和权重一样处理不用单独写一套规则。传递函数 $f(\cdot)$ 在论文里隐含层常用 Sigmoid输出层若做回归则常用线性函数。Sigmoid 的导数是 $\sigma(s) \sigma(s)(1 - \sigma(s))$计算很方便这也是 BP 算法能高效收敛的原因之一。2.2 正向传播与误差函数假设输入层有 $n$ 个节点隐含层有 $q$ 个节点输出层有 $m$ 个节点。隐含层输出为$$z_j f\left(\sum_{i1}^{n} v_{ji} x_i\right)$$输出层输出为$$y_k g\left(\sum_{j1}^{q} w_{kj} z_j\right)$$其中 $v_{ji}$ 是输入层到隐含层的权重$w_{kj}$ 是隐含层到输出层的权重。训练样本是 ${(x^{(p)}, y^{(p)})}_{p1}^{P}$第 $p$ 个样本的期望输出是 $t^{(p)}$实际输出是 $y^{(p)}$。定义全局误差为$$E \frac{1}{2} \sum_{p1}^{P} \sum_{k1}^{m} \left(t_k^{(p)} - y_k^{(p)}\right)^2$$前面的 $\frac{1}{2}$ 是为了求导后消掉平方项的系数不影响最优点。BP 的目标就是找到一组权重使 $E$ 最小。2.3 反向传播权重更新推导反向传播的核心是链式求导。以隐含层到输出层的权重 $w_{kj}$ 为例误差对 $w_{kj}$ 的偏导为$$\frac{\partial E}{\partial w_{kj}} \frac{\partial E}{\partial y_k} \cdot \frac{\partial y_k}{\partial s_k} \cdot \frac{\partial s_k}{\partial w_{kj}}$$三项分别计算$\frac{\partial E}{\partial y_k} -(t_k - y_k)$$\frac{\partial y_k}{\partial s_k} g(s_k)$$\frac{\partial s_k}{\partial w_{kj}} z_j$。所以$$\Delta w_{kj} \eta \sum_{p} (t_k - y_k) g(s_k) z_j$$输入层到隐含层的权重 $v_{ji}$ 需要把误差继续往回传$$\Delta v_{ji} \eta \sum_{p} \left[ \sum_{k} (t_k - y_k) g(s_k) w_{kj} \right] f(s_j) x_i$$论文里省略了中间步骤直接给出了最终迭代式。实操时不需要手写这些链式求导但理解这个流程对调学习率、诊断梯度消失很有帮助。比如隐含层梯度里乘了 $f(s_j)$Sigmoid 饱和区导数趋近 0这就是为什么权重初始化不能太大、数据要归一化的理论根源。3. 轴承振动特征提取时域、频域与小波低频分量的组合3.1 浴盆曲线与特征选择依据轴承从健康到失效故障发生率呈浴盆曲线形态分为早期失效期、偶然失效期和耗散失效期。故障预测关注的是偶然失效期和耗散失效期因为这两个阶段轴承开始出现可观测的退化趋势。论文的思路是提取的特征必须和浴盆曲线的后两段形状吻合才能真实反映衰退过程。如果提取的均值、方差曲线一直平坦直到失效前才突变那对剩余寿命预测几乎没有帮助。从全寿命振动数据里论文选了 8 个特征序号特征描述类型1一个振动周期的均值时域2一个振动周期的方差时域3一个振动周期数据傅里叶变换的功率谱频域4小波分解后的低频分量 A1时频5小波分解后的低频分量 A2时频6小波分解后的低频分量 A3时频7小波分解后的低频分量 A4时频8小波分解后的低频分量 A5时频为什么选这 8 个均值能反映振动能量的缓慢趋势方差能体现波动程度的加剧功率谱则刻画频域能量的分布变化。小波低频分量保留的是信号的大致轮廓滤掉了高频噪声和轴承整体的磨损趋势更相关比直接拿原始振动幅值稳定得多。3.2 特征提取代码实现常见做法是先把振动信号按一个转轴的旋转周期切段比如每段 2560 个采样点然后对每段计算特征。代码用 Python 写import numpy as np from scipy.fft import rfft import pywt def extract_features(signal, fs): 输入一段轴承振动信号shape(N,) 输出8维特征向量 # 1. 均值 mean_val np.mean(signal) # 2. 方差 var_val np.var(signal) # 3. 傅里叶功率谱取正频部分并计算能量 freq_spec np.abs(rfft(signal)) ** 2 power_spectrum np.mean(freq_spec[1:]) # 去掉直流分量取平均功率 # 4-8. 小波分解取5层低频分量 coeffs pywt.wavedec(signal, db4, level5) low_freq_components coeffs[1:] # 各层近似系数实际是cA1~cA5 # 对各层低频系数求均方根作为特征值 low_freq_features [np.sqrt(np.mean(c**2)) for c in low_freq_components] feature_vector np.array([mean_val, var_val, power_spectrum] low_freq_features) return feature_vector这段代码里rfft返回正频率部分去掉直流后取均值得到的是信号在频域上的平均能量。小波分解用db4小波分解 5 层coeffs[1:]是各层逼近系数。对每一层系数取均方根值是为了把不同长度系数压缩成一个标量。注意故障预测的特征必须按时间序列排列每个时间节点算一次最终得到一个(时间节点数, 8)的特征矩阵。3.3 中值滤波与归一化处理提取完特征后两类处理是必须的。第一是中值滤波目的是去掉振动瞬时冲击造成的毛刺让特征曲线更平滑。中值滤波的窗口大小取 35 个时间节点比较合适窗口太小滤波不明显太大会抹掉真实的衰退突变。第二是归一化原始特征量纲差异很大均值可能只有 0.5功率谱可能到几千如果不归一化BP 神经网络训练时大数值特征会主导权重更新导致小数值特征失效。论文里的归一化函数没有给具体形式一般用 min-max 归一化$$x_{\text{norm}} \frac{x - x_{\min}}{x_{\max} - x_{\min}}$$注意归一化参数必须只用训练集的 min/max 计算不能混入测试集否则会引入未来数据的信息造成评估结果虚高。这是故障预测里最常见的泄露错误之一。下面是归一化和中值滤波的示例代码from scipy.signal import medfilt def preprocess_features(feature_matrix_train, feature_matrix_test): 特征矩阵shape: (n_samples, n_features) 返回训练和测试的归一化特征参数仅从训练集获取 n_features feature_matrix_train.shape[1] train_norm np.zeros_like(feature_matrix_train) test_norm np.zeros_like(feature_matrix_test) for i in range(n_features): # 中值滤波窗口大小5 train_col medfilt(feature_matrix_train[:, i], kernel_size5) test_col medfilt(feature_matrix_test[:, i], kernel_size5) # 从训练集取min/max fmin train_col.min() fmax train_col.max() train_norm[:, i] (train_col - fmin) / (fmax - fmin 1e-10) test_norm[:, i] (test_col - fmin) / (fmax - fmin 1e-10) return train_norm, test_norm这里medfilt是 scipy 提供的一维中值滤波kernel_size5表示取前后共 5 个点的中位数。分母加上1e-10防止除零。测试集归一化用的是训练集的fmin和fmax这一点在工程上必须严格执行。4. 基于 BP 神经网络的剩余寿命预测实现4.1 训练样本构造与网络结构参数训练样本的构造方式是设 $x_i$ 为第 $i$ 个时间节点的特征向量$r_i$ 为该节点对应的真实剩余寿命单位是振动监测周期的个数。把 ${(x_i, r_i)}$ 输入 BP 神经网络训练。这样网络学习到的映射是“当前特征→还能活多久”而不是“特征→是否故障”所以输出层的激活函数用线性函数也就是不加任何压缩。网络结构上输入层节点数固定为 8输出层节点数为 1关键调的是隐含层节点数。按论文实验的规模隐含层取 10 个节点、单隐层就够用。节点数太少拟合能力不足预测曲线会过于平滑节点数太多容易过拟合在训练集上误差极小、测试集上误差反弹。一个参考经验样本量级隐含层节点数建议隐含层层数10005101100050001020125000205024.2 训练过程与学习率设置权重优化采用梯度下降。论文推导出的更新公式在实现里就体现为一句代码weights - learning_rate * gradient。学习率 $\eta$ 取 0.01 比较保险迭代次数设 1000误差阈值设 0.0001。如果学习率太大权重会来回震荡无法收敛太小则收敛慢。下面用 Python 和 scikit-learn 的MLPRegressor给出一个可跑的示例from sklearn.neural_network import MLPRegressor from sklearn.metrics import mean_absolute_error # X_train, y_train 已经归一化 # y_train 是剩余寿命也可以归一化到[0,1]帮助收敛 model MLPRegressor( hidden_layer_sizes(10,), # 单隐层10个节点 activationlogistic, # Sigmoid solversgd, # 随机梯度下降 learning_rate_init0.01, max_iter1000, tol1e-4, random_state42 ) model.fit(X_train, y_train) # 预测训练集并查看误差 y_pred_train model.predict(X_train) print(f训练集平均绝对误差: {mean_absolute_error(y_train, y_pred_train):.4f})hidden_layer_sizes(10,)表示单隐层 10 节点。activationlogistic对应论文中的 Sigmoid。solversgd就是 BP 梯度下降如果数据量不大也可以用adam更快收敛但论文里描述的是标准 BP 过程这里保持一致。tol1e-4是迭代停止的误差阈值。注意 y 如果也做了归一化预测后要反向还原才能得到真实寿命周期的数值。4.3 剩余寿命粗估计与滑动窗口滤波训练完成后对待估样本的每个时间节点输入特征 $x_i$网络输出一个剩余寿命粗估计 $\hat{r}_i$。由于振动监测数据本身是序贯的相邻节点的真实剩余寿命应该接近所以论文对粗估计做了进一步滤波对当前节点取前后共 n 个节点的估计值求平均。论文实验里 n 取 3公式是$$\widetilde{r}i \frac{1}{3} \sum{ki-1}^{i1} \hat{r}_k$$这种滑动平均能明显抑制单点突变。实现时要注意边界处理前两个和后两个节点不足 3 个邻居常见做法是只对有效邻居求平均或者对边界节点直接沿用粗估计。代码示例def sliding_average_filter(r_est, window3): half window // 2 n len(r_est) r_smooth np.zeros_like(r_est) for i in range(n): left max(0, i - half) right min(n - 1, i half) r_smooth[i] np.mean(r_est[left:right 1]) return r_smooth窗口大小 n3 是论文里的值实际使用时可以尝试 n5 或 n7观察曲线平滑度和响应速度。窗口越大曲线越平滑但对真实的寿命突降会反应迟钝。如果预测目标是给出“还能工作多少分钟”用 n5 也行但要在评估指标里加入对突变时刻的惩罚不然单纯追求平滑会把失效点提前或延后。5. 实验验证与工程化排错从两套数据到可靠部署5.1 训练集与测试集划分及结果评估论文用了两组轴承全寿命数据一组做训练集一组做测试集。这种“用某台轴承的完整寿命数据训练再预测另一台轴承”的设置非常接近真实场景因为实际部署时不可能为每一台轴承都先跑到失效再训练。评估方式是绘制测试集的剩余寿命估计值与真实值随时间的对比曲线论文给出的结果表明模型整体预测趋势接近真实值且运行后期节点 t 800 后剩余寿命估计准确率显著提高。这个现象很符合 BP 神经网络的特性——退化后期特征变化明显网络更容易区分不同的寿命阶段。为了量化评估建议在测试集上计算平均绝对误差和误差随寿命区间分布。比如寿命区间平均绝对误差周期相对误差全寿命期18.612.3%后期t8006.26.8%后期误差更小是因为轴承进入耗散失效期后振动能量和频域分量都会快速上升特征和剩余寿命的线性关系更强网络容易把握。而早期退化缓慢特征变化小预测偏差大也正常。工程上如果必须提高早期精度可以考虑把早期样本加权或者改用时序模型比如 LSTM、TCN不过这些模型需要的数据量和训练成本会明显增加。5.2 六个容易踩的坑与规避方法第一归一化泄露。前面提过测试集的 min/max 必须来自训练集。很多人直接对整个数据集做归一化再切分导致测试信息提前进入训练验证结果虚高。第二特征对齐错误。剩余寿命是按“节点到失效点的周期数”计算的如果节点定义用的是“等间隔时间”而不是“等转数”轴承转速波动时特征对应关系就会错位。最好按主轴转数或固定角度采样。第三对粗估计直接取整输出。网络输出是连续值而真实寿命是整数周期。不要在模型输出处直接 round而是保留浮点数做后续滤波最后再按业务需要向上取整为“安全寿命”。第四过度依赖滑动平均。滤波窗口 n3 在论文实验里表现不错但换数据后要先做敏感性实验。用一个简单脚本扫描 n1,3,5,7,9观察平均绝对误差的变化选误差最小的窗口而不是直接照搬。第五忽略失效阶段识别。浴盆曲线提示轴承从健康到失效要经历两个阶段如果设备长期处于早期平稳期特征几乎不变此时网络给出的预测可能长期停留在一个常数附近产生“估计值偏保守”的错觉。建议结合趋势检测当特征斜率超过阈值时才激活寿命预测否则只输出“健康”。第六训练样本太少导致的偏差。论文里只有两组数据一组训练一组测试本质上是单样本验证泛化性能没有被充分评估。实操中至少要准备 10 组以上全寿命数据用留一法或 K 折交叉验证才能比较可信地估计模型在其它轴承上的误差。最后一个可用技巧把 BP 网络的输出残差分析一下。如果残差随时间的增大而增大说明模型对后期的预测方差变大此时可以在后期给滤波窗口加权比如靠近失效点使用更短的窗口让预测值更快跟随真实衰变。反过来如果残差集中在早期则说明特征提取不够敏感优先检查小波低频分量是否覆盖了早期微弱磨损的频率带而不是急于调网络结构。把这条残差分析流程固定为每次实验后的例行检查比盲目调参要高效得多。本文还有配套的精品资源点击获取