滤波算法[2]----理解离散贝叶斯滤波器(上)

离散过滤器(Discrete Filter)

为了方便对离散贝叶斯过滤器的理解,开始使用了下面的一个例子,十分形象生动的阐述了离散贝叶斯的原理,以及实现过程。
虽然我本篇博客的目的不是为了直接对书进行翻译,但是这个例子很妙,从这个例子讲起来也是个十分不错的选择。

追踪狗狗的位置

作者假设了一个场景,他把他的狗----丧彪(书里面叫 Simon) 带到了公司。
在这里插入图片描述
丧彪(的脖子上带着一个可以实时检测与物体的距离和运动方向和速度的传感器。假设丧彪只会在公司的走廊里面跑动的话,当经过门的时候传感器就会回传“门”,当没有在门附近的时候传感器就会回传“走廊”。假设这个公司是个的走廊是个圆形的结构,也就是丧彪从走廊的开始一直向一个方向跑,一会它就会经过一圈,又会再跑回来原来的位置。

给这个圆形的场地划个区域,从 0 ~ 9 共 10 个区域。这个场地一共有三个门,和 7 个走廊.示意图如下,除了门之外都是走廊部分。

在这里插入图片描述
先使用一组数组来表示一下,丧彪在这个圆形区域中各部分可能的概率。
在这里插入图片描述
为啥都是 0.1? 因为刚开始不知道丧彪的位置,所以在这个圆形中的每一个位置都是十分之一,也就是 0.1。
现代贝叶斯统计学(Bayessian statistics)中这被称为先验(prior)。先验就是在进行测量之前给出的概率,先验的全名叫做先验概率分布(prior probability distribution) 。这里所有先验的概率加在一起必须要是 1 ,因为 1 就代表了 100%,就拿这个追踪丧彪的例子来说,丧彪肯定会在这10个位置之内,不可能“越狱”逃跑或者“瞬间移动”到别的地方去。

上面已经使用数组表示了丧彪在 10 个位置中出现的概率,接下来使用另一个数组来标记一下门和走廊,门记作“1”走廊记作“0”.

在这里插入图片描述

如果假设丧彪项圈的传感器回传的都是“1”,这意味着丧彪在门的位置上,但是究竟是那一个人是不确定的。但是一共有 3 个门,所以说在各个门前的概率为 1/3 . 下图为 python 代码,和其生成的柱形图/直方图。

在这里插入图片描述
当然,我们也可以将概率化为小数的形式。

在这里插入图片描述

传感器误差

没有完美的传感器,只是误差的大小有区别,误差的形式有区别。那么如何将传感器产生的误差引入我们的存储位置概率的数组呢?
因为概率的综合要是 1,那么如果引入误差的话,在门旁边的概率就应该各自减小一些,以分摊到其他部分中。如下图

在这里插入图片描述
因为传感器都会噪声,但是一个传感器被设计出来肯定测得的结果正确要大于错误。如果不是这样的话这玩意被设计出来就没有什么意义了。
现在我们假设传感器测得的正确情况大于错误情况的 3 倍(实际情况肯定不只3倍),这种说法说起来可能和式子比起来可能不够直观:

在这里插入图片描述
scale 是比例,prob correct 是正确的概率,prob incorrect 是错误概率。对于传感器误差就很直观了。

在这个时候如果传感器回传“门” 我们的概率数组就要变成下图中的样子了。

在这里插入图片描述
上图还是很好理解的吧~ 假设传感器接收到了“门”的位置。正确又是错误概率的三倍,也就是门的概率要是走廊的三倍,这样就有了这个直方图。但是这里面有个很关键的问题,概率的总和变为了 1.6 (因为只是将门的位置乘上了scale)。所以我们要想个办法把总和改回原来的 1 才行。

在可以使用数学中的归一方法(normalize function)。这个方法很简单,每一项分别除以总和就可以了。

在这里插入图片描述
好了再把我们到目前位置学的都利用起来。这里还假设我们在传感器上读到的还是“门”的位置。那也就是说,首先要对整个概率分布直方图中“门”部门的概率乘上传感器的比例(scale),在使用归一算法(normalization function)调整比例的总额。

def scaled_update(hall, belief, z, z_prob): 
    scale = z_prob / (1. - z_prob)       # 计算比率
    belief[hall==z] *= scale             # 将概率数组中接收到的位置乘以比率
    normalize(belief)                    # 归一化操作

    belief = np.array([0.1] * 10)        # 初始化概率数组
    scaled_update(hallway, belief, z=1, z_prob=.75)

    print('sum =', sum(belief))
    print('probability of door =', belief[0])
    print('probability of wall =', belief[2])
    book_plots.bar_plot(belief, ylim=(0, .3))

下面的图就是这个 python 代码的输出。这里大家需要看懂 scaled_update 函数的实现。

在这里插入图片描述
上图就表示了我们在初始阶段对于概率的模型,这个时候由于没有引入其他的一些外部信息,比如实际的测量值等。目前这个情况又称作”后验概率分布“也可以称为“后验”。这个术语有别于“先验”,因为先验是要结合实际的测量信息后得出的。

还有一个在这里很重要的的术语叫做可能性(likelihood)。是给定位置测量值的可能性,其实在代码中使用比率乘以概率的时候 belief[hall==z] *= scale 就是在做这个事。与分布概率不同的地方是,可能性的总和不用是 1,所以还要进行归一化。

后验有如下等式:

在这里插入图片描述

在滤波算法中一般处理前的状态叫做“先验(prior)”或者“预测值(prediction)”,使用滤波算法进行处理后得值成为“后验(posterior)”或者“评估值(estimated)”。

考虑丧彪的移动

我们门和走廊的位置关系用数组来表示就是 [1, 1, 0, 0, 0, 0, 0, 0, 1, 0] , 那么可不可以说如果我们连续的从传感器接收到 “门”“向右移动”“门”,这三个位置,丧彪就一定在 数组的第 0 位也,就是第一个门的位置呢?

NO! 不可以,虽然这种概率很高,由于误差的存在,这种情况只能说有很大的可能(接近 100%),而不能说就一定在第一个门的位置。

所以就算传感器接收到了丧彪移动的信息,并不能将其信息和实际的位置来对应。而是要将表示位置的概率数组整体移动,现在假设丧彪向右移动了一个位置:

在这里插入图片描述
接下来为了能更好的介绍后面的文章,这里需要解释一下几个术语:

系统( system )就是我们试图建立模型或者过滤器的事务,这里的系统就是指丧彪。态(state)就是当前的配置或者值,在这篇博客中就是指丧彪的位置。这里的态是不能准确得知的,所以我们要借助滤波器来对这个系统进行态的评估(estimated state)。
像上一篇博客中,系统为了是会根据测量值和预测值对评估值进行更新(update),这个过程也被称为系统进化(system evolution)或者系统繁衍(system propagation)。这个更新的行为也可以推导出系统伴随时间所产生的变化。

对这个系统行为进行建模的过程称为“过程模型(process model)”。在这篇博文中“过程模型”就是丧彪随着时间的流逝其位置变化的过程。但是这种建模是无法模拟丧彪的准确位置的,这其中就存在误差,我们管这种误差叫做“系统误差(system error)”或者“过程误差(process error)”。

来看一个小学问题,如果丧彪在位置 17m 处,以 15m/s 的速度,现在预测两秒后的位置应该在哪里:

x ‾ = 17 + ( 15 ∗ 2 ) = 47 \begin{aligned} \overline{x} = 17 + (15 * 2) \\ = 47 \end{aligned} x=17+(152)=47
现在我们已经依靠速度对位置进行了预测,可以把预测的过程写成下面的函数,对应上面的式子, x k x_k xk 就是丧彪的当前的位置/状态 17。

( ‾ x ) k + 1 = f ( ⋅ ) + x k \overline(x)_{k+1} = f(\cdot) + x_k (x)k+1=f()+xk

引入一些预测位置中的不确定性

为了更好的将传感器的误差(不确定性)也纳入滤波系统中,我们假设丧彪项圈内的传感器蒸正确率为 80%,剩下的两个 10% 是当前检测正确位置的左边和右边。

如果当前丧彪的位置在 3 ,那么如果传感器回传显示丧彪向右移动了 2 个位置。那么实际上应该是丧彪有 80% 的概率在位置5,10%的概率在位置4 ,10% 的概率在位置6.

在这里插入图片描述

因为传感器存在误差,我们也不能准确的丧彪的位置。如果当前丧彪 60% 在位置 3 ,40% 在位置 2。拿这种情况再向右移动 2 个位置呢?

在这里插入图片描述

下面解释一下上图各个位置的具体数值:

位置 3 :0.4 * 0.1 = 0.04
位置 4 :0.4 * 0.8 + 0.6 * 0.1 = 0.38
位置 5 :0.6 * 0.8 + 0.4 * 0.1 = 0.52
位置 6 :0.6 * 0.1 = 0.06

所以大家现在想象一下,如果每一步都会分摊一些到别的位置,或者说每次迭代都会丢失一些数据。那么经过长期的迭代一定会平摊在图上。
下图就是迭代 70 次后的样子,几乎概率相同。根本没有办法判断丧彪的位置了。所以接下来就要卷积出马了。

在这里插入图片描述

使用卷积来避免上述的问题

\

卷积的理解

知乎作者 palet 的回答,非常的精彩!原文链接。

卷积的积分形式:

( f ∗ g ) ( t ) = ∫ 0 t  ⁣ f ( τ )   g ( t − τ )   d τ (f \ast g) (t) = \int_0^t \!f(\tau) \, g(t-\tau) \, \mathrm{d}\tau (fg)(t)=0tf(τ)g(tτ)dτ
卷积的加权累加形式:

( f ∗ g ) [ t ] = ∑ τ = 0 t  ⁣ f [ τ ]   g [ t − τ ] (f \ast g) [t] = \sum\limits_{\tau=0}^t \!f[\tau] \, g[t-\tau] (fg)[t]=τ=0tf[τ]g[tτ]

相信大家在看过我推荐的知乎牛文之后都已经基本掌握卷积的原理了。这里也是一样,这里需要处理的函数是我们的概率数组,而 g(x) 则是我们前面假设的传感器传感器概率 [0.1, 0.8, 0.1]

下图就是进行了卷积后预测丧彪在位置 5 的概率。

在这里插入图片描述
下面就是实现卷积预测的 python 代码:


# pdf:     概率分布数组
# offset: 需要计算的卷积前需要移动概率数组中的位置
# kernel: g(x) 用与处理概率数组的数组

def predict_move_convolution(pdf, offset, kernel):
    N = len(pdf)
    kN = len(kernel)
    width = int((kN - 1) / 2)

    prior = np.zeros(N)
    for i in range(N):
        for k in range (kN):
            index = (i + (width-k) - offset) % N
            prior[i] += pdf[index] * kernel[k]
    return prior

第一个 for 需要循环 N 次,也就是 pdf(概率数组) 的长度。第二级的 for 需要循环 kN(kernel 数组的长度此处为 3) 次。
模上 N 是为了让 index 不超过 pdf 数组长度。所以代码中的 index 就是每次在 pdf 移动一位之后再取 3 位。之后用 pdf 中 3 位中每一位和 kernel 中的每一位相乘,再把这三个加起来。也就是点积。
至于 offset 的作用,也就是让每次 index 都少 offset 长度,每次减少 offset 就相当于开始之前就将 pdf 向右平移 offset(说实话,这里我竟然要想 5 分钟,手艺下滑了)。

这里还有一张图,这个图中修改了 kernel 数组的值,并且移动了 3 步。

在这里插入图片描述
上图中 predict 函数的实现就是和上面的卷积代码是一样的。

整合预测和运动更新

在这篇博客的前面介绍了 scaled_update 算法,在上一部分介绍了使用卷积的办法来预测未来位置的概率。

下面代码中的 update 函数就是 我们的 scaled_update 算法。当丧彪的项圈回传”1“也就是门的位置时,首先更新一下位置:

hallway = np.array([1, 1, 0, 0, 0, 0, 0, 0, 1, 0])
prior = np.array([.1] * 10)
likelihood = lh_hallway(hallway, z=1, z_prob=.75)
posterior = update(likelihood, prior)

在这里插入图片描述

kernel = (.1, .8, .1)
prior = predict(posterior, 1, kernel)

在这里插入图片描述
如果再次接收到门的信号时,再次更新位置

likelihood = lh_hallway(hallway, z=1, z_prob=.75)
posterior = update(likelihood, prior)

在这里插入图片描述
这里再次对丧彪进行位置预判(offset == 1, 意味着向右移动了一个位置)。然后再次更新,让我们看一下现在的图。

prior = predict(posterior, 1, kernel)
likelihood = lh_hallway(hallway, z=0, z_prob=.75)
posterior = update(likelihood, prior)

在这里插入图片描述
这里位置”2“的概率高达 35%,从图中可知,我们设计的过滤器已经生效了。

离散贝叶斯算法(Discrete Bayes Algorithm)

这里关于离散贝叶斯算法的流程图和前面的 g-h 算法十分的相近(或者说是一摸一样)。

在这里插入图片描述

这里面也是由两个关键的步骤:1. 预测;2.更新。

x ˉ = x ∗ f x ( ∙ )    Predict Step x = ∥ L ⋅ x ˉ ∥    Update Step \begin{aligned} \bar {\mathbf x} &= \mathbf x \ast f_{\mathbf x}(\bullet)\, \, &\text{Predict Step} \\ \mathbf x &= \|\mathcal L \cdot \bar{\mathbf x}\|\, \, &\text{Update Step}\end{aligned} xˉx=xfx()=LxˉPredict StepUpdate Step

书上也为这个算法提供了伪代码:

初始化
1. 初始化最初状态的概率。

预测:
1. 基于当前系统的行为,预测下一步的状态;
2. 要将之前没有考虑的因素(就是 kernel 数组,其用于表示传感器的误差)调整到预测概率之中。

更新:
1. 接收实际测量值,并与之概率进行对应;
2. 计算测量值和实际状态的可能性;
3. 通过可能新去更新概率,从而获得我们要的评估值。

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/679094.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WebStorm 2024.1.1 Mac激活码 前端开发工具集成开发环境(IDE)

WebStorm 2024 Mac激活码 搜索Mac软件之家下载WebStorm 2024 Mac激活版 WebStorm 2024 功能介绍 WebStorm 2024是由JetBrains公司开发的一款专为前端开发设计的集成开发环境(IDE)。它提供了一整套功能,旨在提高Web开发者的工作效率和代码质…

Nextjs使用教程

一.手动创建项目 建议看这个中文网站文档,这个里面的案例配置都是手动的,也可以往下看我这个博客一步步操作 1.在目录下执行下面命令,初始化package.json文件 npm init -y2.安装react相关包以及next包 yarn add next react react-dom // 或者 npm install --save next react…

特步公主与七匹狼公子举行婚礼:“校服是你,婚纱也是你”!95后“二代”们开始接班?

从校服到婚纱,两位福建晋江系企业的“二代”上演了一出豪门青梅竹马的网络小说情节。 6月1日是个有意思的日子,有人庆祝儿童节,有人举办婚礼。 当天晚上,特步集团“小公主”丁佳敏在其社交媒体平台官宣了喜讯,并且晒…

重磅消息! Stable Diffusion 3将于6月12日开源 2B 版本的模型,文中附候补注册链接。

在OpenAI发布Sora后,Stability AI也发布了其最新的模型Stabled Diffusion3, 之前的文章中已经和大家介绍过,感兴趣的小伙伴可以点击以下链接阅读。Sora是音视频方向,Stabled Diffusion3是图像生成方向,那么两者没有必然的联系&…

Nginx在线部署和离线部署方式

Nginx 有两种安装方式: 1)在线安装的方式 1.添加Nginx 到yum源 sudo rpm -Uvh <http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm> 2.安装Nginx,直接使用yum方式 yum install -y nginx 3.启动nginx,刚安装的nginx不…

