☰
物理约束与不平衡样本下的工业故障诊断实时部署框架
2026/10/27 5:56:22 网站建设 项目流程

做工业故障诊断的算法,最怕的不是模型精度不够,而是模型在实验室指标漂亮、一到产线就开始乱报。我近一年都在做“物理约束下基于不平衡样本的工业故障诊断与实时部署框架”,从数据采集、模型训练到边缘端推理整个链路都走了一遍,今天把里面真正起作用的思路、代码和坑一次说清楚。这个方向适合正在做旋转机械监测、电机异常检测、流水线质量判定的人参考,也适合刚接触工业AI的学生看看真实项目里的取舍。

这里说的“物理约束”,不是让模型硬背物理公式,而是把振动、温度、电流这些信号的客观规律作为先验,连同不平衡样本处理一起设计进训练目标里;“实时部署”则照顾产线上毫秒级判断的需求。文章不会只讲概念,我会把损失函数怎么改、窗口怎么设、模型怎么压缩、现场怎么调阈值都摊开讲,希望你看完能少走弯路。

1. 为什么工业故障诊断绕不开物理约束

1.1 纯数据驱动在产线上的“三连崩”

第一崩是变工况。一台离心泵转速从2900转/分调到1500转/分,振动频谱的峰位和幅值全部变化,纯数据模型如果没采过低速工况,很容易把正常状态判成故障。第二崩是故障样本天然稀缺,重型设备不允许故意弄坏,故障样本往往是历史事故攒下来的,类别极度不平衡。第三崩最隐蔽:模型训练时没有引入物理一致性,推理结果可能违背常识。

举一个具体例子。轴承内圈损伤产生的冲击会以特定频率形成边频带,这个频率由轴承几何参数和实时转速唯一确定。纯数据模型在样本充足时也能学到这种特征,可一旦转速偏离训练分布,它可能把任何一个高能量频段都当成故障证据,于是现场频繁误报。物理约束在这里的作用,就是逼着模型只在“物理上说得通”的频率范围内寻找证据,训练分布之外的频率即使幅值很高也会被抑制。

这三连崩叠加起来,光靠加大数据量根本解决不了。数据可以补,但变工况下补样本的成本和风险都很高;模型可以堆参数,但推理合理性没法靠堆参数保证。物理约束恰好是少数能在模型结构之外同时缓解这些问题的杠杆。

1.2 物理约束具体约束什么:能量、频段、因果

我在项目中把物理约束分成三类来落地:能量约束、频段约束、时域因果约束。能量约束比较好理解,设备正常运行时振动烈度总在一定范围,突然出现不可能的能量跳变通常来自传感器冲击或外界干扰,模型应把这种突变归为异常事件而不是故障类别;如果输出层给出高置信度故障判断,但对应频段能量根本达不到物理阈值,这个判断就是可疑的。

频段约束是最常用的。以滚动轴承为例,外圈故障特征频率BPFO、内圈BPFI、滚动体BSF都可以由转速和轴承参数实时算出来,正常部件能量集中在转频及其低阶谐波附近,故障部件会在特征频率附近出现边频带。网络在频谱图上的注意力如果落在与这些频率完全不沾边的区域,物理损失就会变大,反向传播会慢慢纠正这种错误。

时域因果约束则关注顺序关系:故障冲击通常先出现微弱周期,再逐渐变得密集,最后恶化到明显破坏。模型如果直接跳到“严重故障”而跳过演化过程,在时序任务里就违反了因果先验。这一条在早期故障诊断里尤其重要,因为现场要的是“趋势判断”而不是只看瞬时刻状态。

2. 不平衡样本:比想象中更难处理的“三种不平衡”

2.1 数量失衡、时窗失衡、难易失衡

说到工业数据不平衡,大多数人的第一反应就是故障样本少、正常样本多。这确实是最直观的数量失衡,一般用重采样和类别加权就能顶住。但落地之后我发现,真正让模型失效的是另外两种不平衡:时窗失衡和难易失衡。

时窗失衡指的是故障不是全程都明显的,比如轧机咬钢瞬间电流冲击大,但故障特征只在某个转速区间内激发。切窗时如果按时间均匀切,故障出现在窗口内的时刻和时长都不均匀,模型学到的是“某段时间异常”而不是“某种物理状态异常”。难易失衡更隐蔽,早期故障、复合故障、轻微磨损这类样本占比极少,而且特征弱,模型为了降低整体损失会直接忽略这些难样本。普通重采样解决不了这两种问题,因为简单重复故障样本并不会增加信息量。

2.2 采样、代价敏感和物理约束的配合顺序

