基于LMS最小均方误差法的语音降噪北工大.docx
《基于LMS最小均方误差法的语音降噪北工大.docx》由会员分享,可在线阅读,更多相关《基于LMS最小均方误差法的语音降噪北工大.docx(21页珍藏版)》请在冰豆网上搜索。
基于LMS最小均方误差法的语音降噪北工大
信号处理与分析课程设计报告
项目名称:
基于LMS最小均方误差法的
语音降噪
姓名:
07021102台斯瑶
07021106王金泊
指导教师:
李如玮
一、课题背景和简介
本课题是根据电子信息类本科生信号处理和分析课程的学习内容和语音信号处理的实际应用相结合而设计的实践性训练。
课程训练以数字信号处理为基础,在掌握基本原理的同时,理解语音信号的相关知识并结合实际应用实现对语音信号的分析和处理。
滤波是一种数字信号处理操作,其目的是为了处理某个信号,以便提取出输入信号中所包含的期望信息。
在数字信号处理课程中,我们基本掌握了一些线性滤波器的设计方法,有固定的规范可遵循。
而在我们的实际生活中,充满了偶然和随机,时不变滤波器已不能够满足更好效果的滤波。
在这种情况下,我们就需要自适应滤波器。
可以看到,随着数字超大规模集成技术的发展,自适应滤波技术在很多领域得到了广泛应用。
最小均方算法是一种搜索算法,他通过对目标函数进行适当的调整,简化了对梯度相量的计算。
由于其计算简单性,LMS算法以及其它一些相关算法已广泛应用于自适应滤波的各种应用中。
而LMS算法是自适应滤波理论中应用最广泛的算法。
这主要归因于其地计算复杂度、在平稳环境中的收敛性、其均值无偏地收敛到维纳解以及利用有限精度算法实现时的稳定特性等等。
对LMS最小均方算法的学习,将加深我们对数字信号处理课程的理解,同时对我们今后滤波技术的应用奠定了巩固的基础。
二、训练目的
1.通过利用c程序实现数字信号处理的相关功能,巩固对信号处理原理知识的理解,提高实际编程和处理数据的综合能力,初步培养在解决信号处理实际应用问题中所应具备的基本素质和要求。
2.培养研发能力,通过设计实现不同的信号处理问题,初步掌握在给定条件和功能的情况下,实现合理设计算法结构的能力。
3.提高文献整理和资料查询的能力。
通过课下对相关语音知识的学习和理解,培养快速解决实际问题的能力,并在文献整理的过程中学会科技文献的写作,提高语言表达能力。
三、训练内容
根据语音信号的特点,利用不同信噪比的高斯白噪声对语音进行加噪,利用LMS最小均方误差法设计实现自适应滤波器,并讨论语音状态变化下的收敛情况。
四、最小均方差LMS实现自适应滤波器的方法介绍
自适应滤波器是符合某种准则的最佳滤波器。
它是通过对环境进行学习,逐渐达到或逼近最优滤波器。
由于学习过程中有“导师”存在,因此它是一种具有监督学习功能的过程。
当滤波器的应用环境发生缓慢变化时,相当于滤波器应用于非平稳环境,但环境变化比学习速度更缓慢时,自适应滤波器能够自适应地跟踪这种非平稳变化。
开始时,给FIR滤波器赋予任意的初始权系数,在每个时刻,用当前权系数对输入信号进行滤波运算,产生输出信号,输出信号与期望响应的差定义为误差信号,由误差信号与输入信号矢量一起构造一个校正量,自适应地调整权矢量,使误差信号趋于降低的趋势,从而使滤波器逐渐达到或接近最优。
LMS最小均方误差的方法是由最速下降法推导而出。
最速下降法需要求出其梯度的精确值,要求输入信号和期望信号平稳,且
(Rak=抽头输入向量u(n)与期望响应d(n)的互相关向量;Rxx=抽头输入向量u(n)的相关矩阵;W=抽头权向量)要首先估计
和
,这给具体实现带来很大困难,因此该算法还不是真正意义的自适应滤波算法,但讨论最陡下降法是有意义,由最陡下降法可以很直观地导出一类自适应滤波算法---LMS算法。
LMS算法的基本思想:
调整滤波器自身参数,使滤波器能够自适应地跟踪这种输入信号的变化,实现最优滤波。
当横向滤波器运行在实数据的情况下,该算法大体上可描述为:
抽头权向量更新值=老的抽头权向量值+学习速率参数*抽头输入向量*误差信号
其中误差信号定义为期望向量与抽头输入向量所产生的横向滤波器的实际向量之差
设输入信号为u(n),LMS算法理论推导过程如下:
滤波器输出y(n)为:
(1)
由误差定义得:
(2)
使用最小均方误差法,得代价函数为均方误差为:
(3)
式(3)中J是滤波器的系数kw(k=0,1,2,…)的函数。
通过选择最优的系数,使J达到最小值。
定义梯度向量为∇J,
∇
(4)
另外,最陡下降迭代方程为:
w(n+1)=w(n)−μ∇ˆJ(n)(5)
LMS是直接利用单次采样数据获得的e2(n)来代替均方误差J(n),从而进行梯度估计,
每次迭代时计梯度估计为:
(6)
式(6)代入式(5),得到系数向量自适应迭代法:
w(n+1)=w(n)−μ∇ˆJ(n)=w(n)+2μe(n)u(n)(7)
式(7)称最小均方自适应算法LMS。
五、实验设计及实施过程
自适应滤波器的基本原理:
所谓自适应滤波,就是利用前一时刻已经获得的滤波器参数的结果,自动的调节显示课的滤波器的参数,以适应信号和噪声未知的或随时间变化的统计特性,从而实现最优滤波。
自适应滤波器实质上就是一种能调节器自身传输特性已达到最优的维纳滤波器。
自适应滤波器不需要关于输入信号的先验知识,计算量小,特别是用于实时处理。
由于无法预知信号和噪声的特性,必须设计自适应滤波器,以跟踪信号和噪声的变化。
自适应滤波器的特性变化是由自适应算法通过调整滤波器系数来实现的。
一般而言,自适应滤波器有两部分组成,已是滤波器的结构,二是调整滤波器系数的自适应算法。
本实验的滤波结构采用FIR滤波器设计,自适应算法采用LMS最小均方差算法。
总体结构图如图1
图1
1、滤波器结构设计
①FIR滤波器原理
FIR滤波器的数学表达式为
(8)
式中:
N为FIR滤波器的抽头数;x(n)为第n时刻的输入样本;h(i)为FIR滤波器第i级抽头系数。
在本实验中,即为w(n);
其相应的z变换为:
(9)式中:
z-i为N-1阶多项式。
普通的直接型FIR滤波器结构如图2所示。
图2FIR滤波器直线型结构
在本实验中,抽头系数会根据每一次的输出进行自适应修改。
②程序实现
对输入信号x[i]和滤波系数w[i]进行时域的卷积和,求出输出信号y.
for(i=0;i{y=y+x[i]*w[i];//实际输出信号的合成
}
2、高斯白噪声的实现方法
①高斯白噪声的原理
高斯白噪声:
具有高斯分布的噪声就成为高斯噪声,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。
在本实验中,我组针对高斯白噪声的特点进行了程序的设计。
首先确定的我们需要的白噪声的期望值、方差、和噪声数组的长度,通过一个专门产生白噪声的种子文件进行设计,利用如下公式,最终得到了所需要的白噪声信号。
根据定理:
设
为n个相互独立的均匀分布的随机数,其期望为
,方差为
,有中心极限定理可知(如果n个独立随机变量的分布式相同的,并且具有有限的数学期望和方差,当n无穷大时,它们之和的分布趋近于高斯分布;即使n个独立随机变量不是相同分布的,当n无穷大时,如果满足任意一个随机变量都不占优或对和的影响足够小,那么它们之和的分布仍然趋于高斯分布),
当n充分大时,有
(10)
②程序实现方法
for(k=0;k<=n-1;k++)
{
t=0.0;
for(i=1;i<=12;i++)//取
=1/12次
{
*r=(*r)*w+v;//求r,s=65536.0;w=2053.0;v=13849.0;
*r=*r-m*s;//求整数后余下的数
t=t+(*r)/s;//累加到t中
}
a[k]=u+g*(t-6.0);//放到a[k]中,产生高斯白噪声过程
③信噪比的改变
为了测试噪声信号的改变对LMS算法最终效果的影响,我组对噪声信号进行了信号能量强度处理。
处理方法即使通过给已产生的信号乘上一个系数,通过系数值的改变来调节信号的能量。
系数值得计算方法为
(11)式中,SNR为信噪比,es为原始声音的均值,ns为噪声的均值。
程序实现:
snrate=sqrt(es/ns/pow(10,SNR/10));//开根号pow计算10的SNR/10次方的值,求能量,为了达到信噪比20DB而乘上的系数,SNR为信噪比
3、LMS算法的实现
LMS最小均方差算法的原理已在前文给出。
本实验就以该原理为基础进行设计。
在此不多赘述。
需要注意几点:
1LMS的收敛性
LMS算法的收敛因子必须在如下范围内选取:
(12)
0<μ<2/(MSmax)其中Smax是抽头输入u(n)的功率谱密度的最大值,而滤波器长度M为中到大
在满足收敛条件下,才有
(13)
即,
值得合理选取确保了系数向量的平均值接近于最优系数向量W。
实际中,
通常选得很小,选
(14)
在实验中,选定N=10
实验程序为:
mu=mu+sn*sn;
mu=1/(10*(mu));//sn为加噪信号,即为式(14)中x
2抽头系数的自适应改变
抽头系数的自适应改变是LMS算法中的一个重要部分,没有他的改变,自适应也就无从谈起。
我们设计的滤波器权系数控制电路如图3
图3FIR滤波器中第
个权系数的控制电路图
根据权系数的计算方法
(15)
我们得到程序设计:
for(i=0;i{
w[i]=w[i]+e*x[i]*mu;//做下一信号的权值
}
初始化抽头权向量为0
六、实验结果分析
图4原始声音信号频谱图
图5高斯白噪声频谱图
图6加噪声之后的频谱图
图7滤波后的语谱图
Map1
Map2
Map3
图8matlab仿真图
Map1原始声音
Map2加了噪声后的语音
Map3降噪后的语音
七、从实验中分析LMS算法的缺点
LMS保证算法收敛并减少失调系数,通常把收敛因子取得比较小,这样使它存在收敛慢的缺点;如果μ值取的过大,可以快速达到收敛,但是很大程度上影响系统稳定度。
另外,在具体实现权系数调整时,运算精度非常重要,因为该算法对抽头输入相关矩阵条件数(矩阵的条件数定义为最大特征值与最小特征值之比)的变化比较敏感。
要求所用的乘法器和加法器有很高的精度,这样增加了成本,降低了运算速度,针对这些问题,国内外提出了一些改进算法。
如LMS2算法、LMSQ算法、MLMS(修正的LMS)算法、TDO和LMF算法等。
并且,LMS算法是对误差的一种跟踪,所以对于处理比较嘈杂的语音信号的时候,误差误差随时在变,所以并不是能做到很好的跟踪。
而对于误差变化不大的信号,如正弦波等,就能做到很好的无差跟踪,几乎可以全部复原原信号。
因为作为自适应滤波器,对输出有一个学习以及追踪的功能,但是条件是外部环境变化要比学习速度缓慢。
当处理连续变化的语音信号时,LMS算法并不能很好的应用,在于误差e2(n)在不断的变化。
从MATLAB时域图中我们可以看到降噪效果很好,但是用COOLEDITOR进行频谱分析的时候就可以看出,对于连续变化的语音部分,LMS并不是能很好的降噪。
八、实验完整程序
LMS(主函数)部分:
#include"math.h"
#include"stdio.h"
#defineSNR20//信噪比
#defineBUFLEN50
#defineRNSLEN50000
voidgrns(double,double,double*,int,double*);
main()
{
FILE*fp,*fps,*fpx,*fpy,*fpe1,*fpe2,*fpes,*fpxs,*fpys;
shorts1=0;
doubles=0.0;
doublesn=0.0;
doubleu=0;
doubleg=1.0;
doubler=1.0;
doubleran=0;
doublees=0.0;
doublesnrate=0.0;
doublens=0.0;
doublex[BUFLEN]={0.0};
doubled[BUFLEN]={0.0};
shortxs={0};
shortys={0};
doublew[BUFLEN]={0.0};
doubley=0.0;
doublemu=1e-8;//初始化
doublee=0.0;//初始化
doublernsbuff[RNSLEN]={0.0};
inti=0,j=0;
intnump=0;
fp=fopen("tone.dat","rb");//打开文件
fpes=fopen("tone.dat","rb");
fps=fopen("s.dat","wb");
fpx=fopen("x.dat","wb");
fpy=fopen("y.dat","wb");
fpe1=fopen("e1.dat","wb");
fpe2=fopen("e2.dat","wb");
fpxs=fopen("xs.dat","wb");
fpys=fopen("ys.dat","wb");
nump=fread(&s1,sizeof(short),1,fpes);//sizeof(short)长度运算符
&s1取地址
fread从fpes所指向的文件的位置
读取长度为sizeof(short)的1个数据项,
存到s1所指向的内存单元,
返回所读的数据项个数,
文件结束或出错返回0
es=0.0;i=0;
while(nump==1)
{
es=es+s1*s1;//平方后相加
i=i+1;
nump=fread(&s1,sizeof(short),1,fpes);//指针自动加1
}
es=es/i;//平方和的平均值
grns(u,g,&r,RNSLEN,rnsbuff);//调的外部的函数高斯白噪声
ns=0.0;
for(i=0;i{ns=ns+rnsbuff[i]*rnsbuff[i];}//高斯白噪声的平方和
ns=ns/RNSLEN;//平方求和的平均数
snrate=sqrt(es/ns/pow(10,SNR/10));//开根号
pow计算10的SNR/10次方的值,
求能量,
为了达到信噪比20DB而乘上的系数,
SNR为信噪比
/*************************************
***************************************
*****************************************
************************************/
nump=fread(&s1,sizeof(short),1,fp);//把fp所指的数据读入s1中
while(nump==1)
{
s=(double)s1;//s1转为双精放到s中,就是纯净语音信号
fwrite(&s,sizeof(double),1,fps);//把s中的文件写到fps中
grns(u,g,&r,1,&ran);//ran就是刚才的那个a[k],即高斯噪声信号
ran=ran*snrate;//重新计算后的噪声
sn=s+ran;mu=0;//步长先设定为0,为了能让信号对齐,sn为合成信号
fwrite(&sn,sizeof(double),1,fpx);
fwrite(&ran,sizeof(double),1,fpe1);
for(i=BUFLEN-1;i>0;i--)
{
x[i]=x[i-1];d[i]=d[i-1];mu=mu+x[i]*x[i];//算一个数就往后挤一个数再算
}
x[0]=sn;
d[0]=s;
mu=mu+sn*sn;
mu=1/(10*(mu));//x[i]是合成信号,d[i]是纯净语音信号。
//求步长,通过E[x^2]来求,
y=0.0;
for(i=0;i{
y=y+x[i]*w[i];//实际输出信号的合成
}
e=d[0]-y;//真实信号和实际输出信号的差值
for(i=0;i{
w[i]=w[i]+e*x[i]*mu;//做下一信号的权值
}
xs=(short)x[0];
ys=(short)y;
fwrite(&y,sizeof(double),1,fpy);//实际输出的降噪的合成信号
fwrite(&e,sizeof(double),1,fpe2);//误差
fwrite(&xs,sizeof(short),1,fpxs);//整形的加噪合成信号
fwrite(&ys,sizeof(short),1,fpys);//整形的降噪输出信号
nump=fread(&s1,sizeof(short),1,fp);
}
}
产生高斯白噪声(grns)部分:
voidgrns(u,g,r,n,a)//产生高斯白噪声,并且加在纯净语音信号上
intn;//初值是主函数中的RNSLEN长度
doubleu;//平均值
doubleg;//方差
double*r;//种子,针对这一点计算产生高斯白噪声
doublea[];//产生随机信号,即高斯白噪声
{
inti,k,m;
doubles,w,v,t;
s=65536.0;//都是任意给定的初值
w=2053.0;
v=13849.0;
for(k=0;k<=n-1;k++)
{
t=0.0;
for(i=1;i<=12;i++)//12次
{
*r=(*r)*w+v;//求r
m=(int)(*r/s);//取整
*r=*r-m*s;//求整数后余下的数
t=t+(*r)/s;//累加到t中,感觉像相对误差
}
a[k]=u+g*(t-6.0);//放到a[k]中,产生高斯白噪声过程
}
return;
}
九、参考文献
《自适应滤波算法与实现》(第二版)电子工业出版社
《自适应滤波器原理》(第四版)电子工业出版社
十、特别鸣谢
感谢李如玮老师的细心教导和刘欣研究生的热心解答,使我们不仅顺利完成了实验,而且还收获了很多知识。