AI程序员来了,大批码农要失业

根据GitHub发布的《Octoverse 2021年度报告》&#xff0c;2021年中国有755万程序员&#xff0c;排名全球第二。 ChatGPT的出现&#xff0c;堪比在全球互联网行业点燃了一枚“核弹”&#xff0c;很多人都会担心“自己的工作会不会被AI取代”。 而2024年的AI进展速度如火箭般&am…

搭建chattts应用,做文字转语音

下载代码 git clone https://github.com/2noise/ChatTTS.git下载endpoint并上传&#xff1a; https://huggingface.co/2Noise/ChatTTS/tree/main 将上面下载的文件上传到服务器上 修改webui.py 更改为本地模型地址 import os import random import argparseimport torch i…

Java常规题技术分享

一、数组排序和添加成员 设计类Student和类StudentClass。 (1) 类Student有字符串属性name、double属性grade和int属性age 有带参数的构造方法&#xff0c;可设置三个属性的值 有各个属性的置取方法 (2)类StudentClass有Student数组属性stus存放班级成员&#xff0c;有int…

【ARM Cache 与 MMU 系列文章 7.6 -- ARMv8 MMU 相关寄存器介绍】

文章目录 MMU 转换控制寄存器 TCR_ELxTCR_ELx 概览TCR_ELx 寄存器字段详解TCR 使用示例Normal MemoryCacheableShareability MMU 内存属性寄存器 MAIR_ELx寄存器结构内存属性字段使用实例 MMU 地址翻译表基址寄存器 TTBR0/1_ELxTTBR0_ELx 寄存器概述寄存器结构功能和用途编程示…

