东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 1366|回复: 2
打印 上一主题 下一主题

[通信原理] 自适应滤波器之LMS算法实现Demo

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14429
QQ
跳转到指定楼层
楼主
发表于 2021-4-16 09:08:14 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式


自适应滤波器之LMS算法实现Demo


  1. # -*- coding: utf-8 -*-
  2. __author__ = u'东方耀 微信:dfy_88888'
  3. __date__ = '2021/4/15 11:27'
  4. __product__ = 'PyCharm'
  5. __filename__ = '01_自适应LMS滤波算法'

  6. import numpy as np
  7. import matplotlib.pyplot as plt

  8. # 自适应滤波器之LMS算法实现Demo

  9. # 定义向量的内积
  10. # np.convolve()
  11. # np.dot()
  12. # def multiVector(A, B):
  13. #     # 两个向量的内积 对应元素相乘后求和  np.dot()
  14. #     C = sc.zeros(len(A))
  15. #
  16. #     for i in range(len(A)):
  17. #         C[i] = A[i] * B[i]
  18. #
  19. #     return sum(C)


  20. def inVector(vector, b, a):
  21.     '''
  22.     从一个长向量vector中按索引截取并返回倒着的序列
  23.     :param vector:
  24.     :param b: 终点索引
  25.     :param a: 起点索引
  26.     :return:
  27.     '''
  28.     sub_vector = np.zeros(shape=(b-a+1, ))

  29.     for i in range(b - a + 1):
  30.         sub_vector[i] = vector[i + a]

  31.     return sub_vector[::-1]


  32. # lMS算法的函数

  33. def LMS(xn, dn, M, learning_rate, itr):
  34.     '''
  35.     N阶线性系统出发
  36.     自适应滤波之LMS算法实现
  37.     :param xn: 输入原始信号或序列
  38.     :param dn: 期望的
  39.     :param M: 滤波器阶数=64
  40.     :param learning_rate: 学习率
  41.     :param itr: 采样点数
  42.     :return:返回的yn与en是 输出和误差
  43.     '''
  44.     en = np.zeros(shape=(itr, ))   # 误差 或 损失 信号
  45.     # 空间复杂度有点高 需要优化
  46.     W = [[0] * M for i in range(itr)]  # 滤波器的参数 初始化 列表长度=采样点数 每个元素有滤波器阶数个值
  47.     # print(len(W), len(W[0]))   10000 64

  48.     for k in range(itr)[M - 1:]:
  49.         # 为什么要从M-1开始切片:63到最后 为根据前面的信号样点作为期望值
  50.         # 开始的:k=63  k-M+1=0
  51.         x = inVector(xn, k, k - M + 1)   # len(x) = 64 滤波器的阶数=滤波器长度 决定了输入信号样点的长度
  52.         # 那个LMS函数里的d是滑动平均作为期望  问题:如果噪声均值不为0 效果会差吧?
  53.         # 输入原始信号序列还是xn 但是filter是逐步滑动去滤的
  54.         d = x.mean()
  55.         # y是一次滤波操作的输出: W[k - 1]是上一次的滤波器的参数  x呢?不是xn吗?
  56.         # x是前面的 输入样点的 倒序   因为向量点乘要求:长度一致啊
  57.         # y = multiVector(W[k - 1], x)  一维滤波
  58.         y = np.dot(W[k - 1], x)

  59.         # print("第一次应该为0:", y)
  60.         # assert 0 == 1, "停"
  61.         # 误差信号是从k=63开始的
  62.         en[k] = d - y   # 误差如果很小了 可以不需要迭代了
  63.         # 循环里 每输入一个序列就更新一次滤波器参数  更新频率很高
  64.         # 梯度= -2 * learning_rate * en[k] * x
  65.         # 标准时域LMS算法的更新公式  最终发现:误差越来越小
  66.         W[k] = np.add(W[k - 1], 2 * learning_rate * en[k] * x)

  67.     # 求最优时滤波器的输出序列

  68.     yn = np.inf * np.ones(len(xn))  # inf 是无穷大的意思
  69.     # 先在原始输入序列信号上 不断改进自适应滤波的权重参数
  70.     filter_best = W[len(W) - 1]
  71.     # 最后根据得到的最优滤波器,计算原始输入信号的输出

  72.     for k in range(itr)[M - 1:]:
  73.         x = inVector(xn, k, k - M + 1)
  74.         # x才是真正的输入信号序列,错了,x是滤波操作的输入

  75.         # yn[k] = multiVector(W[len(W) - 1], x)
  76.         # 默认:最后的滤波器参数就是最优的
  77.         yn[k] = np.dot(filter_best, x)

  78.     return (yn, en)


  79. if __name__ == "__main__":
  80.     # 参数初始化

  81.     itr = 10000  # 采样的点数
  82.     # sigma = 0.12
  83.     noise_size = itr

  84.     X = np.linspace(0, 4 * np.pi, itr, endpoint=True)
  85.     Y = np.sin(X)
  86.     signal_array = Y  # [0.0]*noise_size  真实的信号
  87.     noise_array = np.random.normal(0, 0.3, noise_size)  # 加上高斯白噪声
  88.     # 高斯白噪声是分析信道加性噪声的理想模型,通信中的主要噪声源——热噪声就属于这类噪声
  89.     """noise_array = []
  90.     for x in range(itr):
  91.         noise_array.append(random.gauss(learning_rate,sigma))"""
  92.     signal_noise_array = signal_array + noise_array   # 信号+噪声

  93.     M = 64  # 滤波器的阶数

  94.     learning_rate = 1e-4

  95.     xn = signal_noise_array  # 原始输入端的信号为被噪声污染的正弦信号
  96.     # xn并非输入序列,因为输入序列必须与filter长度一致

  97.     dn = signal_array  # 对于自适应对消器,用dn作为期望 实际没有用这个

  98.     # 调用LMS算法

  99.     (yn, en) = LMS(xn, dn, M, learning_rate, itr)

  100.     # 画出图形

  101.     plt.figure(1)

  102.     plt.plot(xn, label="$signal_noise[        DISCUZ_CODE_0        ]quot;)

  103.     plt.plot(dn, label="$signal[        DISCUZ_CODE_0        ]quot;)

  104.     plt.xlabel("Time(s)")

  105.     plt.ylabel("Volt")

  106.     plt.title("original signal xn and desired signal dn")

  107.     plt.legend()

  108.     plt.figure(2)
  109.     # plt.plot(xn,label="$xn[        DISCUZ_CODE_0        ]quot;)
  110.     # plt.plot(xn,label="$xn[        DISCUZ_CODE_0        ]quot;)
  111.     plt.plot(signal_array, label="$signal_array[        DISCUZ_CODE_0        ]quot;)
  112.     plt.plot(yn, label="$yn[        DISCUZ_CODE_0        ]quot;)

  113.     plt.xlabel("Time(s)")

  114.     plt.ylabel("Volt")

  115.     plt.title("out signal yn best for filter")

  116.     plt.legend()

  117.     plt.figure(3)

  118.     plt.plot(en, label="$error[        DISCUZ_CODE_0        ]quot;)

  119.     plt.xlabel("Time(s)")

  120.     plt.ylabel("Volt")

  121.     plt.title("error between y and d")

  122.     plt.legend()

  123.     plt.show()
复制代码


01.png (134.31 KB, 下载次数: 132)

01.png

02.png (261.14 KB, 下载次数: 132)

02.png

03.png (130.38 KB, 下载次数: 134)

03.png

04.png (129.59 KB, 下载次数: 137)

04.png

05.png (176.75 KB, 下载次数: 133)

05.png

06.png (125.8 KB, 下载次数: 137)

06.png

07.png (79.28 KB, 下载次数: 137)

07.png

08.png (116.76 KB, 下载次数: 132)

08.png

lr1.png (15.09 KB, 下载次数: 136)

lr1.png

lr2.png (21.67 KB, 下载次数: 134)

lr2.png

lr3.png (24.72 KB, 下载次数: 133)

lr3.png

lr4.png (21.9 KB, 下载次数: 133)

lr4.png

lr5.png (22.3 KB, 下载次数: 135)

lr5.png

lr6.png (31.03 KB, 下载次数: 136)

lr6.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14429
QQ
沙发
 楼主| 发表于 2021-4-16 09:20:06 | 只看该作者
LMS算法步长调整原则:滤波器的收敛速度和稳态误差是一对矛盾。当拥有较大的步长因子会加快滤波器的收敛速度,但同时也会增大稳态失调误差。较小的步长因子会减小滤波器的收敛速度但会拥有较小的稳态误差
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14429
QQ
板凳
 楼主| 发表于 2021-4-16 09:22:05 | 只看该作者
东方耀 发表于 2021-4-16 09:20
LMS算法步长调整原则:滤波器的收敛速度和稳态误差是一对矛盾。当拥有较大的步长因子会加快滤波器的收敛速 ...

为了克服这一矛盾,在现有固定步长算法的基础上我们提出了新的算法—变步长自适应算法。其优点是步长值随误差的改变而改变。在误差较大的时候步长因子也大以获得更快的收敛速度;当收敛过程接近稳态,误差小的时候其步长因子也小以获得较小的稳态误差
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-4-19 15:26 , Processed in 0.190021 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表