做工业设备健康管理或者产线质量检测的朋友,对“异音检测”这四个字应该都不陌生。老师傅凭耳朵听轴承转得顺不顺、压缩机喘不喘气,一听一个准,但让自动化系统接盘就麻烦了:设备型号不一样、转速负载天天变、车间里环境噪声还特别大,传统阈值和规则根本扛不住。这几年大家开始把深度学习的模型往这个场景里搬,可一搬又卡在选型上——CNN、Transformer、AutoEncoder这三类模型到底用哪个?它们分别解决什么问题?有没有一套能直接套用的判断逻辑?
这篇内容就围绕这三个模型在异音检测里的原理、适用边界和实际选型过程展开,把我做过的对比实验、踩过的坑、还有最后沉淀下来的选型规则一起写出来。不管是刚入门的小白,还是已经写了几个月训练脚本的工程师,读完应该都能对自己的方案有个更清楚的判断。
1. 把“异音检测”这个任务先翻译成人话
1.1 异音从哪来、长什么样
异音检测不是简单的“声音大不大”或者“声音像不像”,它的核心是捕捉设备运行状态偏离正常模式的那些频谱结构。常见的故障源包括轴承磨损、转子不平衡、结构松动、润滑不良、气阀泄漏、齿轮点蚀等等。不同故障的声学表现差异很大:轴承内圈剥落通常会产生周期性的瞬态冲击,反映在时频图上是一串短促的竖直条纹;齿轮咬合不良会诱发调幅边带;气阀泄漏则往往表现为宽频带的噪声抬升,且在特定频段出现集中能量。这些形态上的差异,决定了不同模型各有所长。
采集端还要注意一个很容易被忽视的问题:采样率和传感器位置。工业现场一般用16kHz或48kHz采样率,但设备的主噪声往往集中在几千赫兹以下,而某些冲击信号的高频成分可以延伸到10kHz以上。麦克风离设备太远,高频细节会先衰减掉;离太近,又会吃进大量气流噪声。我通常建议先做一次现场声学摸底,记录设备在不同转速、负载下的频谱形态,再决定麦克风布点和采样率,而不是一上来就直接套公开数据集里的参数。
1.2 传统方法为什么不够用,深度学习能接什么盘
传统做法主要是频谱分析加包络解调,配合一组专家规则或阈值判断。这种方案在小批量、工况稳定的场景下能跑,但一旦设备的转速变化、负载波动,或者车间里还有其他机器在运行,特征的方差就会迅速增大,固定阈值根本没法同时做到低误报和低漏报。还有一个痛点是非平稳的瞬态异音,你在频谱图上看得到,但很难用手工特征把它稳定地提取出来。
深度学习解决的是“从数据里学习正常模式或故障模式”的问题。它不要求人预先定义异音长什么样,而是从足够多的样本中自己归纳出规律。具体到模型选型,CNN、Transformer、AutoEncoder其实就是三种不同思路的落地:CNN靠局部卷积滤波器抓取频谱图中的局部纹理;Transformer通过自注意力建立整张时频图的全局依赖;AutoEncoder则只学习正常样本的分布,用重建误差来判断“没见过的东西”。这三条路线没有绝对的优劣,关键看你的数据形态和业务约束。
2. 三个模型逐个拆:原理、直觉、适用边界
2.1 CNN:用“看图找病灶”的方式找异音
CNN处理异音检测,最自然的做法是把Log-Mel谱图当作单通道图像,然后像图像分类一样做卷积、池化、全连接。卷积核在时频图上滑动,每次只观察一个局部窗口,这样设计的好处和它在图像上成功的原因一样:局部特征往往是判断类别的最强信号。
在异音场景里,CNN的局部感受野刚好匹配那些短时冲击型特征。比如轴承故障产生的瞬态冲击,在时频图上就是一个局部的竖条纹,3×3或者5×5的卷积核就能覆盖住。连续多层的叠加能逐渐扩大感受野,让模型从局部纹理过渡到更大的结构模式。工程实现上,我一般用类似“小ResNet”的结构:首层一个较大的卷积核做粗特征提取,后续叠加3×3卷积块,每个块里配BatchNorm和ReLU,最后用全局平均池化替代全连接层,能显著减少参数量,也降低过拟合风险。
CNN的短板在于它的感受野始终是受限的,想看到跨频段、长周期的整体关系,就得堆很深,或者用膨胀卷积、大卷积核来弥补。而且在实际项目中,如果异音更多体现在一种“整体结构偏离”而不是“局部突变”上,CNN容易把注意力落在一些局部噪声伪影上,导致误报。
2.2 Transformer:把整张谱图连起来看
Transformer引入异音检测的逻辑是:频率轴和时间轴上距离很远的位置,状态未必独立。比如轴承保持架故障会产生低频的调制周期,它同时作用于多个频段,局部卷积想看全这些关系,需要足够深的网络,但Transformer可以直接让任意两个位置互相“看见”。
实际操作的时候,通常把Log-Mel谱图切成固定大小的patch,展平成一串token,加上位置编码后送入标准Encoder。如果按ViT的思路,再加一个class token用来聚合全局信息。这种设计的优点是天然建模长程依赖,能捕捉谐波族之间的联动、跨时间的弱周期性。我在某些压缩机异音数据上观察过,Transformer对“多频段同时抬升”这类模式确实比CNN更敏感。
但Transformer不是免费的午餐。它的自注意力矩阵复杂度是序列长度的平方,谱图patch一多,显存和推理时间都往上涨。更关键的制约是数据量:从头训练一个Transformer做二分类,在异音检测这种通常只有几百到几千条样本的任务里,很容易欠拟合甚至训不收敛。我自己的经验是,要么借用预训练音频模型做微调,要么先用小的patch和浅层结构做消融,不能一上来就套大模型。
2.3 AutoEncoder:不学“什么是异常”,只学“什么是正常”
AutoEncoder的思路完全另走一条路:它不关心异常样本长什么样,只学习正常样本的压缩-重建过程。训练阶段只用正常声音,让编码器把输入映射到低维瓶颈向量,再由解码器还原。推理阶段计算重建误差,正常样本误差小,没见过的异常样本误差大,设定阈值即可判断。
这个思路对异音检测有一个巨大的吸引力:故障样本永远是最难收集的。你不可能为了训练一台设备的故障检测模型,就真的把轴承跑坏很多次。很多时候项目启动时手里连一条真实的异常录音都没有,这时只有AE类方法能开工。具体实现上,卷积自编码器是主流,瓶颈维度一般在32到128之间,重建损失可以用L1或L2,也可以加入频谱梯度损失(spectral convergence loss)来约束重建出的时频图不仅数值接近,结构也更接近。
AE的坑也不少。它最大的毛病是误报容易集中在“正常样本覆盖不到的变化”上。比如设备刚开机、负载突变、环境温度变化,这些工况变更同样会让频谱整体偏移,AE很可能把这种变化当成异常。所以训练集必须尽可能覆盖所有正常的工况变化,这一点做不好,阈值怎么调都压不住误报。
2.4 一张表看清三者定位
| 维度 | CNN | Transformer | AutoEncoder |
|---|---|---|---|
| 监督类型 | 有监督/弱监督 | 有监督/自监督预训练 | 无监督 |
| 数据需求 | 需要正常+异常样本 | 需要大量样本,最好配合预训练 | 只需正常样本 |
| 强项 | 局部冲击、纹理型异音 | 跨频段长程调制、复杂结构 | 正常流形建模,故障样本稀缺时首选 |
| 弱项 | 全局建模能力有限 | 数据少时难训练,计算量大 | 对工况变化敏感,容易误报 |
| 可解释性 | Grad-CAM热力图 | Attention图 | 重建误差热力图 |
| 推理速度 | 快 | 较慢 | 中/快 |
| 典型落地角色 | 故障分类、初筛 | 复杂场景精细识别 | 基线过滤、无监督预警 |
选型的第一步不是比指标,而是先回答三个问题:我手上有没有正常样本之外的故障样本?如果有,标注到不到位?如果只有正常样本,就老老实实从AE开始。前两个问题的答案决定你是走有监督路线还是无监督路线,第三个问题决定具体模型结构。
3. 实操流水线:特征、实验设计、训练配置
3.1 先规范数据:采集、切样本、打标
数据规范度决定项目上限。我之前做过一个压缩机气阀项目,第一版模型指标看着还行,部署到另一条产线上直接崩了,原因是训练数据只录了同一车间同一工况的声音。后来重新采集时要求录音覆盖三台同型号设备、两个班次、不同负载率,还把周边产线的环境噪声一并录进去当作正常样本的背景,这才把跨线性能拉回来。
采集时长上有一个经验值:原始录音总时长至少是单个样本时长的十倍以上。如果你打算切成30秒一段做训练,至少要录超过300秒的连续音频,否则相邻片段高度重叠,训练集和验证集之间会有信息泄漏,指标虚高得厉害。打标环节也要注意,最好两个工程师独立标注同一批片段,如果两人的一致性低于90%,先别急着训模型,说明“正常”和“异常”的定义本身还有分歧,模型学出来的边界也没法用。
3.2 特征工程:Log-Mel谱还是要做的
虽然叫“端到端”,异音检测里直接拿原始波形训练的模型并不多,原因很简单:原始波形的采样数据量太大,且直接映射到故障状态的关联性太稀疏。常规做法是分帧加窗提取时频特征。我常用的参数是:预加重系数0.97,窗长25ms,帧移10ms,FFT点数1024,Mel滤波器组数量64或128,取对数。
市面上MFCC也用得不少,但MFCC做了倒谱截断,丢掉了很多异音检测需要的高频细节,所以我在做故障异音时很少用MFCC做主要特征,Log-Mel更稳妥。特判场景下可以考虑CQT(恒Q变换),它对旋转机械的谐波结构表征更自然,不过计算量偏大,一般先当备选。特征标准化要做在样本级,也就是每条样本自己做mean和std归一化,而不是对整个训练集做全局统计,否则部署时来了新开机状态的数据,统计量对不上,效果就漂移。
3.3 模型训练细节从哪抄作业
训练配置是耗时最少但影响最大的环节。优化器用AdamW,学习率1e-4到3e-4,weight_decay设置1e-4左右,这在PyTorch里对应优化器的weight_decay参数,本质上就是L2正则化。很多人低估了L2在AE训练中的作用,AE的瓶颈如果不够紧,模型会把噪声也“背”下来,正则化能强迫它只保留正常样本的共性结构。训练轮数设置50到100轮,加早停,早停的patience给10轮就够。
数据增强方面,SpecAugment是一类很实用的方法:在特征图上随机遮盖若干时间条带或频率条带,强制模型不依赖单一频段。相比之下在原始波形上加高斯噪声通常不是好选择,因为工业现场信噪比本来就低,再加噪声反而把弱故障特征淹没了。Mixup在异常检测这种任务上效果不太稳定,分类任务可以直接用,但AE训练时mixup会同时改变“正常样本”的分布定义,容易引入偏差,我一般不推荐。
关于深度学习环境配置,这里有句实在话:比起模型结构,项目卡在环境上的时间往往更长。尽量统一CUDA、PyTorch和显卡驱动的版本,跑对比实验时锁定同一个镜像环境,否则换了环境后指标波动可能比模型差异还大,造成选型误判。
3.4 一份可跑的对比实验清单
对比实验的表格设计要有固定的记录维度:模型变体、参数量、输入特征、训练数据规模、单条推理耗时、AUC/pAUC。我建议每次只改一个变量,比如固定Log-Mel特征和增强策略,先跑AE基线,再跑CNN,最后跑Transformer,避免“换模型的同时也换了特征”这种混变量操作。
阈值设置上有个常规做法:先用验证集里正常样本的重建误差分布取99%分位数作为初始阈值,再根据业务对漏报和误报的容忍度上下调整。有标注数据时,可以直接遍历阈值选最大化F1的那档;但是如果业务更看重低误报,就用pAUC这类指标来指导选型,它只统计低假正率区间下的性能,比AUC更贴合工业报警场景。
4. 选型决策:什么场景选什么模型(我的判断规则)
4.1 三个常规场景的选中逻辑
第一个场景:你有几百条带标签样本,其中明确包含故障样本,且故障类型相对单一。这种情况我通常先跑一个AE当基线,再上CNN做分类。CNN在这个体量下一般精度够用,推理速度也快,产线上用树莓派或者边缘盒子都能跑得动。实际经验里,CNN做好后AUC普遍能到0.9以上,变压器这类“重武器”未必有优势。
第二个场景:故障样本几乎没有,连一条真实的异常录音都拿不到。这个约束直接锁死了有监督路线,只能做AE/VAE。此时的重点不是换模型,而是尽量扩大正常样本的工况覆盖,并把阈值留足余地。VAE相比AE多了一个潜在分布的约束,重建误差分布会更平滑,误报概率略低,代价是训练稍不稳定,需要多跑几次种子的均值。
第三个场景:你需要同时区分多种故障类型,比如轴承磨损、齿轮点蚀、转子不平衡。在标注足够的情况下,先把AE当预筛器,把明显正常的数据过滤掉,再用CNN或Transformer做多分类。标注不够时用AE的潜向量特征做聚类或浅分类,比直接训练一个大模型稳妥得多,因为潜向量本身就是对正常分布的偏离度的压缩表征。
4.2 组合与级联才是实战王道
不少团队把选型理解为“选一个模型解决所有问题”,实际落地中我越来越倾向做一个两级分流:第一级AE总体打分,先判断“当前状态是否偏离正常”;只有偏离的片段才进第二级,由CNN/Transformer分类器决定是报警、警告还是忽略。这样做的原因有两个:一是便宜模型先过滤掉绝大多数正常样本,减少了后级高算力模型的调用次数;二是两级的错误模式不同,AE容易对工况变化误报,CNN对局部冲击更灵敏,级联在一起能互相兜底。
如果业务要求在边缘设备上实时推理,还要重新算一遍算力账。CNN量化后跑ONNX/TensorRT非常顺畅,参数量可以压到几百万以内;AE也不难部署;Transformer则要谨慎,先做小模型加剪枝,仍然达不到帧率约束的话,宁可维持“AE过滤+CNN细分”的组合方案。
4.3 部署侧的考虑:延迟、显存、可解释性
部署侧的三个硬指标是延迟、显存和可解释性。延迟不必多说,工业报警通常要求秒级内反馈,模型单条推理控制在几十毫秒级别才安全。显存在边缘盒子上经常只有1到2GB,大模型根本塞不进去。可解释性这个问题容易被技术团队忽略,但现场维护工程师很看重:你模型说这台设备异常,凭什么信你?
CNN可以用Grad-CAM输出热力图,指出时频图的哪个区域贡献了异常判断;Transformer能输出attention map,展示模型重点关联了哪些patch;AE反而给的是最直观的东西——重建误差热力图,差在哪、差多少一目了然。我习惯把AE的误差图和CNN的Grad-CAM叠加展示,如果两边的异常区域在时频图上高度重合,现场工程师也会更愿意信任这个报警。
5. 项目里真实踩过的坑(FAQ式避坑清单)
5.1 高频翻车现场速查表
| 问题 | 现象 | 根因 | 处置建议 |
|---|---|---|---|
| 跨设备性能崩 | 这台设备效果好,换一台同型号就误报 | 模型学到单台个体特征而非故障共性 | 训练集覆盖多台设备;或做设备级微调 |
| 背景噪声误报 | 附近其他设备声音、人声导致误报 | 正常样本没包含环境干扰音 | 把环境噪声/干扰音纳入正常类别 |
| 低信噪比失效 | 实验室效果稳,现场效果差 | 训练数据信噪比与部署现场不一致 | 采集时贴近现场信噪比,避免用静音库 |
| Transformer不收敛 | loss来回跳,指标上不去 | 学习率过大、无warmup、数据太少 | 先用小模型消融;加warmup;降低lr |
| AE过拟合正常集 | 训练集误差低,验证集正常样本误差高 | 模型记住了训练样本个体而非正常分布 | 增加正常样本的工况种类;加L2正则 |
| 阈值调不动 | 怎么调都误报/漏报 | 真正瓶颈在训练集没覆盖正常变化 | 扩充正常样本,而不是继续调阈值 |
| 推理延迟超标 | 部署帧率达不到要求 | 模型过大或feature计算过重 | 模型量化裁剪;或换级联方案 |
第一个坑值得多解释一句:同样的设备型号,不同个体之间的频谱差异可能比故障状态之间的差异还大。你在一台设备上训出来的模型,迁移到另一台设备上,误报率升高是常态。实操经验是多台设备数据混合训练,再给每一台保留一个轻量微调的阶段,这样才能在“个性”和“共性”之间取得平衡。
第二个坑同样隐蔽:车间里不止有目标设备,还有风扇、行车、隔壁产线的冲压声。这些声音如果不出现在正常样本里,模型就会把它们当成“没见过的东西”,误报自然压不住。正确做法是采集时把典型干扰源录进来,加进正常样本,甚至可以做一点人声抑制的预处理,让模型关注设备本身的频段,而不是所有声音成分。
5.2 几条没有人写在算法文档里的经验
关于AE阈值设定,我在实际项目里的习惯是不要在训练集上选阈值,而是在部署现场采集一段没有异常报警记录的历史音频,标成“现场正常”,在这个集合上定报警线。训练集里录的“正常”和现场实际运行的“正常”永远有差异,用现场数据定阈值,误报率能降低一大截。
关于自然样本的划分:不要随机打乱划分训练集和验证集。异音检测的数据采集通常是同一时段连续录的,随机打乱会让同一条设备状态的一部分进训练集、一部分进验证集,指标虚高。我用的是按设备、按时间戳切分,验证集用另一台设备或另一天的数据,这样评估出来的才是模型在真实场景的泛化能力。
关于人工监听:深度学习也好,特征工程也好,最后模型给出的报警,我都会让现场经验最丰富的老师傅去听回来。不是为了验证算法,而是为了让阈值、误报率这些抽象指标变成老师傅口中“这个确实不对劲”还是“这声音平时也这样”的实感。模型的注意力热力图和老师傅的经验判断对齐几次之后,整个系统的调试速度和可信度都会明显变好。
我个人做了几个项目之后最大的体会是:模型选型这件事,85%的场景一个AE基线加一个CNN分类器就能打穿,Transformer在数据量不够时大概率比CNN和AE更差。与其纠结要不要上最新的架构,不如先把异音的形态定义清楚,把正常样本的工况覆盖做扎实。模型只是最后的两成工作量,前面八成在数据和特征这两件事上,做对了,模型跑起来只是时间问题。