ELAI S.r.l.

当传感器误导 AI:为什么快速振动看起来很慢

通过可复现实例,解释为何 700 Hz 会看起来像 300 Hz,以及嵌入式系统中的采样、信息丢失和抽取前滤波。

当传感器误导 AI:为什么快速振动看起来很慢

问题出现在模型之前

电机正在振动,一个小设备尝试识别异常。系统记录到 300 赫兹峰值,也就是每秒三百次振荡。能因此断定电机真的存在这种振动吗?未必:采样不合适时,700 赫兹分量可能留下完全相同的数字轨迹。如果没有其他信息,即使非常准确的 AI 模型也无法区分以同样数字呈现的两种原因。

本文的问题是:把物理信号送入嵌入式系统,也就是集成在设备中的计算机时,如何保留有用信息?我们从两条简单波形开始,证明它们为何变得无法区分,再构造一个在减少样本之前使用的滤波器。同时考察代价:延迟、内存和运算。所有信号及数值结果均为合成、可复现的内容;没有测量电机、开发板或 EL-AI 产品。

采样意味着隔一段时间看一次

加速度计可以产生随时间变化的信号。模数转换器,常缩写为 ADC,将它表示为离散时刻采集的数字。若采样率 f_s 为每秒 1,000 个样本,就是每毫秒观察一次。两次观察之间发生的事情没有被直接保留。问题不仅是每个数字有多少位:即使数字无限精确,观察过于稀疏也会让动态过程的描述产生歧义。

为隔离这一现象,使用单位幅度、初相位为零的余弦振荡。频率 f 表示每秒周期数,t 是秒为单位的时间,n 是整数样本索引。代入 t = n/f_s,就只在可用时刻计算波形。这里圆括号表示连续时间,方括号表示数字序列;它们不改变传感器物理,只明确我们在观察什么。

x(t) = cos(2π f t) x[n] = cos(2π f n / f_s)

两种频率,同一序列

令 f_s = 1,000 Hz,比较 f = 700 Hz 与 f = 300 Hz。一毫秒内,第一条波走 0.7 圈,第二条走 0.3 圈。余弦对正负相反的角度取相同值,加上整数圈也不改变结果。正是这两个性质,而不是软件缺陷,让样本相同。下面的推导对每个整数 n 都成立,不只是图中几个点。

cos(2π · 700 n / 1000) = cos(2π n − 2π · 300 n / 1000) = cos(2π · 300 n / 1000)

这就是混叠:不同物理频率在采样序列中具有同一身份。对 1,000 个样本进行数值核对,最大差约为 1.27 × 10⁻¹²,来自计算机有限精度;数学上差为零。改变初相位可能改变混叠的符号或相位,但不会消除一般性的歧义。如果引入外部假设,比如已知不存在高于 400 Hz 的频率,就能排除部分解释。然而这是额外信息,并非从这些样本恢复的信息。

f_s/2 称为奈奎斯特频率。要无混叠表示任意带限信号,最高频率必须低于该阈值;恰在边界上,某些相位会出问题。不过,“有用信号是 300 Hz”不等于“全部信号都低于 500 Hz”。超过阈值的干扰和谐波仍会进入转换器。因此真实系统也必须了解并限制那些原本不想测量的成分。

为什么事后滤波可能已经太迟

假设已经以 1 kHz 采集,再应用保留 300 Hz 的数字滤波器。它也会保留来自 700 Hz 的贡献,因为后者已经叠到同一组样本上。若去掉 300 Hz,就会一起去掉两种解释。区别一旦丢失,滤波器无法判断原来是哪一种。因此保护必须放在产生歧义的操作之前:首次采样要在 ADC 前,后续降低数字采样率也要预先处理。

本实验改为从每秒 4,000 个样本开始:300 和 700 Hz 都低于 2,000 Hz,仍可区分。随后只想给模型每秒 1,000 个样本。每四个保留一个,称为 M = 4 的抽取。不先滤波就这样做,会重现前面的问题。中间滤波器必须削弱在新采样率下会变得模糊的成分,同时保留所需频带。

构造一个可核查的滤波器

