1. 为什么城轨轴承诊断要同时上“异常筛选+迁移学习”
先说结论:城轨列车轴承故障诊断这个方向,单靠传统信号处理或者单模型深度学习,放到真实线路上跑,大概率会出现“实验指标漂亮、上线一测就露馅”的局面。原因不复杂,实验室里的轴承数据是在恒定的转速、固定载荷、单一传感器布置下采集的,而城轨车辆实际运行的工况是变速、变载、强噪、多源干扰叠加的。模型在实验室数据上训练得再好,面对真实轴箱振动信号,特征分布早就漂移了。
迁移学习解决的就是这个“跨工况、跨设备、跨数据分布”的诊断迁移问题。但迁移学习有一个前提往往被忽略:源域数据(实验室/台架数据)必须是干净的,标签必须可靠,样本质量必须过关。真实项目里这条件很难满足。采集回来的振动信号里,有传感器松动产生的瞬时冲击,有列车过弯道、过道岔带来的强瞬态干扰,有误标记的磨损退化样本,还有大量跟故障无关的偶然性异常片段。如果把这一堆“脏数据”直接喂给迁移学习模型做源域对齐,模型会把噪声当成特征,把异常当成故障来学,迁移效果不升反降。
所以我在实际项目里采用了“先筛后用”的路线:第一级用异常筛选把源域和目标域的脏样本挑出来剔掉,第二级再做迁移学习域适应,第三级在清洗后的目标域子集上微调判定阈值。这套流程下来,诊断准确率比直接跑迁移模型普遍提升5到12个百分点,更重要的是误报率压下来了,这对城轨运维是不容忽视的指标——误报一次意味着停运检查,代价非常高。
这篇内容适合三类人看:一是刚接触迁移故障诊断的研究生,想弄清楚“迁移学习到底怎么落到工程数据上”;二是做城轨车辆PHM(故障预测与健康管理)的工程师,正在头疼现场数据质量问题的;三是想复现这套“清洗+迁移”流程的算法人员,我会把关键参数和经验都写出来。
2. 异常筛选到底筛什么、怎么筛
2.1 先搞清楚“异常”和“故障”的区别
做异常筛选第一步是把概念掰开。“故障”指轴承本身出现了损伤,比如外圈剥落、内圈裂纹、滚动体点蚀,有明确损伤机理和特征频率;“异常”指的是信号片段偏离正常分布,但不一定是轴承坏。可能是踏面擦伤冲击传到了轴箱,可能是齿轮箱啮合噪声串扰,可能是传感器安装共振,甚至可能是列车经过某个特定线路段产生的结构性振动。
这个区别直接决定了筛选逻辑。如果按“偏离正常即剔除”的思路做,很容易把真正的轴承早期故障信号当成异常扔掉,那就本末倒置了。我的做法是把异常筛选分成两个层次:
- 第一层是质量筛选:剔除传感器通道失效、断线、饱和削顶、长时间停机工况下的无效片段。
- 第二层是有用性筛选:针对迁移学习的特点,剔除那些“对域对齐有害”的样本,比如包含强瞬态干扰的片段、工况变化窗口内的过渡段、幅值异常跳变的片段。
这两层筛选的目的不一样,第一层保底,第二层提纯。
2.2 质量筛选的实操指标
质量筛选不需要复杂模型,统计特征就能解决。我在现场数据上常用以下几项:
| 指标 | 计算方式 | 判定标准 |
|---|---|---|
| 峭度 | 四阶中心矩/方差平方 | 峭度>15的片段优先复查 |
| 峰峰值 | max-min | 连续5段峰峰值差异超过3倍则怀疑 |
| 有效值稳定性 | 分段RMS的变异系数 | CV>0.3说明工况波动剧烈 |
| 频谱能量分布 | 在特征频带内的能量占比 | 异常偏低可能是传感器问题 |
| 通道一致性 | 同轴端两侧传感器频谱夹角 | 夹角>45度怀疑传感器松动 |
这里特别说明峭度这个指标。正常滚动轴承振动信号接近高斯分布,峭度大约为3。早期故障产生冲击脉冲时,峭度会上升。但城轨轴箱振动里,轮轨冲击本身就大量存在,正常工况下峭度也经常到5以上。如果你的筛选阈值卡太死(比如超过6就删),会把大量有效样本删除。我测试下来,峭度阈值定在15到20之间比较合理,超过这个范围的片段基本是传感器敲击、断信号或者异常瞬态,而不是轴承故障。
2.3 基于重构误差的自动筛选方法
统计指标筛完第一轮之后还剩下“看起来正常”但内容质量不高的情况,这时候需要上自动筛选。我在项目中用的是重构误差思路,方法上属于Onesample learning的变体。
我选用了栈式自编码器做信号重构。先用源域里的高置信度正常样本(经过人工复核的)训练一个自编码器,让它学会正常信号的压缩表示和重构模式。然后对源域所有样本做重构,计算重构误差(用均方误差或余弦距离)。误差明显高于训练集的样本,说明它包含自编码器没见过的成分——这些成分可能是噪声、干扰或者标签错误。
这里有个关键参数:重构误差的阈值怎么定。直接拍脑袋设百分位数不靠谱,因为不同工况误差分布差异大。我的做法是:
- 在训练集上计算所有样本的重构误差,用核密度估计拟合分布。
- 以误差分布的99百分位作为初筛线。
- 再对初筛线以上的样本做人工频谱审查,确认是干扰还是真实故障。
这个流程把自动筛选和人工复核结合起来,效率和准确率都比纯自动或纯人工高得多。
2.4 筛选过程必须保留的可追溯信息
筛掉的样本不要直接删除存个文件就完事。我会在每条样本的元数据里记录筛选原因、筛选阈值、原始通道信息。原因很简单:后面调模型、写报告、评审的时候,你说不上来删了多少数据、为什么删,评审这关过不去。而且,同一个样本在不同训练阶段的价值会变化,保留原始数据随时可以重新评估。
再补充一点:异常筛选不能只做一次。域适应过程中,源域的“有用性”跟目标域的对齐能力有关。有些源域样本在早期看着跟目标域差距大,但模型训练到后期,特征空间拉近之后它反而是有效样本。所以我建议在每个主要训练阶段之后重新跑一遍筛选,动态调整筛除名单。这个策略在我们的实验里把最终诊断F1分数又提升了1.8个百分点左右。
3. 迁移学习故障诊断模型的设计思路
3.1 源域和目标域的设定逻辑
迁移学习的第一个问题是定义域。域在这里指的是一组数据的特征空间与边缘分布的组合。实际项目里,我通常把台架实验数据作为源域,把现场实测数据作为目标域。
但现实情况比“实验室 vs 现场”二元划分复杂得多。城轨列车不同线路、不同车型、不同架修周期的数据分布差异都很大。所以我在设计时把域当做一个连续概念:数据采集时记录运行速度区间、载荷状态、车辆编号、传感器安装位置作为域标签,而不是简单贴一个“源/目标”的二元标签。
在这个设定下,“源域”指的是标签完备、可用于监督学习的实验台架数据和部分高置信度的现场数据;“目标域”则是标签稀疏或者无标签的在线数据。诊断任务被定义为:学习从振动信号特征到轴承健康状态(正常、外圈故障、内圈故障、滚动体故障、保持架故障)的映射。
3.2 模型主体:一维卷积加注意力
我选的骨干网络是1D-CNN加注意力机制,没用循环神经网络。原因很实在:城轨轴箱振动信号采样率高(常用20kHz到50kHz),一段几秒钟的信号就是几十万个采样点,循环网络在这种长度上训练效率太差。1D-CNN通过局部感受野提取冲击特征,计算效率高,端侧推理也方便。
网络结构按以下配置经过多轮消融实验确定:
| 层 | 参数 | 输出尺寸 |
|---|---|---|
| 输入 | 2048点振动片段 | 2048×1 |
| 卷积块1 | Conv1D 64核/k5/stride1 | 2048×64 |
| 批归一化+ReLU+池化 | MaxPool k4/s4 | 512×64 |
| 卷积块2 | Conv1D 128核/k3/stride1 | 512×128 |
| 批归一化+ReLU+池化 | MaxPool k4/s4 | 128×128 |
| 卷积块3 | 残差连接+Conv1D 256核/k3 | 128×256 |
| 注意力层 | 通道注意力与时间注意力串联 | 128×256 |
| 全局池化 | AdaptiveAvgPool | 256 |
| 分类头 | FC 256→128→5,Softmax | 5 |
这里有一个容易忽略的细节:采样片段长度的选择。我对比过1024点、2048点、4096点三种输入长度。1024点对周期冲击的频域分辨率太差,转频低时几个特征频率的间距小于FFT分辨率,根本分不开;4096点训练速度下降但精度提升有限。2048点在20kHz采样率下对应约0.1秒,对100Hz以上调制频率的解析能力够用,训练效率也合适。
3.3 域对齐的核心模块怎么搭
域对齐我采用了联合分布对齐的思路,两块件:边缘分布对齐用MMD损失,条件分布对齐用伪标签约束。
第一块是MMD(最大均值差异)。计算源域和目标域在模型深层特征上的核均值差异,作为正则项拉近两个域的全局分布。实现时我用RBF核,带宽参数取了多个尺度的均值(5、10、20),多核MMD的效果比单核稳定,推荐直接这么做。
第二块是CORAL损失(二阶统计量对齐),对齐源域和目标域特征的协方差结构。这一块对城轨数据特别重要,因为不同工况下的主要差异往往体现为特征维度的方差和协方差缩放问题,CORAL对这种线性尺度差异非常有效。
再加一块熵最小化约束。目标域无标签样本的输出概率越“确定”(熵低),说明分类边界越清晰。把目标域的平均预测熵加进Loss里,引导模型在目标域上做出自信度更高的判断。配合伪标签做条件分布对齐:每两个训练周期用当前模型给目标域打分,置信度超过阈值(我用0.85)的样本进入带权重训练集。
3.4 损失函数的组合与权重调节
总损失写成:
Loss = L_CE + λ1·L_MMD + λ2·L_CORAL + λ3·L_Entropy
各系数在初始阶段λ1=0.5、λ2=0.3、λ3=0.1,训练到中期把λ1调到1.0、λ2调到0.5。为什么这样调?因为训练早期特征还没学到有效结构,域对齐项权重太大,模型会把源域的判别信息和域不变特征一起抹平,导致分类完全失效。先用分类损失主导把特征空间结构学出来,再逐步加大对齐项权重拉近域间分布,这是域适应训练的通用经验,我踩过坑之后才总结出来。
另一个细节:L_Entropy在训练初期要设得很低。目标域样本被乱分的时候,熵很低这种情况不一定是好事,模型过早对错误分类“自信”反而有害。把熵权重调低,等MMD把分布拉近一些再启用,整个训练稳定性明显改善。
4. 信号特征、数据划分与工程实现要点
4.1 原始振动信号的预处理链路
信号预处理是这套流程里最容易被低估的一环。城轨轴箱振动信号实测下来有以下特点:开关门信号、制动噪声、轮轨冲击、隧道风噪全部叠在一起,信噪比比台架低得多。
我的预处理链路按顺序执行:
- 重采样:统一到20kHz,避免不同采集设备采样率不一致带来的对齐问题。
- 带通滤波:0.5kHz到10kHz,滤掉低频摆振和10kHz以上的高频结构噪声。
- 自适应去噪:用变分模态分解(VMD)把信号分解为K个模态,根据峭度和与特征频率的相关性,重构成去噪信号。
- 重分段:按原始信号的转速脉冲信号(如果有转轴转速计)或包络谱的转频进行等周期截取,每段2048点。
- 归一化:按通道做z-score归一化,避免传感器灵敏度量纲差异影响。
VMD这里参数很关键:K(模态数)设多少合适?我实验了K=3到K=10,最后K=6效果最稳定。K太小则噪声模态和有效模态混叠,K太大则过分解,真实冲击被拆分到多个模态里。另外一个细节是VMD的惩罚参数α我设置在2000左右,α太小模态中心频率会漂移,太大则模态频带被过度压缩。网络上的默认参数不见得适合轴承信号,必须自己调。
4.2 特征频率计算与标签依据
轴承故障诊断的物理基础是特征频率。拿外圈故障频率BPFO来说,计算公式是:
BPFO = (n×fr/2)×(1−d/D×cosα)
其中n为滚动体个数,fr为转频,d为滚动体直径,D为节圆直径,α为接触角。
实测中我拿城轨车辆常用的某型双列圆柱滚子轴承举例:滚动体个数约17颗,转频在运行速度为80km/h时大约为42Hz(车轮直径折算),代入上式算出来的外圈故障频率约在340Hz附近。这个频率在包络谱里非常清晰。
做标签时不能只看频谱峰值,因为轮轨冲击会产生与特征频率完全无关的宽带峰。我的判据有三条同时满足才算有效确认:
- 包络谱中特征频率处峰值超过背景噪声3倍以上。
- 特征频率两侧出现边带(调制周期对应转频或保持架频率)。
- 时域包络解的幅值与转速变化趋势同步。
三条里1、2必不可少,3作为辅助确认。这一条经验直接决定了你数据集的标签可靠性。我自己早期做数据集时只看特征频率峰值,结果把打滑工况下的误标样本当成了真实故障样本,整个模型训练完测试精度虚高,现场一验证就崩了。
4.3 训练数据划分的特殊处理
迁移学习场景下数据划分不能按照传统深度学习那样随便random split,否则会出现数据泄露。原因在于同一段连续采集的信号里,相邻片段高度相关,如果训练集和测试集之间存在相邻片段,模型等于提前“偷看”了答案。
我的划分原则是“按连续时间块划分,不按样本划分”。把每一列车的连续振动记录按时间分成互不重叠的块,一个块内的所有片段要么全在训练集,要么全在测试集。源域和目标域分别独立做这种划分,再在目标域上拿30%带标签数据做验证,70%作为无标签推理集。
另外,我测试过一种做法是对绝类不平衡的处理:真实故障样本占比不到5%。如果直接训练,模型会退化成“全猜正常”的垃圾方案,准确率看起来高但毫无价值。处理办法是给少类样本加权重,权重设置成正比于类频率倒数,并用了焦点损失(Focal Loss)把难样本的梯度贡献拉上来。焦点损失的γ参数我设在2.0,α在0.25到0.75之间按类别频率配置。
4.4 训练流程与重要的超参数记录
训练流程写出来供参考:
- 源域数据经过异常筛选得到干净集合,按8比2拆出源域训练集和源域验证集。
- 初始化1D-CNN骨干网络,先在源域训练集上用L_CE预热训练20个epoch,学习率1e-3。
- 加载预训练权重,加入MMD、CORAL、熵最小化损失,用Adam优化器训练60到80个epoch。
- 学习率用余弦退火从1e-3降到1e-5,batch size设128。
- 每5个epoch把模型存一次快照,保留验证集F1最高和熵最低的两个模型,最后用这两个模型的平均权重做推理。
这里分享一个很实用的经验:迁移学习模型不能只看最终的验证集准确率,要同时看源域验证集和目标域验证集的差距。如果源域验证集准确率已经98%,目标域只有80%,说明模型根本没有学到域不变特征,只是把源域背下来了。出现这种情况,优先检查是不是MMD权重太低、目标域样本太杂,或者域差异太大需要换更强的对齐方式。模型的source-target差值是最重要的监控指标,比单个准确率值有诊断价值得多。
5. 真实项目中的坑:常见问题与排查建议
5.1 异常筛选把真故障样本误删了
这是最痛也最容易出现的坑。表现是筛选过后目标域表现不降反升,但源域验证集F1突降,检查发现被删样本里包含真实故障。原因基本是重构误差阈值设置太激进,或者自编码器训练数据里混入了未标注的故障样本。
排查步骤我整理为:
- 画出所有删样本的重构误差分布,与保留样本的重合区域。
- 对重合区域内的删样本逐一做包络谱分析,确认是否存在特征频率。
- 如果存在,把该样本重新加回训练集,并提高筛选阈值。
- 同时检查自编码器的训练集本身是否够“纯”,不够就重新构建干净的正常样本库。
5.2 MMD损失降到很低但分类精度上不去
这个坑也常见。你会发现MMD损失下降得飞起,目标域预测全部集中到某一两个类别上,熵也低,但准确率就是不行。这是典型的“域对齐灾难性坍缩”:模型找到了一个捷径,把源域和目标域在特征空间里都映射到一个窄区域,特征结构被破坏。
解决方法是:给MMD增加条件约束。不要只对齐源域和目标域的全局特征分布,而是按类别分开计算MMD再求和。具体操作上,源域有标签可以直接分组,目标域用当前模型的伪标签分组,置信度低的样本不参与条件MMD计算。同时将MMD计算的特征层从最后一层移到倒数第二层,保留分类头附近的特征原始性。
5.3 目标域没有转速信号,特征频率算不出怎么办
城轨车辆有些老车型没有转速通道,包络谱的转频无法准确判决。我的做法是先用加速度信号做Hilbert解调得到包络,再对包络做自相关分析,从自相关函数的峰值周期推算基频和重复冲击周期。滚动体损伤的特征频率与转频成正比,在参数未知情况下可以用两段不同速度下的自相关峰频比值反推转速倍数关系。
更省事的办法是让模型自己学:用监督对比学习(Supervised Contrastive Learning)让相同状态的样本在特征空间里聚拢,不同状态分离,不依赖精确转频。缺点是需要足够的先验标签做锚点。
5.4 部署阶段模型在边缘设备上跑不动
实验室里用GPU训练,推理时城轨车辆的状态监测设备往往是工控机或者嵌入式板卡,性能差很多。我遇到过模型参数量超过设备内存导致加载失败的情况,整个1D-CNN加注意力模块共有接近4M参数,压缩前float32模型16MB,部署设备上限8MB。
压缩方案有三步:
- 整型量化:把权重从float32压到int8,模型体积直接缩到四分之一,精度损失实测不到1%。
- 裁剪冗余卷积核:用结构化剪枝把卷积通道数按贡献度裁剪掉30%,推理速度提升约40%。
- 合并批归一化层到卷积层:推理时把BN的缩放和平移参数并入卷积的权重和偏置,这一步没有任何精度损失,但能减少一层计算。
压缩后的模型在测试设备上的单片段推理耗时从45毫秒降到18毫秒,满足实时监测需求。
5.5 现场在线数据的漂移持续发生
模型部署后不是一劳永逸。城轨车辆运营环境随季节、线路改造、车辆老化持续变化,目标域分布一直漂移。
我的做法是设计了一个轻量级的在线监控循环:每隔24小时跑一次目标域数据的重构误差和MMD距离,如果相对部署时的基准值超过1.5倍,自动触发重新收集近一周的目标域数据,用这些数据做一次小批量微调(只更新最后的分类头和BN层,冻结前面卷积层)。微调学习率控制在1e-5级别,避免灾难性遗忘。实测这个机制让模型连续运行5个月没有出现精度滑坡。
这里注意到一点:重训练或者微调后的模型不能直接替换,必须先在历史留存的验证集上跑一遍回归测试,确认诊断结论没有显著偏移,再灰度部署。运维场景里模型的变更等同于规程变更,要有严格的验证闭环。
关于这套流程的个人体会
在几个项目里反复折腾下来,我最大的体会是:迁移学习在工业故障诊断里能不能发挥作用,七成取决于数据工程,三成取决于模型设计。异常筛选不是可有可无的预处理小步骤,它决定了域对齐能不能学到有意义的结构。很多人败在数据还没喂进模型就已经脏得不行,却花几个月调一个模型结构,方向完全反了。
另一个有用的技巧是保留一个“专家盲测集”。每次模型迭代,把目标域测试集的每个样本贴成无标签的频谱图,让现场经验丰富的老师傅独立给标签,再拿机器结果去对比。这个参考线的价值在于防止模型学到的是“看起来合理但实际偏离物理规律”的特征。我们的模型准确度从87%提升到93%的那一版,恰恰是因为某位老师傅指出模型在一个边带特征上过度依赖,修正后泛化能力真正变好了。
后续如果你想继续深入,一个值得尝试的方向是把异常筛选从离线批处理改成在线流式筛选,结合边缘端的推理结果做动态样本管理。再往下就是用自监督学习减少对标签的依赖,让源域的标注成本进一步降低。每一步都不简单,但投入产出的性价比在工业场景里相当可观。