基於LMS算法的自適應濾波器

基於LMS算法的自適應濾波器

LMS(Least Mean Square)

LMS(Least Mean Square),最小均方算法,是一種自適應濾波算法,最早由Widrow和Hoff提出,此算法不需要已知輸入信號和期望信號,當前時刻的權重是通過上一個時刻的權重加上負均方誤差梯度的比例得到的。權重公式:
在這裏插入圖片描述
β爲學習率,或者稱爲收斂步長,恰當的學習率可以使結果更趨近於真實。▽k是目標函數的梯度。

假設兩地通信,說話聲音信號single,會因爲與噪音noise結合生成新的被幹擾的信號input,根據這三個條件設計出符合該假設的濾波器。

利用上面的公式推導得出下面的公式:
在這裏插入圖片描述

分析

使用計算機模擬的方法十分簡單,步驟如下:
①創建資料集,產生single和noise的值;

②劃分資料集,一部分作爲訓練LMS模型;另一部分用來檢測模型誤差大小。

③建立模型,理解LMS算法原理後,可以根據公式建立一個基於LMS的模型:
i 設置權重空間,我們通過公式已經知道權重W是一個一維矩陣,因此用來要設置它的空間大小,這裏假設是4,那麼初始化的權重是[0, 0, 0, 0]。

ii 設置偏置項b,訓練產生的結果爲了更加接近原始資料,根據訓練的迭代可以得出一個與input存在線性關係的偏置項b,爲了不影響訓練,初始值設置爲0。

④訓練模型,導入訓練集,設置學習率,LMS模型將會不斷調整濾波器全向輪,使權矢量和偏置項接近最優解。

⑤使用模型,訓練已經完成,將已有資料導入模型進行處理,然後根據結果來調整參數大小,降低誤差。

實現

# python-Noise Cancellation
# coding=utf-8
import numpy
import matplotlib.pyplot as plt
class LMS:
    def __init__(self, vector_size):
        self.size   = vector_size
        self.weight = [0] * vector_size
        self.b      = 0
    def train(self, trainX, trainY, beta = 1e-3):
        step        = len(trainX)
        if step < self.size:
            return
        for i in range(self.size - 1, step):
            x       = trainX[i - self.size + 1: i + 1]
            value   = numpy.sum(self.weight * x)
            error   = trainY[i] - value
            self.weight += 2 * beta * error * x
            self.b      += 2 * beta * error
        return
    def predict(self, input):
        predictY    = [numpy.nan] * (self.size - 1)
        for i in range(self.size - 1, len(input)):
            x       = input[i - self.size + 1: i + 1]
            predictY.append(numpy.sum(self.weight * x) + self.b)
        return predictY
    def evaluate(self, predictY, realY):
        loss = (predictY - realY) ** 2
        MSE = numpy.mean(loss[self.size - 1:])
        return MSE
numpy.random.seed(7)
vector_size = 4
step        = 200
beta        = 1e-4
t           = numpy.mgrid[0 : 2 : (2 - 0) / step]
single      = 2 * numpy.sin(t) + 1.5
v           = numpy.random.normal(0, 1, step)
noise       = (v - 1.34) ** 2 + 5.2
input       = single + noise

train_size  = int(step * 0.7)
test_size   = step - train_size
trainX      = input[0 : train_size]
testX       = input[train_size : step]
trainY      = single[0 : train_size]
testY       = single[train_size : step]

model       = LMS(vector_size)
model.train(trainX, trainY, beta)
train_Pre   = model.predict(trainX)
test_Pre    = model.predict(testX)
train_Cost  = model.evaluate(train_Pre, trainY)
test_Cost   = model.evaluate(test_Pre, testY)
output      = model.predict(input)
cost        = model.evaluate(output, single)
print('train MSE:', train_Cost)
print('test  MSE:', test_Cost)
print('all   MSE:', cost)
plt.plot(single, 'r-', linewidth=1, label='single')
plt.plot(input,  'b-', linewidth=1, label='input')
plt.plot(output, 'g-', linewidth=1, label='predict')
plt.legend()
plt.grid(True)
plt.show()

繪圖結果:
在這裏插入圖片描述

模型效果:
train MSE: 0.42479847238705815
test MSE: 0.22478527148613403
all MSE: 0.3627344052096806

擴大資料集範圍:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章