自适应滤波器原理——(功率)归一化最小均方算法(NLMS/PNLMS)

一、归一化最小均方算法(NLMS)

传统的LMS算法的滤波器更新步长是固定的;滤波器的变化与输入信号的大小直接相关,输入较大时,会产生梯度噪声放大的问题,因此,在实际的应用中,我们希望两次权重的更新之间,滤波器权重的变化要尽可能小,波动不要太剧烈,即最小扰动原理。

因此在原始的LMS算法作如下改动:

 

 

归一化最小均方(Normalized Least Mean Squares,NLMS)算法是改进的LMS算法,对于较大的输入,会导致梯度噪声的放大,因此需要用输入向量的平方范数进行归一化。根据原LMS算法中误差信号与远端输入信号的乘积,对远端输入信号的平方(功率)进行归一化处理,将固定步长因子的LMS算法变为根据输入信号时变的变步长NLMS算法,具体算法如下:

其中w(n)为滤波器的系数,e(n)为误差信号

  • 优点:改善了LMS算法收敛速度慢的缺点。计算简单、更高的精度
  • 缺点:输入相关信号时,收敛速率明显下降

MATLAB程序如下:

function [e,y, w] = NLMS(d, x, M)
    % 输入:
    % d  - 麦克风语音
    % x  - 远端语音
    % M  - 滤波器阶数
    %
    % 输出:
    % e - 近端语音估计
    % y - 远端回声估计
    % w - 滤波器参数
    d_length = length(d);
    if (d_length <= M)
        print('error: 信号长度小于滤波器阶数!');
        return; 
    end
    if (d_length ~= length(x))  
        print('error: 输入信号和参考信号长度不同!');
        return; 
    end

    xx = zeros(M,1);
    w1 = zeros(M,1);        % 滤波器权重
    y = zeros(d_length,1);   % 近端语音
    e = zeros(d_length,1);  % 误差

    for n = 1:d_length
        %在输入信号x前补上M-1个0,使输出y与输入具有相同长度
        xx = [xx(2:M);x(n)];    % (39,1)+(1,1)=(40,1)
        y(n) = w1' * xx;        % (40,1)'*(40,1)=1
        mu = 1/(xx'*xx);    % 步长
        e(n) = d(n) - y(n);     % 误差
        w1 = w1 + mu * e(n) * xx;
        w(:,n) = w1;
    end
end

二、功率归一化最小均方(PNLMS)

 PNLMS 在NLMS的基础上引入了α和β,稳定性要好于 NLMS 。β一般设为一个较小的整数,防止输入数据矢量x(n)的内积过小使得μ(n)过大而引起稳定性能下降,一般取0.0001。当α=1,β=0时, PNLMS 退化为 NLMS 。

MATLAB程序如下:

function [e,y, w] = PNLMS(d, x, M, aplha, beta)
    % 输入:
    % d  - 麦克风语音
    % x  - 远端语音
    % a  - 偏置参数
    % M  - 滤波器阶数
    %
    % 输出:
    % e - 近端语音估计
    % y - 远端回声估计
    % w - 滤波器参数
    d_length = length(d);
    if (d_length <= M)
        print('error: 信号长度小于滤波器阶数!');
        return; 
    end
    if (d_length ~= length(x))  
        print('error: 输入信号和参考信号长度不同!');
        return; 
    end

    xx = zeros(M,1);
    w1 = zeros(M,1);        % 滤波器权重
    y = zeros(d_length,1);   % 近端语音
    e = zeros(d_length,1);  % 误差

    for n = 1:d_length
        %在输入信号x前补上M-1个0,使输出y与输入具有相同长度
        xx = [xx(2:M);x(n)];    % (39,1)+(1,1)=(40,1)
        y(n) = w1' * xx;        % (40,1)'*(40,1)=1
        mu = aplha/(beta + xx'*xx);    % 步长
        e(n) = d(n) - y(n);     % 误差
        w1 = w1 + mu * e(n) * xx;
        w(:,n) = w1;
    end
end

参考链接:

https://www.cnblogs.com/LXP-Never/p/11773190.html

https://www.bilibili.com/video/BV1Lt4y1E7DJ/?spm_id_from=333.788

猜你喜欢

转载自blog.csdn.net/qq_42233059/article/details/131342294
今日推荐