粒子过滤器:如何进行重采样?


24

我了解粒子过滤器的基本原理,并尝试实现一个。但是,我挂了重采样部分。

从理论上讲,这很简单:从一组旧的(加权的)粒子中,绘制一组替换的新粒子。这样做时,请偏爱具有高重量的那些粒子。高权重的粒子更容易被吸引,而低权重的粒子则更少地被吸引。也许只有一次或根本没有。重新采样后,将为所有权重分配相同的权重。

我关于如何实现这一点的第一个想法基本上是这样的:

  1. 标准化权重
  2. 将每个重量乘以颗粒总数
  3. 将这些缩放后的权重舍入到最接近的整数(例如,int()在Python中使用)

现在我应该知道绘制每个粒子的频率,但是由于舍入误差,最终我得到的粒子少于重新采样步骤之前的粒子

问题:我如何“填充”缺少的粒子,以便获得与重新采样步骤之前相同数量的粒子?或者,如果我在这里完全偏离轨道,如何正确重新采样?

Answers:


18

您遇到的问题通常称为样本贫困。我们可以通过一个非常简单的示例来了解为什么您的方法会受此困扰。假设您有3个粒子,其归一化权重为0.1、0.1、0.8。然后将每个权重乘以3得到0.3、0.3和2.4。然后四舍五入产生0、0、2。这意味着您不会选择前两个粒子,而最后一个会被选择两次。现在您只剩下两个粒子了。我怀疑这是您说“由于舍入错误而导致我的粒子减少了”时所看到的。

另一种选择方法如下。

  1. 标准化权重。
  2. 计算权重的累加和的数组。
  3. 随机生成一个数字,并确定该数字所属的累积权重数组中的哪个范围。
  4. 该范围的索引将对应于应创建的粒子。
  5. 重复进行直到获得所需数量的样本。

因此,使用上面的示例,我们将从归一化的权重开始。然后,我们将计算数组[0.1,0.2,1]。从那里我们计算出3个随机数,例如0.15、0.38和0.54。这将使我们选择第二个粒子一次,并且选择第三个粒子两次。关键是它使较小的粒子有传播的机会。

需要注意的一件事是,尽管这种方法可以解决贫困问题,但可能导致解决方案欠佳。例如,可能没有一个粒子与您的给定位置完全匹配(假设您正在使用该粒子进行本地化)。权重只会告诉您哪些粒子最匹配,而不是匹配的质量。这样,当您获取其他读数并重复该过程时,您可能会发现所有粒子都集中在一个不正确的位置。这通常是因为没有好的粒子开始。


1
感谢您的深刻反馈!您建议的选择方法似乎很熟悉。如果我没记错的话,那是解决样本贫困问题的一种常用方法。我以前看过它,但从未真正了解执行此过程的原因。现在我知道了!
丹尼尔·埃伯茨

2
我认为您对抽样贫困的解释可能有点误导。张贴者散布颗粒的事实是由于不合适的重采样方法所致。粒子贫困是指您的后部分布不再能充分代表粒子的情况。
雅各布2012年

9

正如我猜到的那样,您提出的重采样方法有些瑕疵,因为它不应更改粒子数(除非您愿意)。原理是权重代表相对于其他粒子的相对概率。在重采样步骤中,您从一组粒子中进行绘制,以便对于每个粒子,归一化的重量乘以粒子数表示平均得出粒子的次数。那样您的想法是正确的。仅通过使用舍入而不是采样,您将始终消除期望值小于一半的粒子。

有多种方法可以正确执行重采样。有一篇不错的论文叫做《关于粒子滤波器的重采样算法》,比较了不同的方法。简要介绍一下:

  • 多项式重采样:想象一下一条纸,其中每个粒子都有一个截面,其长度与重量成正比。N次随机选择条带上的某个位置,然后选择与该截面关联的粒子。

  • 残余重采样:此方法尝试通过首先为每个粒子分配其期望值的整数下限,然后将其余部分留给多项式重采样来减少采样的方差。例如,一个预期值为2.5的粒子在重采样集中将有2个副本,而另一个预期值为0.5的副本。

  • 系统重采样:取一个带有规则间距标记的标尺,以使N个标记的长度与纸条的长度相同。随机将标尺放在试条旁边。取标记处的颗粒。

  • 分层重采样:与系统重采样相同,不同之处在于标尺上的标记未均匀放置,而是作为N个随机过程添加,从间隔0..1 / N开始采样。

因此,回答您的问题:您已实施的方法可以扩展为残差抽样的形式。您可以通过基于提醒的多项分布来采样来填补丢失的空位。


+1已回答了我的后续问题:)
丹尼尔·埃伯茨

5

对于正确实现重采样的python代码示例,您可能会发现此github项目很有用:https : //github.com/mjl/particle_filter_demo

另外,它带有自己的重采样过程的可视化表示形式,应该可以帮助您调试自己的实现。 粒子过滤器操作

在此可视化中,绿海龟显示实际位置,大灰点显示估算的位置,会聚时变为绿色。权重从可能(红色)变为不可能(蓝色)。


感谢您的链接。看看其他人如何实现算法总是很有见地的。
丹尼尔·埃伯茨

这是粒子过滤器收敛的可视化。不确定对问题有什么见解。
雅各布2012年

我包含了可视化内容,因为它是我发布的代码所产生的内容-有关如何正确实现重采样的示例。
伊恩

1

一种简单的方法是numpy.random.choice(N,N,p = w,replace = True)其中N为否。W =归一化权重。


欢迎来到narayan的Robotics。您能否扩大这个答案一些?例如,为什么要使用随机选择?什么是p你的功能?您可以做的越详细,对以后遇到相同问题的访问者来说越有用。
Chuck

1

我使用@narayan的方法来实现我的粒子过滤器:

new_sample = numpy.random.choice(a=particles, size=number_of_particles, replace=True, p=importance_weights)

a是您要采样的粒子的向量,大小是粒子的计数,p是其归一化权重的向量。replace = True处理带有替换的引导程序采样。返回值是新粒子对象的向量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.