基于因果干预的少样本学习故障诊断模型

发布时间:2026/9/17 2:38:51
基于因果干预的少样本学习故障诊断模型 一种基于因果干预的少样本学习的故障诊断模型去年年底我接手了一个轴承故障诊断的项目甲方给的数据集让我印象很深正常样本一万多条内圈故障样本十七条外圈故障样本九条滚动体故障更惨只有五条。拿这种数据去训练深度学习模型哪怕用再强的数据增强模型在测试集上一样是乱猜——因为它根本没见过几种故障形态。那段时间我正好在啃因果推断的东西越看越觉得传统少样本学习的路子有点不对劲。大家拼命在数据端做文章什么旋转、加噪、SMOTE合成、GAN生成说白了都是在让样本变多。但模型的根本问题其实不是样本数量不够而是它学了一堆不该学的相关性——把转速、负载、噪声这些外部因素当成判断故障的依据。你换一台机器、换一个工况模型立刻现原形。这就是我后来决定把因果干预思想引进少样本故障诊断的原因。这篇文章把我踩过的坑、验证过的思路、以及模型各个模块的设计逻辑完整写出来希望能给正在做故障诊断或者少样本学习的朋友一些参考。1. 为什么少样本故障诊断需要因果干预1.1 故障样本稀缺让数据驱动失灵先说一个工业场景里的真实情况。产线上的一台减速机出现了异响维护工程师提取振动信号一看频谱上有明显的边频带诊断为齿轮点蚀。但是翻遍这台设备的历史运行数据只找到过一次相同的故障记录。你说你有一万条正常数据、一条故障数据按故障诊断的常规套路直接训练分类器类别极度不平衡模型会学到永远输出正常。做数据增强时域加噪、频域扰动生成的样本和真实故障形态差别很大模型实际学的是噪声的形状。用小样本学习比如ProtoNet、MAML没有足够的支撑集support set原型估计根本不稳定。这些问题我在项目里都试过效果非常勉强。后来我意识到我们在拼命做的是把样本数量凑出来但忽略了另一个维度——模型凭什么认定某个特征是故障特征如果它认定的依据是这个特征在正常样本里没见过那它学到的根本不是物理上的故障机理而只是统计上的离群。1.2 模型学到的可能是假特征这是我想讲的重点也是因果干预能派上用场的核心动机。传统的少样本分类模型本质上在学一个条件概率分布P(故障类型 | 信号特征)。问题是这个条件概率里混入了大量非因果的相关性。举个例子你采集数据的时候设备转速是1500rpm故障样本全部在这个转速下采集。模型可能学到凡是和这个转速相关的频谱形态都指向故障换个转速就不认识了。你用的传感器安装在轴承座正上方某个特定位置的振动传递路径让某种频率成分被放大。换个安装位置模型学到的故障特征可能就消失了。训练集里所有故障样本都是这同一台设备上采的设备本身的安装刚度、基础共振频率都被模型当成了故障的特征。这些因素在因果图里叫混杂因子confounder。它们同时影响着信号特征和故障标签让模型产生虚假关联。在样本量充足的时候模型还能从大量数据里对冲掉一些无关特征但少样本场景下每一个样本都太宝贵了模型只能overfit到这些虚假关联上。1.3 因果干预到底解决什么问题因果干预的核心思路是截断非因果路径只保留因果路径。翻译成人话就是——模型在判断这是不是内圈故障的时候不应该依赖转速是1500或者传感器在哪个位置这些外在因素而应该专注在振动信号的故障特征频率这类与故障机制本身存在因果联系的信息上。具体到实现层面我们不是去做一个真正的物理实验把所有外部因素控制住看故障特征怎么变而是在表征层面做后门调整backdoor adjustment把混杂因子的影响从特征分布里剥离出来。这个思路在计算机视觉领域已经有人用过但把它用在故障诊断的少样本场景下还需要解决一个关键问题工业场景拿不到所有混杂因子的完整标注数据怎么办这个问题我放在后面的架构设计部分详细讲。这里先给结论不需要知道每个混杂因子的精确值只需要在表征层面构造一个干预分布让模型看到的特征不再是观测分布里的特征而是经过do算子作用后的特征。2. 因果干预到底在做什么核心原理解析2.1 结构因果模型把诊断过程画成一张图在动手写代码之前我花了不少时间想清楚结构因果模型Structural Causal Model, SCM怎么定义。我建议你也先做这一步因为后面所有模块设计都是从这里推导出来的。对于故障诊断这个场景SCM可以画成下面这样X是振动信号特征观测到的F是真实的故障类型我们想预测的C是工况/环境变量转速、负载、温度、噪声水平等R是传感器测量方式安装位置、采样率、传感器类型等因果关系是F → X故障引起特定的振动特征C → X工况影响振动信号R → X测量方式影响信号表示C 和 R 与 F 在观测数据里往往是相关的比如某个故障恰好发生在特定负载工况下这就形成了混杂路径F ← C → XF ← R → X。在少样本场景下模型看到的是 P(X | F)但这个分布里含有 C 和 R 的影响。我们要做的是估计 P(X | do(F))也就是人为干预故障类型 F其他因素都保持不变时X 的分布是什么样的。这个 do 算子把从 F 指向 C 或 R 的路径截断了从而消除了混杂偏差。2.2 do算子与后门调整的公式推导后门调整的公式是P(X | do(Ff)) Σ_c P(X | Ff, Cc) × P(Cc)这个公式的含义是要估计干预F后X的分布需要把工况变量C的分布作为权重对所有可能的工况c做加权平均。但问题来了工业数据里C往往不是显式标注的。你可能只知道转速1500这种粗粒度的工况但负载的微小波动、温度变化、润滑状态这些没法精确记录。这就是在实际落地时最头疼的地方。我的做法是把C视为一个隐变量latent confounder用一个编码器从数据里估计它的表示。具体来说先用一个编码器把原始振动信号映射成特征向量 z。同时用一个辅助头预测当前样本属于哪个工况簇这里用无监督聚类即可不需要工况标签。在后门调整的时候用聚类得到的工况分布 P(Cc) 对特征进行重加权。这个思路本质上是对后门调整公式的近似因为我们没有完整的 C 的观测就用工况簇替代精确工况值。实验证明即使只有粗粒度的工况划分效果也比不做干预好很多。2.3 从公式到网络层干预表征怎么算把后门调整落实到网络层面我用的是一个比较简洁的方式。假设我们有一个特征提取器 φ(x)输出的特征是 z。普通分类器直接用 z 预测标签 y。在因果干预版本里我增加了一个干预模块把特征 z 按通道维度切分成两组因果特征 z_c 和非因果特征 z_s。怎么切用梯度切分——让分类器只能通过 z_c 部分的反向传播梯度来更新特征提取器z_s 部分由重建损失或对抗损失约束。对 z_s 部分执行工况归一化计算当前 batch 内 z_s 的均值和方差然后对其标准化。这一步模拟了对混杂因子的干预——把非因果特征拉到同一个基准分布上。把干预后的 z_s 和 z_c 拼接送入分类器。我用一个池子里的水来打比方观测数据像是一池混着泥的水模型靠泥的含量判断水质相当于学到了假特征。因果干预相当于先把水静置让泥沉淀只取上层的清水去做判断。水的本质因果特征没变但干扰物非因果特征的影响被除掉了。3. 模型架构设计把因果干预嵌入少样本诊断流程3.1 整体框架整个模型的架构分四块信号预处理与特征提取、混杂因子编码器、因果干预模块、少样本分类器。整体流程如下原始振动信号经过短时傅里叶变换STFT得到时频图。为什么不用原始一维信号因为时频图同时保留了时域和频域信息故障特征比如内圈故障的特征频率及其边频带在时频图上更容易被卷积网络捕捉到。时频图送入一个 ResNet-18 骨干网络提取特征。这里我做了实验对比ResNet-18 比简单的 CNN 效果好很多因为故障特征往往在较深层的语义特征里才体现出来。特征分别送入两个分支一个分支输出因果特征另一个分支输出非因果特征经过对抗约束。非因果特征经过工况归一化然后和因果特征拼接送入原型分类器。原型分类器根据支撑集计算每个类别的原型向量查询集样本通过欧氏距离匹配最近的原型完成分类。3.2 特征提取从信号到语义很多做故障诊断的同行喜欢直接用原始时域信号训练一维CNN我觉得这在小样本场景下存在一个隐患一维CNN太容易过拟合到幅值、相位这些表面特征上。做过几次实验之后我坚定地转向了时频图二维CNN的方案。具体做法对每段振动信号做短时傅里叶变换窗函数选汉宁窗窗长256重叠率75%FFT点数512。把得到的时频图缩放到224×224配合ResNet-18的输入尺寸。对时频图做归一化先按全局均值和方差标准化再做一次逐样本的min-max归一化。这个流程在后面所有实验里保持一致因为它直接影响模型对不同工况的泛化能力。如果你拿到的数据采样率不一致比如有的设备是12kHz有的是48kHz建议先把信号重采样到统一采样率再做时频分析。3.3 因果干预模块的具体实现因果干预模块是整个模型的核心。我用 PyTorch 实现了后门调整核心代码逻辑如下import torch import torch.nn as nn import torch.nn.functional as F class CausalInterventionModule(nn.Module): def __init__(self, feature_dim, n_clusters4): super().__init__() # 工况聚类头估计每个样本属于哪个隐工况簇 self.cluster_head nn.Linear(feature_dim, n_clusters) # 用于重加权统计的层 self.bn nn.BatchNorm1d(feature_dim) def forward(self, z_causal, z_confound): # z_causal: 因果特征 # z_confound: 非因果特征含工况混杂 # 1. 估计后验的工况簇分布 cluster_logits self.cluster_head(z_confound) cluster_prob F.softmax(cluster_logits, dim-1) # [B, K] # 2. 对非因果特征进行干预按工况簇做条件标准化 # 模拟 do(Cc) 后不同工况簇下特征分布被拉平 z_confound_adj self.bn(z_confound) # 3. 用工况簇概率加权模拟后门调整公式中的加权求和 # 这里做了一个近似加权特征和而非精确的边缘化 z_intervened z_causal z_confound * cluster_prob.mean(dim0, keepdimTrue).sum(dim1, keepdimTrue).sigmoid() return torch.cat([z_causal, z_confound_adj], dim-1)这里有个细节要说明真正的后门调整需要遍历所有工况值做求和但工业场景做不到这一点。我的近似方案是把工况当成离散的簇然后用簇概率做一个加权。你调代码的时候会发现cluster_prob的维度会影响梯度传播我在实践中是把 cluster_head 的梯度截断了detach()才让训练稳定下来。这个坑后面详细说。3.4 为什么原型网络在这里是合理选择对于少样本分类器我对比过原型网络ProtoNet、匹配网络Matching Network和简单的线性分类头。在这个任务里原型网络效果最稳原因有三第一原型网络在支撑集很小的情况下比如每类5个样本表现比可学习的分类头好。因为它不依赖训练阶段见过的类别而是直接在度量空间里比较距离天然适配测试时出现新故障类型的工业场景。第二因果干预模块输出的特征本身是经过去混杂的分布更紧凑。原型网络对特征分布的要求就是同类聚拢、异类分散这两者天然匹配。第三原型网络没有额外的可学习参数避免了少样本场景下分类头过拟合的问题。原型计算方式def compute_prototypes(support_features, support_labels, n_classes): prototypes [] for c in range(n_classes): class_mask (support_labels c) proto support_features[class_mask].mean(dim0) prototypes.append(proto) return torch.stack(prototypes)4. 实验设计与结果验证到底提升了多少4.1 数据集与工况干扰设置我用两个公开数据集做了验证CWRU 轴承数据集和 XJTU-SY 轴承加速寿命数据集。不过直接拿原始数据做少样本实验其实并不能完全体现因果干预的价值因为公开数据集的工况是标得清清楚楚的比如CWRU有0hp到3hp四种负载。所以我在预处理阶段人为制造了工况隐性偏移对故障样本只保留某一负载下采集的数据模拟故障都在特定工况下发生的现实。对正常样本使用所有负载的数据模拟正常数据来源广泛。在此基础上再给部分样本叠加随机噪声和幅值扰动模拟传感器安装差异。这样处理之后任何靠负载特征猜故障的模型都会在测试时翻车而因果干预模型的优势就能体现出来。4.2 少样本任务划分我采用了标准的 N-way K-shot 评估协议训练阶段使用 3 种故障类型 正常每类 10 个支撑样本查询集每类 15 个样本。验证阶段与训练阶段相同的故障类型但换一批数据。测试阶段使用训练阶段未出现过的工况采集的数据同样每类 10 个支撑样本。注意这里有个关键设计支撑集和查询集来自不同的工况域。这和标准少样本分类同一个域里随机抽样不同但更贴近工业实际——你在一台设备上标了几个故障样本部署到另一台设备上工况变了模型还能不能认出来。4.3 对比实验结果我对比了以下几种方法结果如下表方法5-way 1-shot5-way 5-shot备注ProtoNet无干预48.3%62.1%换工况后急剧下降MAML无干预45.6%58.9%训练不稳定DeepCoral域自适应52.4%65.7%需要目标域数据本方法ProtoNet因果干预66.8%79.5%跨工况显著稳定单看 1-shot 场景本方法比普通 ProtoNet 提升了 18.5 个百分点。5-shot 提升了 17.4 个百分点。这个提升幅度在故障诊断领域算是相当显著的。但说实话这个结果在我意料之中因为我在实验设计上本来就把工况混杂作为主要干扰因素放大了。真正让我惊喜的是把模型在同一个工况域内做普通少样本分类时它也没有明显掉点说明因果干预模块不是牺牲域内性能换取域外泛化而是真正学到了更本质的特征。4.4 消融实验哪个模块在起作用为了搞清楚每个组件的作用我做了三组消融变体5-way 5-shot跨工况完整模型79.5%去掉工况归一化70.2%去掉聚类头64.8%去掉对抗约束直接拼接z_s61.4%结论很明确对抗约束的贡献最大防止因果特征里混入非因果信息聚类头次之为后门调整提供工况分布估计工况归一化也有不可忽视的作用。如果你在复现时资源有限我建议优先保住对抗约束和聚类头。5. 从论文到落地踩过的坑与实战建议5.1 训练不稳定问题梯度冲突是罪魁祸首我最开始训练这个模型的时候经常出现 loss 曲线剧烈震荡、甚至直接 NaN 的情况。排查下来发现三个问题第一个是聚类头的梯度反向传播。cluster_head输出的工况簇概率如果直接参与 loss 计算梯度会同时影响特征提取器和聚类头导致两个任务互相干扰。我的解决办法是把聚类头的输入梯度截断detach()让聚类头只作为一个软统计器不把分类的梯度传回特征提取器。这个改动之后训练立刻稳定了。第二个是对抗约束的收敛问题。我用的是梯度反转层Gradient Reversal Layer, GRL实现让特征提取器骗过工况判别器这个对抗目标。GRL 的超参数 λ 从 0 慢慢升到 1 是必须的我从 0.01 起步每 100 个 epoch 乘 1.5大概 300 个 epoch 后到达 1。这样做的原因是一开始就让判别器太强特征提取器会被逼疯导致特征崩塌。第三个是学习率。我用 AdamWbase learning rate 设 1e-4并且用了余弦退火。试过初始 1e-3模型在前 20 个 epoch 内就发散。少样本场景下数据集小batch size 也小我设的是 16大学习率很容易让原型估计在早期剧烈摆动。5.2 少样本场景下的一些反直觉发现如果我给新接触因果干预少样本学习的朋友提三个建议会是第一不要迷信更深的骨干网络。我在 ResNet-50 上试过5-shot 跨工况准确率反而比 ResNet-18 低 2 个百分点。原因还是样本太少深网络的特征空间维度太高容易把所有样本记住而不是泛化。ResNet-18 的特征维度 512 在这个任务里刚刚好。第二支撑集的选择不是随机的。实验中发现如果支撑集里的故障样本恰好都来自同一工况模型的性能波动非常大。我后面做了一个简单的启发式支撑集选取时尽量覆盖不同的工况簇。这在少样本评估里相当于作弊但我认为对于实际项目是可操作的——你在现场标注样本时多费点心思把不同转速、不同负载下的数据都标上几份模型部署后稳定很多。第三时频图参数对结果的影响比你想象的大。我试过窗长 128、256、512结果差异在 5 个百分点左右。窗长太小频率分辨率不够故障边频带糊成一团窗长太大时间分辨率下降短时瞬态冲击特征被平均掉。256 在我的数据上是最优的但建议你针对自己的信号采样率、故障特征频率范围多试几组。5.3 模型在实际设备的部署效果项目最后在一个小型电机实验台上做了验证。实验台的情况是一台新型号电机没有任何历史故障数据只有正常振动数据。甲方希望模型能在现场标注 5 个故障样本后就能识别出内圈故障、外圈故障和正常状态。部署时我做了三件额外工作用正常数据的时频图统计分布对特征提取器做了一次自适应归一化把模型在公开数据集上学到的 BN 统计量替换成现场数据的统计量。现场采集时刻意在不同的电机转速600rpm/900rpm/1200rpm下各采了一段正常数据和故障数据确保支撑集覆盖不同工况。部署后用真实故障数据电机人为注入故障后跑出来的数据测试最终准确率 91.7%而直接用公开数据集训练不做任何适配的模型只有 54.2%差距非常大。这种提升我不能说全归功于因果干预因为支撑集覆盖多工况本身就有很大帮助。但因果干预模块确实让模型在支撑集没有覆盖到的工况下比如 1500rpm也保持住了 82% 以上的准确率。这一点在现场很有意义——你不可能在每个转速下都准备故障样本。5.4 关于代码复现的一些补充说明PyTorch 版本我用的是 2.0CUDA 11.8训练时单卡 RTX 3090 就够用输入是 224×224 的时频图batch size 16单 epoch 很快。整个训练流程大概 200 个 epoch耗时约 20 分钟。如果你的显存不够可以把 ResNet-18 换成 ResNet-18-Light把中间层的通道数除以 2性能只会下降大约 1~2 个百分点但显存占用可以少 40%。我没有在这个模型里用任何滑动平均EMA或者知识蒸馏的技巧。有人可能会问加一个 EMA 的 teacher 模型会不会更稳我试过效果提升在 1 个百分点以内但实现复杂度上去了后面就没有在项目里保留。如果你想精简代码实现先跑通我上面描述的基础版本再逐步加功能这样排查问题会容易很多。最后再分享一个小技巧。如果准备在真实设备上部署这个模型建议保存模型的时候把训练阶段的工况簇中心也一并存下来。部署时每隔一段时间用聚类头算一下现场数据的工况簇中心和训练时的对比一下如果漂移超过了阈值说明设备工况发生了显著变化就该考虑重新标定模型或者做自适应。这个小功能在现场被维护工程师夸了好几次因为大部分人只会盯着准确率指标不会想到监控数据分布漂移这件事。因果干预不是万能的它解决的是虚假相关的问题但前提是你把因果图定义得足够合理。在我这个场景里设备结构、信号处理流程、故障机理都比较明确所以建模相对靠谱。如果你面对的是黑箱系统连故障机理都说不清楚那先别急着上因果干预老老实实把数据质量做好或许收益更大。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询