使用 FIR,即有限冲激响应滤波器:每个输出是有限个近期样本的加权和。权重 h[k] 表示每个样本的贡献。这不是训练出的神经网络,而是明确选择低通响应,保留慢一些的振荡并削弱快一些的振荡。求和公式同时说明计算和成本。L = 129 个系数时,直接求值需要 129 次乘法及相加。

y[n] = Σ(k=0…128) h[k] x[n−k] z[m] = y[4m]

第一行滤波,第二行每四个输出保留一个,m 是新序列索引。系数从理想低通的 sinc 形状开始,截取 129 个值,再用 Hann 窗平滑边缘。加窗可以减小部分响应波纹,但代价是过渡并非瞬间完成。最后将所有权重除以其总和,使恒定输入在初始瞬态结束后保持原有水平。

sinc(u) = sin(πu)/(πu), sinc(0) = 1 w[k] = 0.5 − 0.5 cos(2πk/128) g[k] = (2f_c/f_s) sinc((2f_c/f_s)(k−64)) w[k] h[k] = g[k] / Σ(j=0…128) g[j] f_c = 400 Hz, f_s = 4000 Hz

64 用来居中响应,它是首尾系数之间 128 个间隔的一半。f_c 是设计的截止参数,并不保证到 400 Hz 都原样通过、再往上就立刻消失。有限滤波器有过渡带。因此必须检查例子中各频率的实际响应,以及完整曲线。文末代码使用 NumPy 的归一化 sinc 定义;如果改了约定却不改公式,就会得到另一种滤波器。

结果:虚假的峰不再占主导

构造输入:有用的 300 Hz 分量幅度为 0.2,不希望出现的 700 Hz 分量幅度为 1。幅度经过归一化,不赋予实际加速度单位。不滤波就抽取,两者会重叠,使 300 Hz 峰的幅度变成 1.2。软件可能误认为有用振动比预期大了六倍。这个结果依赖所选相位,其他相位也可能使两者部分抵消。

x[n] = 0.2 cos(2π · 300 n / 4000) + 1.0 cos(2π · 700 n / 4000)

滤波后,300 Hz 处增益为 0.998531,几乎保留全部有用分量。700 Hz 处约为 0.0000131684。以分贝表示,该特定频率的响应为 −97.61 dB;这里分贝计算是幅度比的 20 log₁₀。这不意味着整个阻带都有该衰减,曲线中不同谷值和峰值并不相同。滤波并抽取后,在合成信号中测得 300 Hz 幅度约为 0.199693,接近原来的 0.2。

量计算值
f_s → f_out4000 → 1000 Hz
|H(300 Hz)|0.998531446
|H(700 Hz)|0.0000131684
A300: x[4m]1.200000000
A300: y[4m]0.199693121
(L−1)/(2f_s)16 ms
FIR 计算响应:300 Hz 接近 0 dB,700 Hz 被强烈削弱。500 Hz 线是新的奈奎斯特频率。波纹说明 −97.6 dB 只对应 700 Hz,并非整个频带。
FIR 计算响应:300 Hz 接近 0 dB,700 Hz 被强烈削弱。500 Hz 线是新的奈奎斯特频率。波纹说明 −97.6 dB 只对应 700 Hz,并非整个频带。

为让比较可核查,我们在 4 kHz 下生成 5,000 个样本,执行因果卷积,再以四为步长选取索引 256 到 4252,恰好得到 1,000 个输出。从 256 开始避开了滤波器的启动瞬态,本序列中它最多持续 128 个输入样本。对这一秒数据,用 300 Hz 正弦投影估计幅度,等价于对应的离散傅里叶变换系数。窗口包含整数个周期;这里没有研究频率不对齐引起的频谱泄漏。

隐含成本:等待与保存样本

系数对称,因此滤波器具有线性相位,在有用频带内引入 (L−1)/2 个样本的群延迟。L = 129、f_s = 4 kHz 时,即 64 个样本,也就是 16 ms。需要快速反应的识别器必须将它纳入总时间预算。这不意味着 CPU 运算需要 16 ms;信号时间延迟与处理器计算这些和所需的时间不同。

