RUL寿命预测从零讲起

第零课:RUL 是什么?------生活中的直觉

生活中的「还能用多久」

| 场景 | 问题 | 你已经在做的「预测」 |
| 手机电池 | 还能撑多久? | 看电量百分比、充电次数,心里有数 |
| 汽车轮胎 | 还能跑多少公里? | 看磨损、胎压、使用里程 |
| 打印机墨盒 | 还能打多少页? | 看剩余墨水、打印量 |

电梯钢丝绳 还能用多久才需更换? 看磨损、裂纹、使用次数

RUL(Remaining Useful Life)就是在回答:从【现在】到【失效】还有多长时间(或多少次循环)。

三类维护策略

|-------------------|---------------------------|
| 故障后维护(Reactive) | 坏了再修,成本高、停机风险大 |
| 定期维护(Preventive) | 固定周期更换,可能换得太早浪费、或太晚已坏 |
| 预测性维护(Predictive) | 根据状态预测「还能撑多久」,在最佳时机安排维护 ✓ |

RUL 是预测性维护的核心:告诉你【大概还能用X小时】,你就可以提前排检修、备件、不停产。


第一课:RUL 的数学定义与问题形式

1.1 时间线理解

复制代码
时间轴:  [安装/大修] ──────── t_current ──────── [失效]
                          ↑
                    "现在"这个时刻
                    
RUL = t_failure - t_current  (剩余到失效的时间)
  • t_current:当前时刻(或当前采样周期)

  • t_failure:失效时刻(设备不能继续安全运行的时刻)

  • RUL:从当前到失效的剩余时间(小时、天、或采样周期数)

1.2 退化 vs 故障

概念 含义 例子
退化 性能/健康度随时间逐渐变差 轴承磨损越来越严重、振动变大、温度升高
故障 已不能正常工作的状态 轴承卡死、断裂、严重异响
RUL 预测 在退化过程中预测「距离故障还有多久」 根据当前振动/温度曲线,估计还能运行 X 小时

关键是:我们需要在「还没坏」的时候,根据当前状态预测「什么时候会坏」

1.3 RUL 的表示方式

方式 说明 例子
直接 RUL 剩余小时/天 RUL = 45 小时
健康指数 HI 0--100% 健康度 HI = 62%
分段 RUL 粗分类 0--7天 / 7--30天 / 30天以上

选用建议:

场景 更推荐
有 run-to-failure 数据,需精确排程 直接 RUL
无完整失效数据,或主要做健康监控 健康指数 HI
快速上线、资源有限、只需粗略分级 分段 RUL

实际落地时可以组合使用:例如模型输出「直接 RUL」,再映射成 HI 用于仪表盘展示,同时用分段 RUL 做告警优先级。


第二课:超简单示例------手机电池「健康度」

2.1 不用 AI 也能做「预测」

手机电池的「健康度」本质就是一种简化的 RUL

复制代码
健康度 = f(充电循环次数, 使用时间, 温度历史)
       ≈ 初始容量 × 衰减曲线(循环次数)
  • 输入:充电次数、使用时长、温度等

  • 输出:健康度百分比(相当于归一化的「剩余寿命」)

很多手机用经验公式就能算,不需要深度学习。

2.2 退化曲线的直觉

复制代码
健康度/性能
  100% │●
       │ ●
       │  ●
       │   ●●
       │     ●●●
       │        ●●●●
       │            ●●●●●  ← 接近失效
   0%  └──────────────────────────→ 时间/循环次数
       安装    正常期    退化期    失效
  • 正常期:性能基本稳定,RUL 很大(可截断为常数)

  • 退化期:性能下降,RUL 随时间减小

  • 失效:RUL ≈ 0

2.3 从「健康度」到「RUL」

若健康度 60%,且已知「从 100% 到 0% 大约需要 500 次循环」:

  • 剩余循环数 ≈ 500 × (60% - 0%) = 300 次

  • 若每次循环约 1 天 → RUL ≈ 300 天(粗略估计)

这已经是一个最简单的 RUL 模型:用健康度线性映射到剩余时间。


第三课:用 Python 做第一次 RUL 预测

3.1 构造「假想」的退化数据

我们先不用真实传感器,用公式生成一条从「健康」到「失效」的曲线:

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 模拟一条轴承退化曲线:振动幅值随时间增加
np.random.seed(42)
n_steps = 200  # 200 个时间步,模拟从安装到失效

# 退化模型:健康时振动低,越接近失效振动越高
t = np.linspace(0, 1, n_steps)
vibration = 0.1 + 0.9 * t**2 + np.random.randn(n_steps) * 0.05  # 振动随 t 增加
vibration = np.maximum(vibration, 0.1)  # 确保非负

# 每个时刻的 RUL = 剩余步数(或剩余时间)
rul = np.arange(n_steps - 1, -1, -1)  # [199, 198, ..., 1, 0]

# 画出来看看
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(vibration, 'b-', label='振动幅值')
plt.xlabel('时间步')
plt.ylabel('振动')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(rul, 'g-', label='RUL (剩余步数)')
plt.xlabel('时间步')
plt.ylabel('RUL')
plt.legend()
plt.tight_layout()
plt.show()