我试过SMOTE、ADASYN、随机过采样,也试过Focal Loss和类权重。坦率说,如果样本量差距在一两个数量级内,Focal Loss加上合理类权重已经够用;差距再大就必须做合成样本。但SMOTE这类方法有一个致命问题:它在特征空间线性插值,可能合成出物理上根本不可能出现的数据,比如把正常频谱和严重故障频谱的中值当成“早期故障样本”,训练时模型会学到一种现实中不存在的过渡态。

我的经验是,物理约束要前置到数据层和损失层两边。数据层合成样本之后,先用物理规则做一遍过滤,计算合成样本的频谱峰值是否落在合理故障频率附近,离得太远的直接丢弃;损失层再把物理项写进总损失,让模型即使见到不合理样本也没有动力去拟合它。配合顺序上,先保证物理约束存在,再把重采样比例控制在不超过3:1,最后才用Focal Loss调难易样本权重。这个顺序反了我吃过亏,第一版先把SMOTE拉满,公开测试集分数很好看,现场一跑就露馅。

3. 把物理约束写进损失函数:从原理到代码

3.1 三大实现方式:软约束、硬约束与数据约束

物理约束落到代码里,有三种常见实现方式。第一种是软约束,也叫正则约束,在原有分类或回归损失后面加上一个物理损失项,通过梯度下降端到端训练,是最通用也最好调的方式。第二种是硬约束,直接改网络输出层,让输出一定满足物理公式,比如预测故障特征频率时把输出投影到理论频率附近区间;这种方式约束最强,但会破坏网络的学习自由度,应用面比较窄。第三种是数据约束,在训练前清洗和筛选样本,把物理上可疑的样本按规则过滤或改标注,它不影响模型结构,只影响数据质量。

工业项目我默认选“数据约束在前、软约束为主”。原因很简单:软约束写起来快,调试时能单独看物理损失的变化,而且和现有深度学习框架完全兼容;数据约束不增加训练复杂度,又能把明显的脏数据挡在外面。硬约束留给那种输出物理量本身、且物理关系非常明确的子任务,比如用轴心轨迹预测转子偏心量,这种场景用硬约束收益更大。

3.2 物理损失不该“写上去就完事”:权重和顺序是关键

物理损失最常见的问题是权重给得太大。物理约束的目的不是全盘否定数据驱动,而是让模型在模糊地带不乱猜。我先把不带物理约束的模型训练到收敛,保存一个基线,再加载权重、加入物理损失微调。物理项权重从0.01开始,观察训练集和验证集的走势,如果纯分类精度掉了超过三个点,说明权重太大,压缩回一半。判断物理约束是否有用的指标,不只看准确率,更重要的是看验证集上的“物理违规率”:推理结果里有多少条落到了理论频率窗口之外。

另外要注意物理损失和分类损失的量纲可能差很多。物理损失通常是能量比值或频率误差,数值在0到几之间,分类损失是交叉熵,数值可能到几甚至几十。如果不做归一化,λ=1很可能让物理项淹没分类项。我习惯先对物理损失做归一化,让它均值在0.5上下再乘权重。

下面给一段极简的物理损失代码,它计算频谱能量在理论故障频带内的占比,并把“占比过低”当成惩罚。实际项目还会加频带宽度、多次谐波、转频成分等,这里省略了,重点是看思路。

import torch def physics_band_loss(spec, freqs, fault_freq, band_ratio=0.05, eps=1e-8): # spec: [B, F] 幅度谱 # freqs: [F] 每个bin对应的频率 low = fault_freq * (1 - band_ratio) high = fault_freq * (1 + band_ratio) mask = (freqs >= low) & (freqs <= high) # 理论故障频带 band_energy = spec[:, mask].pow(2).sum(dim=1) total_energy = spec.pow(2).sum(dim=1) ratio = band_energy / (total_energy + eps) # 目标不是让比例越高越好,而是如果故障频带几乎无能量,判为故障则矛盾 loss = torch.clamp(0.5 - ratio, min=0).mean() return loss # 总损失 # loss = ce_loss + lambda_phy * physics_band_loss(...)

这段代码体现的是“软约束”的最小实现:只有断言“故障频带能量占比不能太低”。实际操作中,还要根据输入信号的采样率、窗长和FFT点数把freqs生成对,否则频率对不上,物理约束反而帮倒忙。

4. 实时部署框架:边缘选型、模型压缩与流式推理

4.1 部署架构:中心训练加边缘推理是默认答案