【C++修行之道】类和对象(四)运算符重载

目录 一、 运算符重载 函数重载和运算符重载有什么关系&#xff1f; 二、.*运算符的作用 三、运算符重载的正常使用 四、重载成成员函数 五、赋值运算符重载 1.赋值运算符重载格式 传值返回和引用返回 有没有办法不生成拷贝&#xff1f; 2. 赋值运算符只能重载成类的…

思维导图-vb.net开发带进度条的复制文件夹功能c#复制文件夹

你们谁写代码会用流程图来做计划&#xff0c;或者写项目总结报告&#xff1f; .net带进度条复制文件夹 方案 列出所有子文件夹&#xff0c;再创建&#xff0c;复制文件 大文件可以单独做进度条 缺点&#xff1a;设计会更复杂 直接…

让你的博客实现负载均衡

零、缘起 有时候博客突然挂了&#xff0c;发现服务器厂商出了问题&#xff0c;很忧伤&#xff0c;我正在写着或查阅自家博客那种不可xx的内容。这时想着&#xff0c;如果这个博客有负载均衡就好了&#xff0c;空了想着实现下。 一分钟了解负载均衡的一切 选择第二种【反向代…

衡量网络性能的指标

带宽 测速&#xff0c;下载速度一般是MB&#xff0c;运营商用的是b&#xff0c;之间有差别&#xff0c;100M带宽就是100M b 100个人访问同一个服务器&#xff0c;那么这个服务器的并发连接数就是100&#xff0c;有上限&#xff0c;受到性能的限制&#xff0c;当前面连接好多了…