运行结果:

要点

  • 振动越大 → 越接近失效 → RUL 越小

  • 每个时刻我们已知「真实的 RUL」(因为我们是用公式生成的)

3.2 用线性回归预测 RUL

把「振动」当输入,RUL 当输出,用线性回归做第一次预测:

python 复制代码
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error

# 输入:最近 10 步的振动均值(简化版「特征」)
window = 10
X = np.array([vibration[i:i+window].mean() for i in range(n_steps - window)])
y = rul[window:]  # 对应的 RUL

model = LinearRegression()
model.fit(X.reshape(-1, 1), y)
y_pred = model.predict(X.reshape(-1, 1))

print(f"MAE: {mean_absolute_error(y, y_pred):.1f} 步")
# 画预测 vs 真实
plt.figure(figsize=(8, 4))
plt.plot(y, label='真实 RUL', alpha=0.7)
plt.plot(y_pred, label='预测 RUL', alpha=0.7)
plt.legend()
plt.xlabel('样本索引')
plt.show()

运行结果:

这就是最朴素的 RUL 预测:输入是「当前状态」的简单特征,输出是 RUL。


第四课:时序数据与滑窗------RUL 的「输入」怎么来

4.1 为什么要用时序?

真实场景中,我们有的不是「一个数」,而是一段时间的传感器读数

python 复制代码
时刻:    t-4   t-3   t-2   t-1   t(现在)
振动:    [0.2, 0.3, 0.35, 0.4, 0.45]  ← 这段序列
温度:    [32,  33,  34,  35,  36]     ← 这段序列
                         ↓
              模型要输出: RUL = 45 小时
  • 单点值信息太少,无法反映趋势

  • 一段序列能反映:是突然恶化,还是缓慢退化

4.2 滑窗构造样本

给定一整条 run-to-failure 轨迹,用滑窗切成多个训练样本:

python 复制代码
def create_sliding_windows(signal, rul, seq_len=50):
    """从整条退化轨迹构造 (x, y_rul) 样本"""
    n = len(signal)
    X, y = [], []
    for i in range(n - seq_len):
        x = signal[i:i+seq_len]      # 输入:一段序列
        target_rul = rul[i+seq_len-1]  # 标签:该段末尾时刻的 RUL
        X.append(x)
        y.append(target_rul)
    return np.array(X), np.array(y)

# 示例
X, y = create_sliding_windows(vibration, rul, seq_len=20)
print(f"样本数: {len(X)}, 输入形状: {X.shape}, 输出形状: {y.shape}")
# 样本数: 180, 输入形状: (180, 20), 输出形状: (180,)

每个样本:输入 = 过去 20 步的振动序列,输出 = 当前时刻的 RUL。

4.3 多变量扩展

设备有多个传感器:振动、温度、电流等。输入就变成:

python 复制代码
x: (batch, seq_len, num_channels)
   例如 (32, 512, 3) = 32 样本 × 512 时间步 × 3 通道(振动X、振动Y、温度)
y_rul: (batch,)

第五课:简单深度学习------LSTM 做 RUL

5.1 为何用深度学习?

  • 线性回归只能看「一个数」,无法捕捉时序模式

  • LSTM 可以学习「振动先升后降再升」这类复杂模式

  • 工业界常用 LSTM、1D-CNN、Transformer 做 RUL

5.2 最简 LSTM RUL 示例(伪代码逻辑)

python 复制代码
# 概念性代码,展示结构
import torch
import torch.nn as nn

class SimpleLSTM_RUL(nn.Module):
    def __init__(self, input_dim=1, hidden=64):
        super().__init__()
        self.lstm = nn.LSTM(input_dim, hidden, batch_first=True)
        self.fc = nn.Linear(hidden, 1)  # 输出一个数:RUL

    def forward(self, x):
        # x: (batch, seq_len, 1)
        out, _ = self.lstm(x)
        last = out[:, -1, :]   # 取最后时间步
        rul = self.fc(last)    # (batch, 1)
        return rul

训练时:

  • 输入:(batch, seq_len, channels) 的振动/温度序列

  • 标签:每段对应的 RUL

  • 损失:MSE 或 Smooth L1

相关推荐
梦想的旅途22 小时前
企微智能知识库:AI赋能私域流量
人工智能·自动化·企业微信
JavaPub-rodert2 小时前
Codex是什么?和ChatGPT有什么区别
人工智能·chatgpt·codex
链巨人2 小时前
理解L-平滑 (L-smoothness)和\mu-强凸 (\mu-strong convexity)并以此假设来证明梯度下降方法的收敛性
人工智能·机器学习
薛定猫AI2 小时前
【技术干货】Open Claw 最新重大更新:插件生态、上下文控制与自托管 AI 助手的工程实践
人工智能
俊哥V2 小时前
每日 AI 研究简报 · 2026-03-24
人工智能
2501_918126912 小时前
学习python所有用来写ai的语句
人工智能·python·学习
红色石头本尊2 小时前
2-使用LLM链和Prompt模板
人工智能
红色石头本尊2 小时前
1-认识langchain.js
人工智能
NAGNIP2 小时前
面试官:你在训模型的时候经常使用的学习率策略有哪些?
人工智能