四、LMS算法基本原理
根據(jù)小均方誤差準(zhǔn)則以及均方誤差曲面,自然的我們會(huì)想到沿每一時(shí)刻均方誤差 的陡下降在權(quán)向量面上的投影方向更新,也就是通過目標(biāo)函數(shù)k反梯度向量來反 復(fù)迭代更新。由于均方誤差性能曲面只有一個(gè)唯一的極小值,只要收斂步長選擇恰當(dāng), 不管初始權(quán)向量在哪,后都可以收斂到誤差曲面的小點(diǎn),或者是在它的一個(gè)鄰域內(nèi)。 這種沿目標(biāo)函數(shù)梯度反方向來解決小化問題的方法,我們一般稱為速下降法,表達(dá)式如下:
基于隨機(jī)梯度算法的小均方 自適應(yīng)濾波算法的完整表達(dá)式如下:
LMS 自適應(yīng)算法是一種特殊的梯度估計(jì),不必重復(fù)使用數(shù)據(jù),也不必對相關(guān)矩陣 和互相關(guān)矩陣 進(jìn)行運(yùn)算,只需要在每次迭代時(shí)利用輸入向量和期望響應(yīng),結(jié)構(gòu)簡單, 易于實(shí)現(xiàn)。雖然 LMS 收斂速度較慢,但在解決許多實(shí)際中的信號(hào)處理問題,LMS 算法 是仍然是好的選擇。
3 LMS算法性能分析
隨機(jī)梯度 LMS 算法的性能前人有過大量研究,按照前一章所提到的自適應(yīng)濾波性能 指標(biāo),假設(shè)輸入信號(hào)和期望信號(hào)具有聯(lián)合平穩(wěn)性,詳細(xì)討論基于橫向 FIR 結(jié)構(gòu)的濾波器 的標(biāo)準(zhǔn) LMS 算法的四個(gè)性能:一、收斂性;二、收斂速度;三、穩(wěn)態(tài)誤差;四、計(jì)算復(fù) 雜度。 只有在輸入信號(hào)具有嚴(yán)格穩(wěn)定的統(tǒng)計(jì)特性時(shí),權(quán)向量的優(yōu)解是不變的。否則, 將會(huì)隨著統(tǒng)計(jì)特性的變化而變化。自適應(yīng)算法則能夠通過不斷的調(diào)整濾波器權(quán)向量,使權(quán)向量接近優(yōu)解 。因此,自適應(yīng)算法在平穩(wěn)條件下的性能表現(xiàn)可以認(rèn)為是非平穩(wěn)條件下的一種特殊情況。如果在平穩(wěn)條件下,自適應(yīng)算法能夠快 速,平穩(wěn)的逼近權(quán)向量的優(yōu)值,那么在非平穩(wěn)條件下,該算法也能很好的逼近時(shí)變的 權(quán)向量優(yōu)解。
五、算法流程
下面介紹一下LMS算法的基本流程。
1. 初始化工作,為各個(gè)輸入端的權(quán)值覆上隨機(jī)初始值;
2. 隨機(jī)挑選一組訓(xùn)練數(shù)據(jù),進(jìn)行計(jì)算得出計(jì)算結(jié)構(gòu)C;
3. 利用公式3對每一個(gè)輸入端的權(quán)值進(jìn)行調(diào)整;
4. 利用公式1計(jì)算出均方差MSE;
5. 對均方差進(jìn)行判斷,如果大于某一個(gè)給定值,回到步驟2,繼續(xù)算法;如果小于給定值,就輸出正確權(quán)值,并結(jié)束算法。
六、算法實(shí)現(xiàn)
以下就給出一段LMS算法的代碼。
?。踓pp] view plain copyconst unsigned int nTests =4;
const unsigned int nInputs =2;
const double rho =0.005;
struct lms_testdata
{
doubleinputs[nInputs];
doubleoutput;
};
double compute_output(constdouble * inputs,double* weights)
{
double sum =0.0;
for (int i = 0 ; i 《 nInputs; ++i)
{
sum += weights[i]*inputs[i];
}
//bias
sum += weights[nInputs]*1.0;
return sum;
}
//計(jì)算均方差
double caculate_mse(constlms_testdata * testdata,double * weights)
{
double sum =0.0;
for (int i = 0 ; i 《 nTests ; ++i)
{
sum += pow(testdata[i].output -compute_output(testdata[i].inputs,weights),2);
}
return sum/(double)nTests;
}
//對計(jì)算所得值,進(jìn)行分類
int classify_output(doubleoutput)
{
if(output》 0.0)
return1;
else
return-1;
}
int _tmain(int argc,_TCHAR* argv[])
{
lms_testdata testdata[nTests] = {
{-1.0,-1.0, -1.0},
{-1.0, 1.0, -1.0},
{ 1.0,-1.0, -1.0},
{ 1.0, 1.0, 1.0}
};
doubleweights[nInputs + 1] = {0.0};
while(caculate_mse(testdata,weights)》 0.26)//計(jì)算均方差,如果大于給定值,算法繼續(xù)
{
intiTest = rand()%nTests;//隨機(jī)選擇一組數(shù)據(jù)
doubleoutput = compute_output(testdata[iTest].inputs,weights);
doubleerr = testdata[iTest].output - output;
//調(diào)整輸入端的權(quán)值
for (int i = 0 ; i 《 nInputs ; ++i)
{
weights[i] = weights[i] + rho * err* testdata[iTest].inputs[i];
}
weights[nInputs] = weights[nInputs] +rho * err;
cout《《“mse:”《《caculate_mse(testdata,weights)《《endl;
}
for(int w = 0 ; w 《 nInputs + 1 ; ++w)
{
cout《《“weight”《《w《《“:”《《weights[w]《《endl;
}
cout《《“\n”;
for (int i = 0 ;i 《 nTests ; ++i)
{
cout《《“rightresult:êo”《《testdata[i].output《《“\t”;
cout《《“caculateresult:” 《《 classify_output(compute_output(testdata[i].inputs,weights))《《endl;
}
//
char temp ;
cin》》temp;
return 0;
}
評論
查看更多