3. 自适应滤波基础:LMS算法原理、NLMS算法及其归一化策略、自适应滤波器的收敛性与稳定性

好,咱们进入正题。自适应滤波,说白了就是让滤波器自己学会怎么干活。你给它一个目标,它自己调整参数去逼近。在助听器声反馈抑制里,这东西就是核心中的核心。

我刚开始接触这行的时候,总觉得自适应滤波很玄乎。后来做多了才发现,它本质上就是个不断试错、不断修正的过程。就像你学骑自行车,歪了就往反方向调一下,慢慢就稳了。

3.1 LMS算法:最朴素的迭代思路

LMS,全称Least Mean Square,最小均方。名字听着挺唬人,其实思想特别简单。

想象一下,你有一个输入信号x(n),通过一个滤波器得到输出y(n)。我们希望这个输出尽量接近一个期望信号d(n)。误差e(n) = d(n) - y(n)。LMS干的事就是:每次来一个新样本,根据误差大小,稍微调整一下滤波器的系数,让下一次的误差变小。

数学上,系数更新公式长这样:

w(n+1) = w(n) + 2 * μ * e(n) * x(n)

这里w(n)是当前滤波器系数,μ是步长因子,e(n)是误差,x(n)是输入信号。

嗯,这里要注意:μ的选择非常关键。它决定了你学得快还是学得稳。

核心要点:LMS算法不需要计算梯度,直接用瞬时误差的平方作为代价函数的估计。这就是它计算量小的原因。

我在项目中遇到过一个问题:用固定步长的LMS,刚开始收敛挺快,但到了稳态阶段,系数一直在最优值附近晃荡,降噪效果上不去。后来我才意识到,这就是LMS的固有缺陷——收敛速度和稳态精度是矛盾的。

3.2 NLMS算法:归一化解决大问题

LMS有个明显的毛病:它对输入信号的幅度特别敏感。如果输入信号突然变大,比如用户突然说话声音大了,那更新步长相当于被放大了,滤波器可能直接发散。

你想想看,这在实际场景中多要命。助听器用户可能从安静环境走到嘈杂街道,信号幅度变化几十倍。如果算法扛不住,啸叫声瞬间就出来了。

NLMS,Normalized LMS,就是来解决这个问题的。它在更新公式里加了一个归一化因子:

w(n+1) = w(n) + (μ / (||x(n)||² + δ)) * e(n) * x(n)

其中||x(n)||²是输入信号的功率估计,δ是一个很小的正数,防止分母为零。

说白了,就是用输入信号的功率去归一化步长。信号强的时候步长自动变小,信号弱的时候步长自动变大。这样不管输入信号怎么变,算法的行为都相对稳定。

对比项 LMS NLMS
步长控制 固定μ μ / (功率 + δ)
对输入幅度敏感度
收敛速度一致性 差(随输入变化) 好(归一化后稳定)
计算量 略高(多一次除法)

实战建议:在助听器这种资源受限的平台上,我建议直接用NLMS。虽然多了一次除法和一次功率估计,但换来的是稳定性和鲁棒性,这笔账怎么算都划算。

3.3 归一化策略的细节

归一化听起来简单,但实际做起来有不少坑。我踩过最深的坑就是功率估计的方式。

最简单的做法是用当前样本的平方作为功率:||x(n)||² = x(n)²。但这样太粗糙了,单个样本的波动会导致步长剧烈变化。

更好的做法是用滑动平均:

P(n) = α * P(n-1) + (1-α) * x(n)²

α通常取0.9到0.999之间。α越大,功率估计越平滑,但响应越慢。我个人习惯取0.95,在平滑度和响应速度之间取个平衡。

还有一个细节:δ的取值。太小了,当输入信号接近零时,步长会变得极大,容易发散。太大了,归一化效果就减弱了。我一般取δ = 0.01 * 信号的最大可能功率,或者干脆取一个固定的小值,比如1e-6。

避坑指南:我曾经在一个项目中,δ设得太小,结果用户摘下助听器放在桌上(输入信号几乎为零),算法直接发散,重新戴上时啸叫不止。后来我把δ改成了自适应阈值,才彻底解决这个问题。

3.4 收敛性与稳定性分析

为什么LMS能收敛?为什么NLMS更稳定?咱们从直觉上理解一下。

LMS的收敛条件很简单:0 < μ < 1/λ_max,其中λ_max是输入信号自相关矩阵的最大特征值。但实际中我们很难知道λ_max,所以通常取一个很小的μ来保证稳定。

NLMS的收敛条件更宽松:0 < μ < 2。只要步长因子在0到2之间,算法理论上就是收敛的。这就是归一化的威力——它把对输入信号特性的依赖去掉了。

但要注意,理论上的收敛和实际中的稳定是两回事。我见过不少算法在仿真里跑得好好的,一上硬件就崩了。为什么?因为硬件有量化误差、有定点数精度问题、有延迟。

影响稳定性的几个关键因素:

  • 步长因子μ:越大收敛越快,但稳态误差越大,甚至发散
  • 滤波器阶数:阶数越高,收敛越慢,对数值精度要求越高
  • 输入信号特性:窄带信号比宽带信号更难收敛
  • 数值精度:定点实现时,精度不够会导致系数更新失效

经验之谈:在助听器这种16位定点DSP上,我通常把μ设在0.01到0.1之间。太小了收敛太慢,用户能听到明显的啸叫过渡过程;太大了稳态性能差,残留的反馈信号还是能引起啸叫。

还有一个容易被忽略的点:滤波器的初始状态。如果初始系数离最优值太远,收敛过程会很长。我一般会用一段静音期的数据做预训练,让滤波器先收敛到大概位置,再进入正常工作模式。

好了,这一章的内容就这些。LMS和NLMS是自适应滤波的基石,后面的章节我们会在这个基础上,加入频域处理、双滤波器结构、步长控制等更高级的技巧。这些都是在实际产品中真正能打的东西。