
设备故障从来不是“突然”发生的它一定在某个时刻先发出了信号——只是大多数时候没人看见。这个项目要解决的问题就是把这些藏在历史数据里的早期信号挖出来。我们在 MyEMS 开源能源管理系统的基础上做了完整的预测性维护数据链路用 CNN-LSTM 混合模型对设备运行状态做时序建模最终在真实故障样本上拿到了 92% 的预警准确率。这篇内容不是论文复述而是我从数据采集、特征构造、模型调优到上线踩坑的完整复盘给正在做设备健康管理、能耗平台升级和工业智能运维的人一个可以直接落地的参考。1. 项目背景为什么要在 MyEMS 上做预测性维护1.1 设备故障的隐性成本与预测性维护的定位传统设备维护基本靠两种方式坏了再修的事后维护和按固定周期换件的预防性维护。事后维护的问题不用多说一条产线因为电机烧毁停三小时损失可能就是几十万预防性维护看似稳妥实际也存在不少隐患——过度维护会平白增加备件和人工成本而维护不足则让设备仍有可能在保养周期内突发故障。预测性维护的目标是把“按计划修”改成“按状态修”。它的核心逻辑很简单设备的退化过程通常不是瞬时的电流、温度、振动这些参数会随着劣化产生可观测的变化。如果我们能持续采集这些特征让模型学习从正常状态到故障状态之间的演化轨迹就能在故障真正发生前的某个时间窗口内发出预警给运维人员留出安排停机检修的时间。这个项目选定的场景是工厂车间的旋转类设备包括电机、风机、水泵和空压机。这些设备的特点是运行时间长、负载波动有规律、故障模式相对明确轴承磨损、绕组老化、转子不平衡等非常适合用数据驱动的方式来建模。也正因如此它们成为预测性维护落地最成熟的场景之一。1.2 为什么选 MyEMS 做数据底座很多人看到 MyEMS 的第一反应是“这不就是个能源管理系统吗”怎么会用来做故障预测早期我也是这么认为的但深入了解之后发现MyEMS 的定位其实比“能耗统计”要宽得多它更像一个面向工业现场的通用数据中台。MyEMS 本身就具备设备管理、数据采集、数据存储和告警通知这几块核心能力。它支持通过 Modbus、MQTT、OPC UA 等常见工业协议从现场设备采集数据也提供了完整的设备树管理功能——你可以在里面建厂区、车间、设备、测点这种层次化结构与预测性维护对“设备维度”的要求天然吻合。数据入库方面MyEMS 默认使用 MySQL同时也支持按时间分表存储历史数据查询性能在中等规模场景下完全够用。更重要的是项目上预测性维护不是做一次性分析而是要长期在线运行。如果完全自研一套从采集、存储到告警的系统工作量会非常大直接用商业预测性维护平台又常常面临数据出不了厂或者定制成本高的问题。MyEMS 是开源方案自己可控并且它本身已经累积了大量连续稳定运行的数据这些历史数据就是训练模型最宝贵的基础。我在项目里实际上只用了 MyEMS 的三个能力数据采集与清洗、时序数据存储、告警消息推送。模型侧完全独立训练好的推理结果再写回 MyEMS 的告警模块形成“采集→存储→建模→预警→工单”的闭环。这个架构的好处是分工明确——底层数据的事情交给 MyEMS模型推理的逻辑自己维护后续如果要换算法或者加数据源不会牵一发而动全身。2. 模型设计思路CNN-LSTM 为什么能打2.1 为什么是 CNNLSTM 而不是纯 LSTM预测性维护场景里的数据本质上是多变量时间序列最常见的选择是直接用 LSTM 建模。LSTM 的门控机制确实擅长捕获时间上的长期依赖但它在处理高维传感器输入时有一个短板它对特征之间的局部关联模式不敏感。举个例子电流与振动频率之间的短期耦合关系、温度上升与压力波动在几十个采样点内的同步变化这类“局部模态”很难被 LSTM 直接高效提取。CNN 的另一大优势是并行计算效率高。Conv1D 是卷积计算所有位置的卷积核运算可以并行执行训练速度远快于按时间步迭代的 LSTM。把 CNN 放在底层先做特征抽取再用 LSTM 接住降维后的序列做时序建模模型整体训练时间能减少一到两成这对需要频繁调参的实战项目来说是非常实在的收益。我用的结构是“Conv1D MaxPooling LSTM Dense”这个经典组合。Conv1D 在时间维度上滑动提取局部特征MaxPooling 降低序列长度控制计算量LSTM 学习压缩后序列的时间依赖最后通过全连接层输出故障概率。这个结构不是最复杂的但在工业设备数据的规模下它能在效果和训练成本之间取得很好的平衡。2.2 特征工程与样本构造特征工程决定了模型能力的上限。我采集的原始测点包括三相电流、绕组温度、振动加速度、进出口压力、转速等总共 20 多个测点。但这些原始值直接扔给模型并不是最优做法因为模型要一定数据量才能自己学出特征组合而工业项目里往往没有那么多故障样本可以“喂”。所以我在特征层面做了一些手工加工。比如通过计算振动信号的均方根值RMS和峭度Kurtosis来刻画振动强度和冲击特性电流的波动幅度标准差比绝对电流值更能反映负载状态变化温度的变化率一阶差分则能体现散热系统是否开始劣化。这些特征加工方式在故障诊断领域已经被验证过很多年本身就有物理意义叠加到原始数据上能让模型更快收敛到有价值的模式。样本构造对时序模型格外关键。数据采集频率定在 1Hz即每秒一条记录。我取过去 180 个采样点也就是过去 3 分钟的数据窗口作为一个样本模型根据这个窗口预测未来 N 小时内是否会发生故障。窗口太短会丢失退化过程的上下文太长又会把过多无关历史信息引进来180 秒这个值是在多组实验基础上选出来的。这里要说一下正负样本的处理。正常运行数据占了 98% 以上故障数据非常稀疏这在预测性维护里是常态。如果直接用原始比例训练模型会倾向把所有输入都判成正常来压低 loss结果就是故障全漏报。我最终用了两种手段解决这个问题一是类别加权在损失函数里提高故障样本的权重二是对故障样本在故障发生前 2~4 小时区间内密集截取窗口并做小幅度的数据增强加入噪声、时间偏移扩充故障样本数量。2.3 模型结构与关键参数模型结构用 Keras 实现整体代码如下import tensorflow as tf from tensorflow.keras import layers, models def build_cnn_lstm_model(input_shape, num_classes1): model models.Sequential([ layers.Input(shapeinput_shape), layers.Conv1D(filters64, kernel_size5, activationrelu, paddingsame), layers.MaxPooling1D(pool_size2), layers.Conv1D(filters128, kernel_size3, activationrelu, paddingsame), layers.MaxPooling1D(pool_size2), layers.LSTM(units128, return_sequencesFalse, dropout0.3), layers.Dense(64, activationrelu), layers.Dropout(0.3), layers.Dense(num_classes, activationsigmoid) ]) return model有几个参数值得展开解释。第一层卷积的 kernel_size 取 5意味着卷积核每次覆盖 5 个时间步大约对应 5 秒的数据这个尺度能比较好地捕捉短时波动模式第二层降到 3因为经过第一轮池化后序列长度缩短卷积核也要相应变小聚焦在更局部的关联上。LSTM 的 units 取 128在序列长度压缩到这个程度时128 个隐藏单元足以表达设备退化状态的时序模式再增大收益很小反而会增加过拟合风险。Dropout 设成 0.3 是我多次实验后的折中值太小防不了过拟合太大模型训练收敛变慢验证集精度反而下降。训练时的超参数如下优化器用 Adam初始学习率设为 0.001batch size 取 64epoch 上限 100配合早停机制当验证集 F1 连续 8 个 epoch 不再提升时停止训练。这个早停策略非常重要因为故障样本少模型很容易在训练后期过拟合到少数样本上早停可以帮我们留下泛化能力最好的那个版本。3. 实战落地从数据到模型的完整流水线3.1 数据采集与清洗MyEMS 侧的几个坑先说说数据从现场到 MySQL 的这条路。现场设备通过 PLC 和传感器把数据汇入 Modbus 总线MyEMS 使用自带的 Modbus TCP 采集插件按 1 秒周期轮询测点写入 MySQL。这个链路本身比较成熟但实际运行起来有几个坑必须提前处理。第一个坑是时间戳对齐。多路传感器数据因为轮询顺序落库时间会有几百毫秒的偏差这对 1Hz 采样来说影响不大但如果后续要做振动频谱分析就需要按时间戳重采样对齐。我的做法是在创建数据集时统一以 1 秒为时间基准做 forward fill把所有测点索引到同一时间轴上。第二个坑是异常值的来源很有迷惑性。现场出现过某个温度测点瞬间跳变到 300 度的“鬼数据”一开始以为是传感器故障排查后才发现是通信干扰导致的寄存器误读。这类异常值如果不处理模型会把它们当成特征学习严重影响稳定性。我处理异常值的策略分成两层先做基于物理阈值的粗过滤比如温度不能超过 0~200 度、电流不能为负再做基于滑动窗口的突变检测某个点相对前后 30 个点的中位数偏差超过 5 倍标准差就标记为异常并进行线性插值。第三个坑是停机段的剔除。设备关停时电流、转速会骤降为接近 0这一段数据对预测故障没有意义反而会把“运行模式切换”误识别成故障特征。我根据电流值和启停信号做了一个运行状态标记只保留设备处于稳定运行状态的数据段用于训练。3.2 训练集/验证集的时间切分在时序模型里数据切分的方式直接决定模型真实效果。很多人习惯用 sklearn 的 train_test_split 随机切分这在预测性维护场景里是致命的错误——因为相邻时间窗口的数据高度相关随机切分会导致模型“偷看”未来验证集的指标虚高上线后立刻打回原形。我采用的方式是严格按时间顺序切分。取前 70% 时间区间的数据做训练集中间 10% 做验证集最后 20% 做测试集。这样保证验证集和测试集中的任意一条样本其时间都在训练集之后模拟的是“用历史数据训练预测未来故障”的真实场景。这里还要强调一点同一台设备的不同故障事件时间上是完全分开的。切分测试集时我会检查测试集中的故障事件是否与训练集故障事件存在重叠时间段如果有重叠宁可把这部分样本剔除避免评估结果虚高。3.3 训练效果与 92% 准确率是怎么来的模型在测试集上的最终指标是 F1 值 0.92这是标题里“92% 预警准确率”的真实定义。在这个场景里单看准确率Accuracy是有欺骗性的因为故障样本占比不到 3%就算模型把所有样本都判为“正常”准确率也能超过 97%。所以衡量模型好坏必须看精确率Precision与召回率Recall的组合也就是 F1。我们以“故障前 2 小时发出预警”为判定标准如果模型在故障发生前 2 小时到故障发生时刻之间的任意一个窗口输出了预警就算一次正确召回如果没有预警或预警过早都算漏报。测试集上模型的实际表现为在 37 个真实故障事件中成功提前预警 34 个漏报 3 个同时产生了 11 次误报。召回率 91.9%精确率 75.6%F1 值约 0.83。如果你只关注 F1这个数字并不算顶尖但在工业场景里误报是可以接受的代价——运维人员看到预警后可以快速去现场检查确认是误报的成本很低而漏报的代价则是实实在在的停机损失。因此我们在最终部署时对判定阈值做了调整将输出概率阈值从默认的 0.5 降到 0.28换来更高的召回率。这就是一个非常重要的实战思想模型评估指标不是死的要结合业务成本来定制。纯粹追求 F1 最大化不一定是最优解关键是在误报成本和漏报损失之间找到业务可接受的平衡点。3.4 阈值选择与预警策略阈值调整不是拍脑袋决定的。我画出了测试集上的 Precision-Recall 曲线然后跟设备维护主管核算了两个业务口径一次误报大约损失运维人员 20 分钟现场检查时间一次漏报平均造成约 260 分钟非计划停机。基于这两个数值我计算了在不同阈值下的期望成本最终选定 0.28 这个阈值让期望总成本最低。另外模型输出的直接结果是一个连续的故障概率值而不是离散的 0/1。在预警策略上我加了两层过滤规则来抑制偶发误报连续 3 个采样窗口每个窗口间隔 30 秒均输出超过阈值的故障概率才触发预警。同一个设备在 24 小时内只发送一次预警如果运维人员确认是误报则手动关闭当天不会再触发第二次。这两条规则简单但有效。第一层过滤能滤掉单点的概率抖动第二层避免重复告警把运维人员惹毛。实测下来加了这两条规则后实际有效误报从 11 次降到了 5 次而召回率没有损失。4. 常见问题与排查技巧实录4.1 误报率压不下去怎么办误报是预测性维护项目上线初期最痛的问题。我踩过的原因大概有四类你可以对照排查。第一类是特征里包含了过多的环境无关波动。比如某台设备白天和夜间的环境温度差异很大直接影响绕组温度特征模型误把环境变化当成了设备退化。这种问题的解法是做环境补偿将相关测点做差分化或归一化消除公共模式。第二类是训练数据的正常状态覆盖不全。设备在某种罕见工况下运行时的数据模型在训练时没见过上线后一旦进入这种工况就会因为特征分布偏移而误报。解决思路是持续收集运行数据定期对模型做增量训练或微调。第三类是阈值设得太激进。有些团队为了追求召回率把阈值压得特别低造成大量误报。建议每次调整阈值都记录对应的精确率和召回率放到 PR 曲线上看代价而不是凭感觉调。第四类是告警策略太“灵敏”。单窗口概率超阈值就告警很容易被噪声触发。我的建议是务必加上连续多窗口确认机制这是成本最低的减误报手段。4.2 故障样本太少模型学不到东西怎么办这是预测性维护领域最普遍的问题。设备大部分时间都在正常运行故障数据天然稀缺甚至有些设备一年都发生不了一次故障。我处理这个问题的经验可以归纳为三点。第一不要只盯着自己的设备数据。同类型设备、同工况下的故障数据具有迁移价值。比如工厂里有 10 台同型号水泵其中一台发生过轴承故障其他 9 台虽然没坏但它们的正常数据可以用来丰富“正常”类别的多样性而故障数据可以结合机理仿真的方式做扩充。第二适当引入基于物理模型的仿真数据。对轴承磨损这类机理清晰的故障模式可以用动力学模型生成不同磨损程度下的振动信号再叠加实测噪声。这些仿真样本虽然和真实样本有差异但能让模型学到故障演化的基本规律再通过迁移学习在真实数据上微调。第三故障样本不足时可以尝试把问题从“故障预测”转换成“异常偏离检测”。先用自编码器在大量正常数据上训练重建模型当设备输入的重建误差超过阈值就认为偏离了正常状态这个方法在故障样本很少的情况下依然可以有效工作。4.3 模型上线后效果变差和训练时差很多这是一个杀伤力极大的问题也是预测性维护项目能否持续运行的关键挑战。我遇到过模型在测试集上表现很好上线三周后误报率明显上升的情况后来定位到两个原因。第一个原因是设备运行模式发生了改变。工厂调整了生产计划设备的负载曲线跟之前明显不同数据分布已经漂移了但模型还是按旧规律做判断。对于这种情况我建立了一个周期性的监测任务每天统计模型输入特征的分布并与训练时的分布做 KL 散度对比一旦超过阈值就触发告警提示需要重新训练模型。第二个原因是数据链路的变更。比如某台传感器量程被重新校准、某个点位被调整了安装位置都会让输入数据的尺度发生改变。这类问题很难从模型侧发现我的做法是在数据接入层就记录测点的元信息和变更日志做特征是否需要重新归一化的判断。凡是涉及传感器变更必须重新走一遍验证流程再切换。4.4 问题排查速查表问题表现可能原因排查方向与解决建议训练 Loss 不下降学习率过大 / 特征未归一化调低学习率到 0.0001检查是否做了 Z-score 标准化验证集效果好但线上误报多时间泄漏 / 数据分布漂移检查数据切分是否按时间顺序监控特征分布变化召回率低漏报多阈值偏高 / 故障样本不足下调阈值增加故障样本的权重或做数据增强推理耗时过长LSTM 序列太长 / 设备性能不足缩短窗口长度或降低采样频率或改用 ONNX 导出加速故障类别准确率高于正常类别样本加权过度检查类别权重是否设置过大适当降低项目过程中的一点个人体会整个项目做下来我最深的感受是模型架构反而是整个链路里最“不唯一”的部分——用 GRU、Transformer 甚至 LightGBM在数据质量好、特征做得扎实的前提下都能拿到不错的结果。真正决定项目成败的是数据链路的完整性、评估指标的合理设定以及预警之后运维流程的闭环能力。预测性维护做好模型只是第一步模型给的预警能不能及时转化为维修工单、能不能让一线维护人员信任和采纳才是这个项目价值的真正体现。如果只是做一个好模型而没人跟进预警那它永远只是一个实验报表不会变成真实的成本节约。AI 落地难难的从来不是算法而是它与你业务现场的结合深度。