基于MyEMS与CNN-LSTM的压缩机故障预警系统实战解析
预测性维护这个概念圈子里聊了很多年真正能在车间里跑起来并且拿到实打实效果的项目其实不多。今年上半年我带着一支小团队做了一个压缩机故障预警项目数据底座用了开源的 MyEMS 平台算法选的是 CNN-LSTM 组合模型最终在独立测试集上把故障预警准确率做到了 92%平均能比故障真正发生提前 3 到 4 个小时发出预警。这篇就来讲讲我们当时为什么这么选型、数据是怎么处理的、模型是怎么训练和部署的以及中间踩过的几个比较深的坑。如果你正准备在工厂里搭一套设备预警系统或者已经在用 MyEMS 想往上做智能分析这篇文章应该对你有点用。1. 项目概述与方案选型1.1 现场痛点为什么需要预测性维护我们接到这个需求的时候客户那边的核心痛点非常直接一台螺杆式空气压缩机是整个压缩空气系统的主力设备一旦停机后端的几条产线都要跟着降速甚至停线。传统的维护模式是什么被动维护加计划维护。被动维护就是坏了再修非计划停机一次的损失用他们的话说半年的维护预算都搭进去了。计划维护做得也不算差每三个月做一次全面保养按厂家手册定期换油、换滤芯、检查皮带但问题也很明显一部分零部件还没到寿命就被强制换掉造成浪费另一部分故障恰恰发生在保养间隔的中间计划维护对此无能为力。预测性维护要解决的就是这个“中间地带”的问题在设备还没有明显故障、但已经出现劣化趋势的时候提前把风险提示出来。它的核心逻辑并不神秘——设备从正常到故障通常会经历一个性能退化过程在振动、温度、电流、压力这些信号里会留下蛛丝马迹。问题是怎么从这些高噪声的信号里把退化趋势“读”出来。传统阈值报警的方式太粗了往往等阈值被突破时设备已经出了大问题真正能提前几小时或者几天发现问题的必须靠模型从多维时序数据里学规律。1.2 数据底座为什么选 MyEMS选 MyEMS 做数据底座主要看重它开源和完整的协议接入能力。MyEMS 本身是一套能源管理系统支持 Modbus、OPC UA、BACnet、DL/T 645 等常见的工业通信协议能对接大量的 PLC、电表、传感器和设备控制器。它自带数据采集器、MySQL 存储、REST API 和 Web 可视化界面也就是说从数据接入、入库到开放接口这一整套基础设施它都给你搭好了我们不需要从零写采集程序也不用自己搭报表和监控面板。当时我们对比过两种路线一种是自己用脚本读 Modbus 数据然后存 InfluxDB另一种就是直接用 MyEMS。前者的灵活度高但采集点位管理、断线补传、历史数据查询这些都要自己造轮子工程量不小。MyEMS 这些能力是现成的而且作为开源软件我们还能改源码这点在项目里有实际意义——后面做告警联动时我们就是直接调用它的 API 往设备监测报表里写告警信息省了不少对接时间。对于中小规模的产线智能化改造MyEMS 这个层级的数据底座已经够用到“冗余”了。1.3 算法选型CNN-LSTM 为什么合适模型选型的过程其实是在几个候选方案里反复比较后才定下来的。最开始我们尝试过 XGBoost树模型在表格数据上表现不错但用在多通道时序信号上有两个问题一是它天然不考虑时间顺序需要人工构造大量滞后特征二是当设备运行工况变化时树的泛化能力明显下降。后来换成纯 LSTM长短期依赖能学了但对局部异常形态的捕捉不够敏感故障前那种短时间内的波形畸变经常被淹没在正常的工况波动里。CNN-LSTM 的组合思路是一个很自然的折中方案。CNN 是一维卷积专门用来在时间窗口内提取局部特征——某个测点在十几分钟内出现的尖峰、毛刺、阶跃变化卷积层都能高效地捕捉到LSTM 再接在 CNN 后面负责学习这些局部特征在更长时间尺度上的演化规律从“局部异常”过渡到“持续劣化”再到“即将故障”。这正好契合设备退化过程的本质早期是细微的局部异常中期形成持续趋势后期快速恶化。除了效果上的考虑CNN-LSTM 还有一个工程上的优势它可以直接吃原始的多通道时间序列特征工程的压力小到了部署阶段调试起来也方便。2. CNN-LSTM 模型结构与数据工程2.1 模型网络结构拆解我先把最终跑通的模型结构放出来后面再解释每个部分的考量。model Sequential([ Conv1D(filters64, kernel_size3, activationrelu, paddingsame, input_shape(256, 9)), BatchNormalization(), MaxPooling1D(pool_size2), Conv1D(filters32, kernel_size3, activationrelu, paddingsame), BatchNormalization(), MaxPooling1D(pool_size2), LSTM(units64, return_sequencesFalse), Dropout(0.3), Dense(units32, activationrelu), Dropout(0.2), Dense(units1, activationsigmoid) ])输入形状是(256, 9)表示一个样本包含 256 个时间步每个时间步有 9 个通道5 个原始测点加 4 个派生统计特征后面会展开说。第一层 Conv1D 用 64 个大小为 3 的卷积核在时间维度上滑动相当于每次看 3 个连续时间步的局部模式然后池化把时间维度减半第二层卷积继续在更高层抽象上提取特征再做一次池化然后进入 LSTM 层把 CNN 提炼出来的特征序列做时序建模最后通过带 sigmoid 的全连接层输出一个 0 到 1 之间的故障概率值。这里有两个设计细节值得注意。第一卷积层的激活函数用了 ReLU一是计算简单、不容易梯度消失二是对设备信号里的正异常比如温度升高、振动增大能有更清晰的响应。第二BN 层放在卷积层后面作用是把每一层输出的分布拉回标准范围训练稳定性提高不少。我们在实际训练中发现不加 BN 时 loss 曲线经常出现“锯齿状”的震荡加了以后明显平滑了。Dropout 的作用是防过拟合尤其是故障样本数量不多的情况下不加 Dropout 很容易把训练集背下来测试集上一塌糊涂。2.2 数据采集与预处理MyEMS 侧的关键配置数据是整套模型的地基。这个项目里我们通过 MyEMS 采集了压缩机的 5 个核心测点A 相电流、B 相电流、排气温度、排气压力、油温。采样频率配置成每 10 秒采集一条记录这样每天每个测点大约产生 8640 个数据点5 个测点就是 4 万多条连续采集 3 个月累计超过 300 万条数据量对 MySQL 来说完全没压力对于模型训练也够用了。数据不是采上来就能直接用的这里有一个坑MyEMS 采集器偶尔会因为网络抖动或者设备通信超时产生缺失值。我们的处理策略分两层。第一层是实时链路如果某次采集失败MyEMS 会在下个周期自动补采这对趋势分析影响不大第二层是离线训练前我们会做一次完整的质量检查缺失比例超过 5% 的时段直接剔除缺失比例较低的时段用线性插值补全对明显的离群点比如电流瞬间跳到额定值 5 倍以上明显是传感器误报用前后相邻值的均值替换。另外所有数值在进模型之前都做了一次标准化方法就是(x - mean) / std均值和标准差用训练集统计测试集和线上推理时沿用训练集的统计量避免信息泄露。2.3 特征工程与滑动窗口设计很多人以为用深度学习就不需要做特征工程了这是一个常见的误解。CNN-LSTM 能自动学特征但不代表喂进去的原始数据不需要整理。这个项目里我们做了两层处理一层是窗口化另一层是统计特征补充。窗口大小为什么取 256这里有个计算逻辑。采样周期是 10 秒256 个时间步对应约 42 分钟的历史数据。我们把项目里的压缩机运行规律拉出来看了一下一个完整的加减载循环大约在 30 到 50 分钟之间窗口至少要覆盖一个完整循环模型才能区分“正常工况切换”和“异常趋势发展”。同时LSTM 的计算量跟序列长度成正比窗口再拉长到 512 甚至 1024训练时间和显存占用都会显著增加而测试发现准确率并没有明显提升所以最终定在 256。窗口滑动步长设为 128也就是两次相邻采样窗口有 50% 的重叠这样数据量能够翻倍对于样本量紧张的项目来说是很划算的做法。至于统计特征我们给每个窗口额外计算了 4 个派生特征当前窗口内的均值、标准差、峰峰值和变化斜率首尾差值除以窗口时长然后拼在原始信号后面相当于把 5 通道输入扩展为 9 通道输入到模型里。这三组特征分别刻画了信号的基线水平、波动幅度和整体趋势等于帮模型提前框定了重点实验显示加上之后准确率提升了大约 2 个百分点。2.4 标签构造故障预测为什么不是简单的二分类训练标签怎么打是整个项目里最需要认真对待的问题之一。最朴素的做法是把“设备是否发生了故障”作为标签故障时刻之前的样本都标为 0故障发生时刻以及之后标为 1。这样做有两个毛病一是模型只能学到“坏了之后”的特征起不到预警作用二是故障时刻附近的样本数量极少类别严重不平衡。我们采用的是“预警窗口”标签法。拿那几次有记录的故障事件举例从故障停机往前推 4 小时定义为预警窗口窗口内的样本全部标记为 1窗口之外的正常运行样本标记为 0。也就是说模型学习的目标不是“当前是否故障”而是“未来 4 小时内是否会发生故障”。这是预测性维护里非常关键的一个思路转变与其让模型判断“现在发生了什么”不如让它判断“接下来会发生什么”。4 小时这个窗口长度也不是拍脑袋定的而是和工艺团队讨论后定的4 小时足够维护人员响应和处理又不会因为窗口太长导致样本定义过松、正常波动也被误标为正样本。3. 模型训练与 92% 准确率验证3.1 数据划分与训练环境样本准备好之后第一步先划分数据集。我们按时间顺序来划分而不是随机划分——这一点很重要。如果用随机划分模型会“偷看”到未来时段的数据分布造成评估结果虚高到线上部署时立刻现出原形。划分比例大概是训练集 70%、验证集 15%、测试集 15%三个集合按时间先后依次排列。为了进一步压低过拟合风险训练集里尽量多涵盖不同工况验证集和测试集则包含最近两个月的数据这样最能反映“用过去的数据预测未来”的真实场景。训练环境没什么特别的一台带 RTX 3090 显卡的工作站Python 3.9 TensorFlow 2.10。故障样本大约有 3500 个窗口正常样本大约有 21000 个窗口正负样本比例约 1:6这个比例我们后面通过加权损失函数来处理。训练轮数 60 个 epochbatch size 64初始学习率 0.001并且用 ReduceLROnPlateau 在验证集 loss 连续 3 个 epoch 不下降时自动把学习率减半。整个训练大概跑了 40 分钟时间上完全能接受。3.2 超参数是怎么调出来的超参数方面有几个可以分享的经验。卷积核大小的选择上我们试过 3、5、7最终 kernel_size3 效果最好。原因也不难理解在 10 秒一个采样点的尺度上真正的故障特征通常集中在较短的时间局部太大的卷积核反而会把相邻的正常波动也“卷”进来模糊了特征边界。LSTM 单元数我们对比了 32、64、12864 在这个数据集上性价比最高128 时训练时间翻了接近一倍准确率只提升了不到 1 个百分点。Dropout 比例 0.3 和 0.2 是我们试了几个值以后相对稳的组合太低防不住过拟合太高会导致模型欠拟合、准确率反而下降。参数尝试值最终选择选择原因卷积核大小3 / 5 / 73局部特征集中大的卷积核会引入噪声LSTM 单元数32 / 64 / 1286464 性价比最高128 训练时间翻倍但收益甚微Dropout 比例0.2 / 0.3 / 0.40.3LSTM后0.2Dense后太低过拟合太高欠拟合滑窗大小128 / 256 / 512256覆盖完整工况周期同时控制计算量还有一个直接提升效果的点就是类别不平衡。1:6 的比例虽然不算极端但如果不处理模型为了最小化整体 loss会倾向于把所有样本都预测成“正常”因为这样已经把准确率拉到 85% 了。我们用了两个手段一是在损失函数里给正样本加权权重设为 6让模型把“漏报故障”当成比“误报正常”更严重的错误二是用数据增强中的时间扭曲对正样本做小幅度的随机缩放和平移扩充故障样本的多样性。这两个手段叠加下来模型对故障样本的召回率从处理前的 52% 提升到了 86% 左右提升幅度非常明显。3.3 92% 准确率从哪来这里必须说清楚所谓的 92% 是指独立测试集上模型在最优阈值下的综合准确率而不只是训练集上的拟合结果。测试集包含了最近两个月的完整数据其中故障窗口 480 个、正常窗口 3200 个左右。模型对每个样本输出一个 0 到 1 的概率值默认阈值 0.5 的情况下准确率大概是 88%但通过分析验证集上的 PR 曲线我们发现把阈值调高到 0.65 时整体表现最好这时候测试集准确率是 92.3%故障召回率 86.7%F1 值大约 0.90平均预警提前量 3 小时 47 分钟。有两点值得强调。第一准确率 92% 不是越高越好还要看误报率和漏报率的实际代价。在一个实际产线上漏掉一次故障可能意味着一整条线停机而多报一次故障最多是让维护人员多跑一趟检查。所以我们在选阈值的时候不是单纯追求准确率最大而是让漏报率控制在一个可以接受的水平低于 15%同时尽量压低误报率。第二92% 这个数字是在测试集上算出来的上线之后仍然需要持续跟踪实际表现因为设备工况会变数据分布会发生漂移模型需要定期重训。4. 部署上线与 MyEMS 告警联动4.1 模型服务化与容器部署模型训练完后进入部署阶段。我们的部署方案比较轻量把 Keras 模型导出为 SavedModel 格式用 TensorFlow Serving 提供推理服务Docker 容器封装后跑在一台普通的服务器上。TensorFlow Serving 的好处是原生支持 SavedModel版本管理和热加载都方便而且对请求的响应时间控制得很好。我们用 Python 脚本模拟线上请求做了压测单次推理平均耗时在 10 毫秒左右对于 10 分钟一次定时预测的场景来说性能绰绰有余。如果你不想引入 TensorFlow Serving另一个可行的选择是用 ONNX Runtime。先通过 tf2onnx 把 SavedModel 转成 ONNX 格式再用 ONNX Runtime 加载推理整体依赖更轻CPU 上也能跑得很快。但 ONNX 转换过程中偶尔会有算子兼容性问题特别是自定义层和某些高级 API 生成的算子需要额外处理。我们的建议是团队里有 TensorFlow 经验就首选 TensorFlow Serving省心要部署到边缘盒子或资源受限的设备上再考虑 ONNX Runtime。4.2 定时推理与告警触发流程在线推理的逻辑并不复杂每 10 分钟执行一次循环里做四件事。第一步从 MyEMS 的 REST API 拉取过去 42 分钟的 5 个测点数据把单位换算和缺失值处理做完第二步用训练时保存的标准化参数对数据做缩放然后构造成(1, 256, 9)的输入张量第三步调用推理服务得到故障概率第四步把概率值和当前时间写入 MyEMS 的设备监测数据库同时判断是否超过阈值超过则触发告警。告警触发我们还做了一个“连续确认”机制避免个别孤立的高概率值造成误报。具体逻辑是连续 3 次推理也就是 30 分钟内概率都超过 0.65才正式推送告警如果只有一次超过阈值后面又回落到正常范围就只记录日志不打扰维护人员。这个机制上线后误报数量明显减少一线工人的信任度也提高了。4.3 告警消息推送与值班响应正式告警确认后怎么通知到人也是一个重要环节。我们通过 MyEMS 的告警 API 写入系统告警列表同时用了一个简单的 Webhook 脚本推送到企业微信群里消息内容包括设备名称、故障概率、当前关键测点数值、最近 42 分钟的图片化趋势图。维护人员在群里直接看到信息就能判断是否需要立即到现场处理。生成趋势图这个细节看似不起眼但实际价值很大——光给一个“概率 0.82”的数字现场人员很难快速建立信任配上一张趋势图他们能直观看到哪个测点在爬升、是不是真的异常响应效率完全不同。5. 常见问题与排查技巧实录5.1 误报率高模型老是无缘无故报警项目上线头两周我们收到了最多的反馈就是“误报”。排查下来发现主要有三个原因一是工况切换带来的正常波动比如设备在加减载瞬间电流和压力会发生短时大幅变化模型误判为故障前兆二是个别测点的传感器偶尔会出现瞬时尖峰被模型当成了故障特征三是某些外部环境变化比如气温骤降导致信号基线偏移。针对这三个原因我们分别做了处理。对于工况切换我们在输入特征里增加了一个“当前机组负载率”的通道让模型学会区分“负载变化”和“故障趋势”对于传感器尖峰在预处理阶段加入一个中值滤波把单点跳变抹平对于环境变化用滑动平均法把历史基线做动态校准。这一轮优化之后误报率从最初的每天 3 到 4 次降到了平均每两天 1 次左右效果非常明显。误报根因信号表现处理方式工况切换加减载瞬间电流压力短时大幅波动增加负载率通道让模型区分工况切换与故障传感器尖峰单个测点瞬时限值跳变中值滤波抹平单点异常环境基线偏移气温骤降导致整体信号平移滑动平均法动态校准历史基线5.2 模型换到另一台同型号设备上效果变差测试集上 92% 的准确率并不意味着换一台设备就能直接复制。我们尝试把训练好的模型迁移到另一台规格相同、但运行年限不同的压缩机上准确率掉到了 78% 左右。原因很好理解每台设备的磨损程度、传感器安装位置、运行工况都不一样新设备的信号分布和训练数据存在差异。解决思路是迁移学习。我们用原来设备的数据训练出一个预训练模型然后把新设备的少量数据大约 2000 个样本窗口拿来做微调只训练最后两层全连接层前面的卷积和 LSTM 层冻结住。微调了 10 个 epoch 之后准确率回升到了 89%。这个经验很重要做预测性维护的项目不要指望一个模型吃遍整个车间务必要给每台关键设备留出数据适配和微调的时间。5.3 训练数据里故障样本太少怎么办故障场景本身就是小概率事件很多设备一年也发生不了 1 次故障样本量不足是预测性维护项目里最常见的难题。我们这次能有 3500 个故障窗口已经算运气不错因为客户提供了过去两年的历史维护记录和部分故障阶段的数据。如果遇到更极端的情况比如一台新设备没有任何故障记录有两条可以尝试的路线。第一条是借助同类型设备的公开故障数据集做预训练比如轴承故障诊断领域常用的 CWRU 数据集虽然设备类型不完全一样但故障信号的时频特征有一定的通用性预训练后再用自己设备的正常数据做微调。第二条是用自监督或者无监督的思路先用大量正常数据训练一个自编码器或者基于重构误差的异常检测模型把明显偏离正常分布的时段自动标出来作为“候选故障样本”人工确认后再交给 CNN-LSTM 去训练。这种方法不能完全替代真实的故障数据但至少能把冷启动问题的缓解一大半。5.4 一线工人不信模型怎么办这其实是最容易被忽略、也最关键的问题。一个再好的预警模型如果现场维护人员不相信它、收到告警也不去看那一切都是零。我们在项目启动时就和客户强调预警系统要设计成“辅助工具”而不是“裁判”因此特别做了三个细节第一每条告警都附带可追溯的实时数据和趋势图维护人员可以自己验证模型判断是否合理第二系统里设置了一个“处置反馈”按钮工人处理完告警后要填写处理结论正常巡检、发现隐患、已维修等这些反馈会成为下一轮模型优化的标注数据第三项目初期每周和一线班组开一次复盘会把误报和漏报的案例拿出来一起讨论及时调整阈值和告警规则。事实证明这些“非技术”的投入才是项目最终被接受的关键。到项目验收时一线工人对待模型告警的态度已经从不信任变成了依赖甚至主动要求系统在更多设备上部署。写到这里差不多到了我特别想和大家分享的一段个人体会。92% 的准确率听起来很漂亮但真正落地之后你会发现预测性维护的难点从来都不只在模型本身而在于数据质量、工程链路、业务协作和一线信任这四件事。模型选 CNN-LSTM 还是别的架构其实只是决定项目效果上限的一个环节把数据采集、特征处理、告警闭环和反馈机制做扎实才是让上限真正兑现的保障。如果你正在规划类似的设备预警项目我的建议很简单先把数据链路跑通再谈模型效果先解决“误报烦人”的问题再追求“准确率更高”先让现场工人愿意看告警再谈算法优化。这条路没有捷径但每一步走稳了结果是实打实的。