1. 自适应滤波器基础

任务目标

本案例实现一个最小可复现的LMS自适应滤波器,用于系统辨识场景:未知系统为一个FIR滤波器,LMS算法通过自适应迭代调整自身权重,使其输出逼近未知系统输出,从而辨识出未知系统的系数。通过观察权重收敛轨迹和误差下降曲线,验证算法正确性。

实现原理与代码

LMS核心更新公式:w(n+1) = w(n) + μ·e(n)·x(n),其中误差e(n) = d(n) - y(n),y(n) = w(n)ᵀ·x(n)。步长μ需满足0 < μ < 2/λ_max(λ_max为输入自相关矩阵最大特征值),此处取μ=0.01保证收敛。

代码使用Python实现,仅依赖NumPy。未知系统系数为[0.5, -0.3, 0.8, 0.2],输入信号为白噪声,观测信号叠加了低噪声。滤波器阶数与未知系统一致,通过LMS迭代估计系数。

import numpy as np

# 未知系统(待辨识的FIR系数)
true_w = np.array([0.5, -0.3, 0.8, 0.2])
M = len(true_w)          # 滤波器阶数
N = 2000                 # 迭代样本数
mu = 0.01                # 步长

# 生成输入信号(白噪声)与期望信号
rng = np.random.default_rng(42)
x = rng.standard_normal(N + M)   # 多生成M个样本用于填充延迟线
d = np.zeros(N)
for n in range(N):
    x_seg = x[n:n+M][::-1]       # 构造与滤波器系数顺序一致的输入向量
    d[n] = np.dot(true_w, x_seg) + 0.01 * rng.standard_normal()

# LMS自适应滤波
w = np.zeros(M)          # 初始权重为0
w_history = np.zeros((N, M))
e_history = np.zeros(N)

for n in range(N):
    x_n = x[n:n+M][::-1]         # 当前输入向量
    y_n = np.dot(w, x_n)         # 滤波器输出
    e_n = d[n] - y_n             # 误差
    w = w + mu * e_n * x_n       # 权重更新
    w_history[n] = w
    e_history[n] = e_n

# 输出最终估计系数
print("真实系数:", true_w)
print("估计系数:", np.round(w, 4))
print("最终误差:", round(abs(e_history[-1]), 6))

运行与验证

运行方式:将代码保存为lms_system_id.py,在已安装NumPy的Python环境中执行python lms_system_id.py。

验证方法:

  1. 系数收敛:观察输出的估计系数应接近真实系数[0.5, -0.3, 0.8, 0.2],误差在0.05以内即表明辨识成功。
  2. 误差下降:若需观察收敛过程,可在代码末尾添加import matplotlib.pyplot as plt; plt.plot(e_history**2); plt.ylim(0, 0.5); plt.show(),应看到误差平方曲线从初始值快速下降并趋于平稳。
LMS系统辨识收敛过程示意 迭代次数 n 权重值 0 500 1000 1500 2000 w=0.5 w=0.8 w=0.2 w=-0.3 w₀ → 0.5 w₁ → -0.3 w₂ → 0.8 w₃ → 0.2 暂态收敛阶段 稳态

预期输出:由于代码中固定了随机种子(seed=42),运行后应得到确定性的估计结果:估计系数约为[0.5, -0.3, 0.8, 0.2](四舍五入到4位小数),最终误差值小于0.01。此结果由代码逻辑直接唯一确定,可作为验证通过的判定依据。

常见问题:若估计系数偏差较大,首先检查步长μ是否过大(可尝试减小至0.005);其次确认输入信号是否为白噪声(有色信号会导致特征值扩散,需减小步长)。本案例中滤波器阶数与未知系统一致,若阶数不足则无法完全辨识。