工业实时诊断几乎不可能把数据全部传到云端推理。一条产线几百个测点,每秒几万赫兹采样,实时性要求每窗处理在几十毫秒内完成,网络一旦抖动部署就会失效。所以我们采用中心训练加边缘推理的架构:训练阶段在GPU服务器上完成,推理阶段把模型转换、量化后部署到产线边缘装置。

边缘端怎么选,要看信号通道数量和单窗延迟预算。大多数旋转机械测振场景,一块带NPU或GPU的工控机就够了;如果测点特别密集,可以用多路采集边缘网关,把数据切到不同计算核心。选型时的硬指标不是峰值算力,而是持续推理下的算力利用率,有些设备标称算力很高,但散热一上来就会限频,这个必须在现场跑压力测试。我踩过这个坑,选型时不看持续负载,部署后一到夏季车间温度一高就掉链子。换成更注重持续算力的方案才解决。

4.2 剪枝量化蒸馏:把模型压到能上产线的体积

训练好的模型直接部署通常会吃亏,尤其实际网络中混合了1D CNN、GRU和特征处理层,参数并不小。我的标准动作是蒸馏加量化:先让复杂教师模型产生软标签,把小模型蒸馏到教师模型95%以上的预测一致率;然后做结构化剪枝,剪掉注意力得分持续很低的通道;最后做INT8定点化,标定集必须从真实测点采集,不能只用训练集的随机子集。

这里要强调一个容易被忽视的点:量化不是所有层都收益。物理约束相关的频带统计层用INT8会引入频率定位误差,我一般把这层保留FP32,其他卷积和全连接层用INT8。虽然增加了一点内存占用,但换来了物理约束下的推理一致。整套压缩下来,模型体积降到原来的1/4到1/6,单窗延迟从几十毫秒降到几毫秒,这种收益在工业现场是决定性的。

4.3 滑窗和去抖:实时推理的工程细节

不少文章讲完模型就把系统丢给部署,但真正让实时诊断“能看”的是滑窗和输出平滑。振动信号采集是连续流,推理时按固定窗口长度切段,窗口之间需要有重叠。重叠率太低,故障冲击可能被窗口边界切碎;太高又浪费算力。我实测下来的惯用值是窗口长度1秒,步长0.25秒,也就是重叠率75%。这个设定既保留了故障冲击完整性,又让输出每250毫秒刷新一次,现场人员不觉得迟滞。

输出平滑也有讲究。单窗推一个类别概率往往像噪声一样跳动,直接报警会误报。我在框架里做了两级规则:第一级对最近N个窗口的概率做指数移动平均;第二级要求故障概率连续M个周期超过阈值才触发。N和M都要根据现场误报容忍度调,先用历史数据回放确定初值,再到现场迭代。整体上,物理约束下的推理输出本身就比纯数据模型平滑,因为特征已经被约束在物理合理区域,误报尖峰少了一大半,平滑策略的压力小很多。

5. 一次现场落地实录:轴承故障诊断框架复现

5.1 数据准备与物理特征频率核对

这个框架在轴承故障诊断上的复现路径,值得从头到尾走一遍。第一步是数据准备,我采集的是电机驱动端振动加速度信号,采样率25600Hz,转速用编码器同步记录。采集时长要覆盖启停、匀速和加载三个工况段,不能让某类样本只出现在某一段。切窗时按1秒长度、0.25秒步长切,同时记录每个窗口的平均转速和载荷,这两个值后面会决定物理约束频带。

第二步是计算轴承各部件故障特征频率,并和频谱图核对。以滚动轴承为例,设滚珠个数n、滚珠直径d、节径D、接触角α、转频fr,公式是:外圈BPFO=(n/2)·fr·(1−d/D·cosα),内圈BPFI=(n/2)·fr·(1+d/D·cosα),滚动体BSF=(D/(2d))·fr·(1−(d/D·cosα)^2),保持架FTF=(fr/2)·(1−d/D·cosα)。把这些理论值画到频谱图上,如果实测峰值频点偏离理论值超过2%,首先怀疑标注错误或者转速不对,而不是先改模型。这一步特别费时间,但能过滤掉一半以上的脏样本。

5.2 模型结构、训练超参与物理损失调参

模型结构我用的是1D CNN加双向GRU再加物理约束头:1D CNN负责抽取局部冲击形态,双向GRU负责不同时间尺度上的趋势,分类头输出四种状态(正常、外圈故障、内圈故障、滚动体故障),物理约束头接收转速信息,计算每个窗口的故障频带能量占比损失。特征频率不是网络自己猜的,而是用上一步的公式实时算出来喂给物理头,所以模型不用死记转速和频率的关系。

