2012-05-03 56 views
13

Ich bin interessiert an der einfachen Algorithmus für Partikel-Filter hier gegeben: http://www.aiqus.com/upfiles/PFAlgo.png Es scheint sehr einfach, aber ich habe keine Ahnung, wie es geht praktisch. Irgendeine Idee, wie man es implementiert (nur um besser zu verstehen, wie es funktioniert)?Implementierung der sequentiellen Monte Carlo-Methode (Partikelfilter)

Edit: Dies ist ein großes einfaches Beispiel, das erklärt, wie es funktioniert: http://www.aiqus.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo-method-implementation?page=1#39950

Ich habe versucht, es in C++ zu implementieren: http://pastebin.com/M1q1HcN4 aber ich beachten Sie sicher, ob ich es richtig tun . Können Sie bitte überprüfen, ob ich es gut verstanden habe, oder es gibt ein Missverständnis nach meinem Code?

#include <iostream> 
#include <vector> 
#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_01.hpp> 
#include <boost/random/uniform_int_distribution.hpp> 

using namespace std; 
using namespace boost; 

double uniform_generator(void); 

#define N 4 // number of particles 

#define evolutionProba_A_A 1.0/3.0 // P(X_t = A | X_t-1 = A) 
#define evolutionProba_A_B 1.0/3.0 // P(X_t = A | X_t-1 = B) 
#define evolutionProba_B_B 2.0/3.0 // P(X_t = B | X_t-1 = B) 
#define evolutionProba_B_A 2.0/3.0 // P(X_t = B | X_t-1 = A) 

#define observationProba_A_A 4.0/5.0 // P(Y_t = A | X_t = A) 
#define observationProba_A_B 1.0/5.0 // P(Y_t = A | X_t = B) 
#define observationProba_B_B 4.0/5.0 // P(Y_t = B | X_t = B) 
#define observationProba_B_A 1.0/5.0 // P(Y_t = A | X_t = A) 

/// =========================================================================== 

typedef struct distrib { float PA; float PB; } Distribution; 

typedef struct particle 
{ 
    Distribution distribution; // e.g. <0.5, 0.5> 
    char state; // e.g. 'A' or 'B' 
    float weight; // e.g. 0.8 
} 
Particle; 

/// =========================================================================== 

int main() 
{ 
    vector<char> Y; // data observations 
    Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); 
    Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); Y.push_back('B'); Y.push_back('A'); 
    Y.push_back('A'); Y.push_back('B'); Y.push_back('B'); Y.push_back('A'); Y.push_back('A'); Y.push_back('B'); 

    vector< vector<Particle> > Xall; // vector of all particles from time 0 to t 

    /// Step (1) Initialisation 
    vector<Particle> X; // a vector of N particles 
    for(int i = 0; i < N; ++i) 
    { 
     Particle x; 

     // sample particle Xi from initial distribution 
     x.distribution.PA = 0.5; x.distribution.PB = 0.5; 
     float r = uniform_generator(); 
     if(r <= x.distribution.PA) x.state = 'A'; // r <= 0.5 
     if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; // 0.5 < r <= 1 

     X.push_back(x); 
    } 

    Xall.push_back(X); 
    X.clear(); 

    /// Observing data 
    for(int t = 1; t <= 18; ++t) 
    { 
     char y = Y[t-1]; // current observation 

     /// Step (2) Importance sampling 
     float sumWeights = 0; 
     vector<Particle> X; // a vector of N particles 
     for(int i = 0; i < N; ++i) 
     { 
      Particle x; 

      // P(X^i_t = A) = P(X^i_t = A | X^i_t-1 = A) * P(X^i_t-1 = A) + P(X^i_t = A | X^i_t-1 = B) * P(X^i_t-1 = B) 
      x.distribution.PA = evolutionProba_A_A * Xall[t-1][i].distribution.PA + evolutionProba_A_B * Xall[t-1][i].distribution.PB; 

      // P(X^i_t = B) = P(X^i_t = B | X^i_t-1 = A) * P(X^i_t-1 = A) + P(X^i_t = B | X^i_t-1 = B) * P(X^i_t-1 = B) 
      x.distribution.PB = evolutionProba_B_A * Xall[t-1][i].distribution.PA + evolutionProba_B_B * Xall[t-1][i].distribution.PB; 

      // sample the a particle from this distribution 
      float r = uniform_generator(); 
      if(r <= x.distribution.PA) x.state = 'A'; 
      if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; 

      // compute weight of this particle according to the observation y 
      if(y == 'A') 
      { 
       if(x.state == 'A') x.weight = observationProba_A_A; // P(y = A | X^i_t = A) 
       else if(x.state == 'B') x.weight = observationProba_A_B; // P(y = A | X^i_t = B) 
      } 
      else if(y == 'B') 
      { 
       if(x.state == 'A') x.weight = observationProba_B_A; // P(y = B | X^i_t = A) 
       else if(x.state == 'B') x.weight = observationProba_B_B; // P(y = B | X^i_t = B) 
      } 

      sumWeights += x.weight; 

      X.push_back(x); 
     } 

     // normalise weights 
     for(int i = 0; i < N; ++i) 
      X[i].weight /= sumWeights; 

     /// Step (3) resampling N particles according to weights 
     float PA = 0, PB = 0; 
     for(int i = 0; i < N; ++i) 
     { 
      if(X[i].state == 'A') PA += X[i].weight; 
      else if(X[i].state == 'B') PB += X[i].weight; 
     } 

     vector<Particle> reX; // new vector of particles 
     for(int i = 0; i < N; ++i) 
     { 
      Particle x; 

      x.distribution.PA = PA; 
      x.distribution.PB = PB; 

      float r = uniform_generator(); 
      if(r <= x.distribution.PA) x.state = 'A'; 
      if(x.distribution.PA < r && r <= x.distribution.PA + x.distribution.PB) x.state = 'B'; 

      reX.push_back(x); 
     } 

     Xall.push_back(reX); 
    } 

    return 0; 
} 