若每块处理 128 个输入,收齐一块需要 32 ms。块开头的样本比接近结尾的样本等待更久;不能把这种等待与群延迟混为一谈。此外还有传输、模型计算和可能的排队。这里没有测量设备平均延迟或百分位,只识别了设计中的两个确定性贡献。缩小块可减少收集等待,却可能增加调用和传输开销。

CMSIS-DSP FIR 抽取器文档规定:B 个输入一块时,状态需要 L + B − 1 个值。本例若使用每个四字节的 float32,状态为 1,024 字节,系数 516,输入 512,32 样本输出 128。如果四个数组都放 RAM,共 2,180 字节;若系数位于只读存储器,三个显式缓冲区则需要 1,664 字节。栈、结构体、对齐、DMA 和 AI 模型均未计入,这不是应用峰值 RAM 测量。

按直接求和只计算保留输出,每通道每秒约需 129,000 次乘累加:129 个系数乘 1,000 个输出。若先算出全部 4,000 个输出再丢掉四分之三,运算数会是四倍。运算量不等于耗时,向量指令、对称性、缓存和实现都会改变实际成本。为清晰起见,本 NumPy 实验计算完整卷积;没有在 Cortex-M 上执行 CMSIS 内核。

真实开发板上还要检查什么

首先要检查模拟通路。4 kHz 采样并不能防住所有频率,高于 2 kHz 的成分可能已经折叠进数字输入。传感器、内部滤波器和外部滤波器必须一起考虑。不能假定加速度计自动集成了合适滤波器。ADC 饱和、机械安装不当还会产生与混叠不同的问题,本文数字滤波器无法解决它们。

然后要在实际精度下做数值验证。本文结果使用 float64;系数转换成 float32 或定点整数后,并不保证 700 Hz 仍有 −97.61 dB 衰减。应重新计算响应,检查溢出与饱和,并在保持滤波状态的前提下验证块边界。每块都清零状态会反复产生瞬态,恰在我们想提高信号可靠性时改变信号。

最后,要用训练与部署一致的采集链评估模型决策。滤波器变化会改变幅度、相位及延迟,模型也可能恰好学到了某种伪影。试验应记录已知输入频率、传感器设置、时钟、版本及代码,再在平台上测量延迟和功率。这是建议协议,不报告未经测量的功率、每次推理能耗或诊断准确率。

结论:解释信息之前,先保护信息

开头的 300 Hz 峰不足以确认真实振动。现在原因清楚了:观察时刻的选择可能抹去物理区别,下游 AI 若无额外假设就无法重建它。在构造的例子中,先在 4 kHz 下滤波,再降到 1 kHz,可以保留有用成分并削弱污染它的成分。代价可用延迟、缓冲区和运算量描述,但硬件性能仍待验证。因此,设计嵌入式 AI,也包括设计物理世界如何变成数据。

来源、代码与复现条件

MIT 6.300 — Sampling and Aliasing, Spring 2026.

Arm CMSIS-DSP — Finite Impulse Response Decimator, main documentation.

Analog Devices — Filter Basics: Anti-Aliasing.

来源说明采样、抗混叠保护和抽取器接口。CMSIS 的 main 页面是会变化的文档,查阅日期为 2026 年 9 月 25 日,不是我们测过性能的内核版本。滤波器、信号与比较均在附件实验中构造。下面片段计算增益和延迟,压缩包另含卷积、幅度估计及绘图。使用 Python 3.14.0、NumPy 2.5.3、Matplotlib 3.11.2,无随机数。本编辑分析不意味着 EL-AI 已有嵌入式产品或实际安装。

import numpy as np
fs, fc, taps = 4000, 400, 129
k = np.arange(taps)
h = (2*fc/fs) * np.sinc((2*fc/fs)*(k-64)) * np.hanning(taps)
h /= h.sum()
for f in (300, 700):
    gain = abs(np.sum(h*np.exp(-2j*np.pi*f*k/fs)))
    print(f, round(float(gain), 9))
print("delay_ms", 1000*64/fs)

代码、数据与说明 · JSON. 教学计算使用 Python 3.14.0,图使用 Matplotlib 3.11.2。分析由 AI 辅助,不声称经过同行评审或人工审核。原创 ImageGen 封面仅作示意,不记录 EL-AI 人员、场所或实际安装。来源查阅于 2026 年 9 月 25 日。