【数据结构与算法 经典例题】链表的回文结构(图文详解)

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法 经典例题》C语言 期待您的关注 ​ 目录 一、问题描述 二、解题思路 三、C语言代码实现 一、问题描述 二、解…

链表反转--理解链表指针的基本操作

链表反转--理解链表指针的基本操作 链表反转的方法--主要是理解链表指针链表心得类节点是对象和指针区别&#xff1a; 链表反转的方法–主要是理解链表指针 根据值创建新列表 用一个链表指针代替整个新链表 两个链表的赋值 递归求解反向链表 用一个链表代替前后链表数…

解决使用gets(getchar)函数无法输入字符(字符串)和scanf_s函数显示缺少“scanf_s”整型参数的问题

一.函数介绍 gets函数&#xff1a; 该函数就是读取字符串&#xff0c;遇到空格不会停止&#xff0c;直到遇到换行字符&#xff0c;但是也会读取最后的换行字符&#xff08;这也就是我在写代码的时候遇到的一个问题&#xff09; getchar函数&#xff1a; 和gets函数类似&#x…

初识JAVA中的包装类,时间复杂度及空间复杂度

目录&#xff1a; 一.包装类 二.时间复杂度 三.空间复杂度 一.包装类&#xff1a; 在Java中&#xff0c;由于基本类型不是继承自Object&#xff0c;为了在泛型代码中可以支持基本类型&#xff0c;Java 给每个基本类型都对应了一个包装类型。 1 基本数据类型和对应的包装类 &am…

数字塔问题

#include<iostream> using namespace std; //从下向上得到最优值 void dtower(int a[][100],int s[][100],int n) {for(int in; i>1; i--){for(int j1; j<i; j){if(in)s[i][j]a[i][j];else{int ts[i1][j];if(t<s[i1][j1])ts[i1][j1];s[i][j]a[i][j]t;}}} } void…

MapReduce复习

一、MapReduce概述 1.定义 是分布式运算框架 MapReduce&#xff1a;用户处理业务相关代码自身的默认代码 2.优势劣势 优点&#xff1a; 1&#xff09;.易于编程。用户只关心业务逻辑&#xff0c;实现框架的接口。 2&#xff09;.良好的扩展性。可以动态增加服务器&#…

找不到steam_api64.dll,无法继续执行的原因及解决方法

电脑已经成为我们生活中不可或缺的一部分。然而&#xff0c;在使用电脑的过程中&#xff0c;我们经常会遇到一些常见的问题&#xff0c;其中之一就是找不到某个特定的动态链接库文件&#xff0c;比如steamapi64.dll。这个问题可能会导致某些应用程序无法正常运行&#xff0c;给…