一、归一化最小均方算法(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