音频噪声抑制(4):普通最小均方误差(LMS)算法
2016-12-13 12:54
232 查看
引言
前面讲了基于Weiner滤波器的噪声抑制方法。Reivew:用维纳滤波器实现噪声抑制
维纳滤波器有一些假设条件,比如信号平稳(这就导致解方程算滤波器系数的时候,自相关矩阵与绝对时间无关)、噪声和有用信号不相关…
其实,这些条件在实际中并不是那么容易满足的。
因此,用维纳滤波器来实现信号去噪,效果不是特别理想。
于是就有人提出自适应滤波器,“自动”去更新滤波器的系数,使它自己去“适应”信号的一些特性。
自适应滤波器有许多种,这里挑最简单的基于“最小均方误差”准则的自适应滤波器来讲了。
LMS滤波器基本原理
原理的话,每一本现代信号处理的书上都讲得很清楚了。归根结底:这是一个需要“训练”(或者说“学习”)的滤波器,在“学习”的过程中,希望把滤波器的输出与期望信号(训练信号)之差,作为算法的反馈,
不断地更新滤波器的系数,以使得在某种意义下,实现最优滤波。
LMS,顾名思义,最小均方误差。
另外,利用梯度下降法,可以简单地求出目标函数(均方误差是关于滤波器系数w)的极值。
一系列简单推导,可得出LMS算法。
w是滤波器系数,
x是滤波器输入,
d是训练信号,
x和w的内积(滤波器与输入信号的卷积)是滤波器的输出,
u是步长(1个正数)。
理论上,u越小,最终求出的极值点结果越精确,但所需要达到极值点的时间就变长了。
有最优的一个u,但其实吧,我感觉也就是理论上提供一种可能性,意思是,
u在每一次迭代的过程中,在理论上都有个最优值。
但实际上,为了求最优值,又需要一大堆的已知条件,而这些条件其实并不是那么好“知道”;
就算是知道了,求最优的u,也会耗费大量的时间。
所以,自己看着办了……
有资料建议,
滤波器阶数,初值,自己设置了。有可能陷入局部极值。这不知道了。试,效果出来就OK了。
Tail & error。
举例:噪声抑制
1. LMS的训练过程。%% LMS滤波去噪 % 作者:qcy % 版本号:v1.0 % 版本说明:本M文件提供训练阶段。 % 时间:2016年10月29日19:02:44 % 好像提升并不是很明显啊!! % why...?????? and 如何改进??? %【问】 是不是不应该用非语音段进行滤波??? close all;clear; clc; %% 导入音频 filedir=[]; % 设置路径 filename='bluesky1.wav'; % 设置文件名 fle=[filedir filename]; % 构成完整的路径和文件名 [s, fs] = audioread(fle); % 读入数据文件 s=s-mean(s); % 消除直流分量 s=s/max(abs(s)); % 幅值归一 N=length(s); % 语音长度 time=(0:N-1)/fs; % 设置时间刻度 SNR = 5; % 设置信噪比 r2=randn(size(s)); % 产生随机噪声 b=fir1(32,0.5); % 设计FIR滤波器,代替H r21=filter(b,1,r2); % FIR滤波 [r1,r22]=add_noisedata(s,r21,fs,fs,SNR);% 产生带噪语音,信噪比为SNR %% 训练阶段 h_length = 100; h = zeros(h_length,1); % 滤波器的初始化 miu = 1e-4; y_out = zeros(size(s)); Ntimes = 3; err2 = zeros(length(s)*Ntimes,1); counter = 1; % 开始滤波 for kk = 1:Ntimes for k = h_length : N idx = k: -1 :(k-h_length+1); r1_in_sub = r1(idx); filter_out = h.' * r1_in_sub; y_out(k) = filter_out; dk = s(k); err = dk - filter_out; err2(counter) = err^2; h = h + miu * err * r1_in_sub; counter = counter + 1; end end % sound(s,fs); % sound(r1,fs); % sound(y_out,fs); %% 作图 figure plot(err2); grid on; title('均方误差'); figure; subplot 311; plot(time,s,'k'); ylabel('幅值') ylim([-1 1 ]); title('原始语音信号'); subplot 312; plot(time,r1,'k'); ylabel('幅值') ylim([-1 1 ]); title('带噪语音信号'); subplot 313; plot(time,y_out,'k'); ylim([-1 1 ]); title('LMS滤波输出语音信号'); xlabel('时间/s'); ylabel('幅值')
尽管听起来,似乎有一定的改良,但是去噪效果还是不明显!
我暂时不知道为什么。而且,很多书上都回避了普通LMS来去噪的例子。
连去噪前后信号波形图都没有给出。更不要说什么均方误差了。
我在想,是不是在训练的过程中,整个语音信号中,说话不能有停顿啊?
从我的均方误差的图中,似乎看得出来,似乎有一个逐渐变小的过程,但是突然又会变大。
假设,期望信号中,有非常微弱的部分(说话间隙),基本就是0了。
这时滤波器为了让均方误差最小,是不是系数要全为0啊?
那这样的训练过程……
是不是最终导致去噪效果不佳的原因?
所以,是不是还需要做一个端点检测,把真正的语音段全部提取出来,以此作为训练信号呢?
相关文章推荐
- 音频噪声抑制(5):含辅助观测数据的LMS噪声抑制
- 音频噪声抑制(6):不含辅助观测数据的LMS噪声抑制
- 音频处理之去噪算法---基于pcm和g711的音频16000hz、8bit去噪声算法
- 音频噪声抑制(1):经典滤波器篇
- 音频录制的噪声抑制与PCM+H264封装MP4
- 音频噪声抑制(3):维纳(Wiener)滤波器篇之有辅助观测数据
- 滤波器设计(4):自适应滤波器之最小均方误差(LMS)滤波器的设计
- 音频噪声抑制(2):维纳(Wiener)滤波器篇
- 记一下机器学习笔记 最小均方(LMS)算法
- 音频噪声抑制(7):利用基本谱减法实现噪声抑制
- 最小均方(LMS)算法
- 自适应滤波:最小均方误差滤波器(LMS、NLMS)
- 从海量数据中查找出前k个最小或最大值的算法(java)
- 【基础算法练习】【最短路+图的遍历+最小生成树】水题 C+ E+ F-----AC题
- 语音增强算法研究系列(四):非平稳噪声消除
- 最小生成树 kruscal算法 C语言
- 转 最小生成树(kruskal 算法 和prim算法)
- 关于图ADT的一些算法——最小生成树算法(普利姆/Prim算法)
- 序列最小优化算法(SMO)
- Prim 算法生成的最小生成树