/// =========================================================================== 

double uniform_generator(void) 
{ 
    mt19937 gen(55); 
    static uniform_01< mt19937, double > uniform_gen(gen); 
    return uniform_gen(); 
} 
+0

Wann können Sie diesen Filter in der realen Welt? Können Sie einen Test gegen ein Problem mit einer analytischen Lösung durchführen? Wenn Sie es korrekt implementiert haben, erhalten Sie die gleiche Nummer. Es ist sehr unwahrscheinlich, dass bei falscher Implementierung das richtige Ergebnis erzielt wird! –

+0

@AlessandroTeruzzi Dies ist nur eine Implementierung des einfachen Beispiels [hier] (http://www.aiqs.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo-method-implementation)/39950). Ich habe es nur implementiert, um das [Partikelfilter-Konzept, das von diesem Algorithmus gegeben wird] besser zu verstehen (http://www.aiqs.com/upfiles/PFAlgo.png), aber ich bin mir nicht sicher, ob ich es richtig umgesetzt habe, seit Ich habe den Algorithmus nicht sehr gut verstanden. Ich weiß nicht, wie ich testen soll, ob es funktioniert, da der Algorithmus und seine Ausgabe für mich immer noch nicht klar sind (selbst wenn der Algorithmus sehr einfach erscheint). – shn

+0

Mein erster Vorschlag für einen generischen Algorithmus: Versuchen Sie nicht etwas zu implementieren, das Sie nicht vollständig verstehen. Erster Unterton, dann umsetzen. Sonst können Sie nicht sagen, was schief läuft. –

Antwort

20

This online course ist sehr einfach und unkompliziert zu verstehen und mir erklärten Partikelfilter wirklich gut.

Es heißt "Programming a Robotic Car" und spricht über drei Methoden der Lokalisierung: Monte-Carlo-Lokalisierung, Kalman-Filter und Partikelfilter.

Der Kurs ist komplett kostenlos (es ist jetzt fertig, so dass Sie nicht aktiv teilnehmen können, aber Sie können immer noch die Vorlesungen ansehen), von einem Stanford-Professor unterrichtet. Die "Klassen" waren für mich erstaunlich leicht zu verfolgen, und sie werden von kleinen Übungen begleitet - einige von ihnen sind nur logisch, aber ein guter Teil von ihnen programmiert. Auch Hausaufgaben, mit denen Sie spielen können.

Es tatsächlich macht Sie Ihren eigenen Code in Python für alle Filter schreiben, die sie auch für Sie testen. Am Ende des Kurses sollten Sie alle 3 Filter in Python implementiert haben.

Wir empfehlen wärmstens, es zu überprüfen.

+0

Ok, ich werde es überprüfen. Aber da ich mich nur für Partikelfilter interessiere (vielleicht auch die beiden anderen Filter), sollte ich von Anfang an alle Kurse aller Einheiten überprüfen? – shn

+0

Wenn Sie an allen Filtern interessiert sind, sollten Sie auf jeden Fall den gesamten Kurs überprüfen. Aber auch wenn Sie es nicht sind, empfehle ich Ihnen, den anderen Kurs zu besuchen. Dadurch erhalten Sie einen sehr guten Überblick über die Lokalisierungsmethoden und Sie werden leichter verstehen, wo die einzelnen Filter am besten geeignet sind. Ich denke, 1 Vorlesung kann normalerweise in ungefähr 4 Stunden gemacht werden - vielleicht tue es über 1 oder 2 Tage, wenn du es leicht angehen willst;) – penelope

+0

Übrigens werde ich keine Partikelfilter für Robotik (Lokalisierung usw.) verwenden, ich verwende es für ein anderes Problem im Zusammenhang mit Online-Clustering von sequentiellen Daten. – shn

3
+0

Sie sind irgendwie nicht das, was ich erwartet habe. Gibt es trotzdem einen einfachen, den auf Seite 9 von www.cs.ubc vorgestellt wurde?ca/~ arnaud/doucet_defreitas_gordon_smcbookintro.ps? – shn

+0

Sicher, es gibt Möglichkeiten :) Wie unterscheiden sich die Links von Ihren Erwartungen? Wo wirst du aufgehängt? Ich glaube der Algorithmus auf p. 11. ist ziemlich einfach. – Throwback1986

+0

Nun, ich möchte Partikelfilter von Scrach implementieren, nur um es zu verstehen. Ich habe meinen ersten Post bearbeitet, um eine einfache C++ - Implementierung eines einfachen Beispiels hinzuzufügen, das hier erklärt wurde: http://www.aiqs.com/questions/39942/very-simple-particle-filters-algorithm-sequential-monte-carlo- Methodenimplementierung? page = 1 # 39950 Können Sie bitte überprüfen, ob ich es gut verstanden habe, oder es gibt ein Missverständnis? – shn