训练参数我给了个可复现的配置:Adam优化器,初始学习率1e-3,批大小64,训练100轮,前70轮只训练分类损失,后30轮打开物理损失并让λ从0.01线性涨到0.1。这里我特意用“先分类后物理”而不是一开始就联合训练,原因是物理约束在早期可能压制CNN学到的有效特征,等分类结构基本确定再微调,两个目标不会打架。总损失就是ce_loss+λ·physics_loss,我一般把物理损失归一化到0.5均值后,λ从0.01起调。

5.3 边缘端实测:精度、延迟、吞吐和内存对照

最后一环是把模型部署到边缘设备上实测。下面这个表是我在同一批现场数据上做的云侧FP32与边缘INT8对照,不算是普适基准,但可以看出量化和物理约束共同作用后的典型表现:

指标云侧FP32边缘INT8
测试集准确率0.9710.968
单窗推理延迟28ms3.2ms
单核推理吞吐35窗/s260窗/s
模型体积56MB14.2MB
峰值内存810MB214MB

差距最大的不是精度,而是延迟和内存。INT8让单窗延迟降了一个数量级,峰值内存只剩四分之一左右。准确率虽然只降了0.3个百分点,但如果没有物理约束,纯数据模型量化后的准确率掉得更厉害,因为分类边界被标定误差扰动。引入物理约束后,网络的特征表示已经落在物理合理区域内,量化引入的少量噪声不足以把小样本推到错误边界。

6. 常见问题与排查技巧实录

6.1 训练时物理损失NAN或发散的排查思路

物理损失出现NAN,我踩过几次,最常见原因是频谱频率轴和采样参数对不上。比如采样率写了25600,窗口长度却是1秒不整除,FFT点数一改,freqs数组长度和谱向量错位,mask就会出问题。排查步骤很固定:先打印freqs的最后一个值和采样率的一半是否相等;再检查物理头拿到的转速单位,如果转速是RPM而公式用的是转每秒,特征频率会差60倍,物理损失立刻爆炸。

另一个原因是λ设置过大或归一化没做,物理损失量级比分类损失大很多,梯度更新方向被带偏。解决办法是先不对物理损失求梯度,只记录数值,确认置信区间正常后再打开。如果还发散,就加梯度裁剪,一般clip_norm=1.0够用。最后提醒一句,不要在训练早期就加入硬约束,硬约束投影太强容易让早退学习崩掉,软约束微调是更保险的路线。

6.2 漏报误报的平衡:阈值、置信度与趋势斜率

漏报和误报是现场的两个死对头。调阈值不是拍脑袋,我的方法是先离线回放一段足够长的历史数据,模拟各种阈值下的漏报率和误报率,画出一条权衡曲线,再让现场工艺人员根据可接受代价选点。比如更怕设备烧毁就调低报警阈值,更怕停产误停就调高阈值。单靠概率阈值还不够,我还会加趋势斜率:只允许报警在最近几个窗口的故障概率持续走高时触发,瞬时尖峰不报警。

趋势斜率的计算非常简单,用最小二乘拟合最近5个窗口的输出概率,斜率为正且达到设定值才有效。这个方法配合物理约束效果更明显,因为纯数据模型的概率跳动大,趋势拟合容易被干扰;加了物理约束后概率序列整体平滑,趋势判断的可靠性也上来了。

6.3 量化后精度下降:校准集和物理规则的兜底

INT8量化后精度下降,先不要急着换更大模型。最常见的原因是校准集选得太随意,只用了训练集的随机几百个样本,没有覆盖现场真实的工况范围。校准集应该从现场连续采集数据中均匀抽样,至少覆盖正常、早期故障、明显故障三类,并且包含不同转速和载荷段,让量化器充分看到动态范围。

如果校准集没问题但精度还是掉,就把物理约束相关层保留FP32,或者对量化后的模型用物理规则做后处理修正。比如模型输出概率是0.6的内圈故障,但频谱在BPFI附近完全没有能量,就用物理规则把输出概率压回正常类别。这种兜底听起来老土,实际在产线上特别能用,因为物理规律不会跟着量化误差漂移。

真要我给一条最终建议,我会说:物理约束不是用来把测试集分数刷高的插件,而是部署之后让系统不容易乱报的刹车。把物理规律先写进损失里,再去调不平衡采样,顺序别反。我因为这个顺序吃过亏,第一版先把SMOTE拉满,模型在公开数据集上很漂亮,现场一跑就露馅。后面把物理约束放在了第一步,不平衡采样只做适度强化,整个框架才算真正落地。另一个小技巧是平时多保留一些“物理违规率”日志,现场扯皮时,那一串数字比什么曲线都有说服力。

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

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

立即咨询