粒子フィルター:リサンプリングの方法は?


24

粒子フィルターの基本原理を理解し、実装しようとしました。しかし、リサンプリングの部分にこだわった。

理論的には、非常に簡単です。古い(および重み付けされた)パーティクルのセットから、置換された新しいパーティクルのセットを描画します。その際、重量の大きい粒子を優先してください。ウェイトが高いパーティクルはより頻繁に描画され、ウェイトが低いパーティクルはより頻繁に描画されません。おそらく一度だけか、まったくないでしょう。リサンプリング後、すべての重みに同じ重みが割り当てられます。

これを実装する方法に関する私の最初のアイデアは、本質的にこれです:

  1. 重みを正規化する
  2. 各重量に粒子の総数を掛ける
  3. それらのスケーリングされた重みを最も近い整数に丸めます(たとえばint()Pythonで)

今、私は、各粒子を描画する頻度を知っている必要があります、しかし、原因丸めエラーのために、私が持っ終わる少ない粒子リサンプリングステップの前によります。

質問:リサンプリング手順の前と同じ数のパーティクルに到達するために、欠落しているパーティクルを「埋める」にはどうすればよいですか?または、ここで完全に軌道に乗っていない場合、どのように正しくリサンプリングしますか?

回答:


19

直面している問題は、多くの場合、サンプルの貧困と呼ばれます。かなり単純な例で、なぜあなたのアプローチがそれに苦しんでいるのかを見ることができます。3つのパーティクルがあり、それらの正規化されたウェイトが0.1、0.1、0.8であるとします。次に、各重みに3を掛けると、0.3、0.3、および2.4になります。次に、丸めにより0、0、2が得られます。これは、最初の2つのパーティクルを選択せず​​、最後のパーティクルを2回選択することを意味します。これで、2つのパーティクルになりました。これは、「丸め誤差のため、パーティクルが少なくなります」と言ったときにあなたが見ているものだと思います。

別の選択方法は次のとおりです。

  1. 重みを正規化します。
  2. 重みの累積和の配列を計算します。
  3. 番号をランダムに生成し、その番号が属する累積重み配列の範囲を決定します。
  4. その範囲のインデックスは、作成されるべきパーティクルに対応します。
  5. 必要なサンプル数になるまで繰り返します。

したがって、上記の例を使用して、正規化された重みから始めます。次に、配列[0.1、0.2、1]を計算します。そこから、0.15、0.38、および0.54という3つの乱数を計算します。これにより、2番目の粒子を1回、3番目の粒子を2回選択します。ポイントは、小さな粒子に伝播の機会を与えるということです。

注意すべきことの1つは、この方法は貧困を処理する一方で、次善の解決策につながる可能性があることです。たとえば、特定の場所に実際に一致するパーティクルはない場合があります(ローカライズにこれを使用している場合)。重みは、どのパーティクルが最も一致するかを示すものであり、一致の品質を示すものではありません。そのため、追加の測定値を取得してプロセスを繰り返すと、すべてのパーティクルが正しい場所ではない単一の場所にグループ化されることがあります。これは通常、開始する適切なパーティクルがなかったためです。


1
洞察に満ちた反応をありがとう!あなたが提案した選択方法はおなじみのようです。正しく思い出せば、それはサンプルの貧困問題を扱う一般的な方法でした。私は前にそれを見たことがありますが、この手順の理由を本当に理解したことはありません。今、私はよく知っています!
ダニエルエバーツ

2
サンプリング貧困のあなたの解釈は少し誤解を招くかもしれません。ポスターが粒子を失うという事実は、リサンプリングに不適切な方法によるものです。粒子の貧困とは、粒子によって後方分布が適切に表されなくなった場合です。
ヤコブ

9

あなたが自分自身を見つけたと思いますが、あなたが提案しているリサンプリング方法は、パーティクルの数を変えてはならないので、少し欠陥があります(あなたが望んでいない限り)。原則は、重みが他の粒子に対する相対的な確率を表すことです。リサンプリングのステップでは、各パーティクルについて、正規化された重みとパーティクル数の積が、パーティクルが平均して描画される回数を表すように、パーティクルのセットから描画します。その点であなたの考えは正しいです。サンプリングの代わりに丸めを使用することによってのみ、期待値が半分未満のパーティクルを常に排除します。

リサンプリングを適切に実行する方法はいくつかあります。パーティクルフィルターの再サンプリングアルゴリズムについて、さまざまな方法を比較するという素晴らしい論文があります。簡単な概要を示すために:

  • 多項リサンプリング:各粒子にセクションがあり、長さがその重量に比例する紙のストリップを想像してください。ストリップ上の位置をランダムにN回ピックし、セクションに関連付けられているパーティクルをピックします。

  • 残差リサンプリング:このアプローチは、最初に各パーティクルに期待値の整数フロアを割り当て、残りを多項リサンプリングに任せることにより、サンプリングの分散を削減しようとします。たとえば、期待値が2.5のパーティクルのリサンプリングセットには2つのコピーがあり、期待値が0.5の別のコピーがあります。

  • 体系的なリサンプリング:規則的な間隔のマークが付いた定規を使用して、Nマークが紙のストリップと同じ長さになるようにします。ストリップの横にルーラーをランダムに配置します。マークで粒子を取ります。

  • 階層化されたリサンプリング:ルーラー上のマークが均等に配置されず、間隔0..1 / NからサンプリングするN個のランダムプロセスとして追加されることを除いて、体系的なリサンプリングと同じです。

したがって、あなたの質問に答えるには、実装したものを残差サンプリングの形式に拡張することができます。リマインダーの多項分布に基づいてサンプリングすることにより、欠落しているスロットを埋めます。


フォローアップの質問にすでに回答していたため+1 :)
ダニエルエバーツ

5

リサンプリングを適切に実装するPythonコードの例については、次のgithubプロジェクトが役立つことがあります:https : //github.com/mjl/particle_filter_demo

さらに、リサンプリングプロセスの視覚的な表現が付属しているため、独自の実装のデバッグに役立ちます。 粒子フィルター操作

この視覚化では、アオウミガメは実際の位置を示し、大きな灰色の点は推定位置を示し、収束すると緑に変わります。重みは、ありそうなもの(赤)からありそうもないもの(青)になります。


リンクをありがとう。他の人がどのようにアルゴリズムを実装したかを見るのは常に洞察に富んでいます。
ダニエルエバーツ

これは、収束する粒子フィルターの視覚化です。それが質問に関してどのような洞察を提供しているかわからない。
ヤコブ

それは私が投稿したコードによって生成されるものであるため、視覚化を含めました-リサンプリングを適切に実装する方法の例です。
イアン

1

これを行う簡単な方法の1つは、numpy.random.choice(N、N、p = w、replace = True)です。Nはnoです。粒子およびw =正規化された重み。


Robotics、ナラヤンへようこそ。この回答をいくつか展開していただけますか?たとえば、なぜランダムな選択を使用するのですか?pあなたの機能には何がありますか?より詳細に答えることができれば、同じ問題を抱えている将来の訪問者にとってより有用になります。
チャック

1

@narayanのアプローチを使用して、パーティクルフィルターを実装します。

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

aはサンプリングする粒子のベクトル、sizeは粒子の数、pは正規化された重みのベクトルです。replace = Trueは、ブートストラップサンプリングを置換で処理します。戻り値は、新しいパーティクルオブジェクトのベクトルです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.