在二维迷宫中使用HMM定位,遇到平滑(后向算法)问题

我们使用HMM(隐马尔可夫模型)来在一个有风且传感器损坏的迷宫中定位机器人。如果他尝试朝某个方向移动,他会以高概率成功移动,并有低概率意外地向两侧移动。如果他的移动会使他越过障碍物,他会弹回到原来的位置。

从任何给定的位置,他可以向四个方向感知。如果某个方向有障碍物,他会以高确定性注意到它,而在没有障碍物时,他会以低确定性看到障碍物。

我们有一个概率地图,显示机器人在迷宫中可能存在的所有位置,因为他知道迷宫的布局。最初,所有位置的概率是均匀分布的。

我已经完成了运动和感知方面的任务,并且得到了正确的结果,但我在平滑(后向算法)上遇到了困难。

假设机器人执行以下一系列动作:感知、移动、感知、移动、感知。这为我们的HMM模型提供了3个状态。假设到目前为止,每一步的结果都是正确的。

我遇到了很多麻烦,无法执行平滑(后向算法),因为有四个条件概率(每个方向一个)。

假设SP代表平滑概率,BP代表后向概率

假设Sk代表一个状态,Zk代表该状态的观测。我的问题在于如何构建我的后向方程,因为每个Zk仅适用于单一方向。

我知道平滑的算法是:SP(k)与BP(k+1) * P(Sk | Z1:k)成比例

其中BP(k+1)定义为:

如果(k == n)返回1,否则返回BP(k+1) * P(Zk+1|Sk+1) * P(Sk+1=s | Sk)的总和

这就是我遇到麻烦的地方。主要是在这个方程的条件概率部分。因为每个位置有四个不同的方向需要观察!换句话说,每个状态有四个不同的证据变量,而不是只有一个!我应该平均这些值吗?我应该为它们做一个单独的总和吗?我如何考虑在一个给定状态下的多个观测,并将其正确地压缩到这个只有一个条件概率的方程中?

这是我执行平滑的代码:

public static void Smoothing(List<int[]> observations) {        int n = observations.Count; //n是证据序列的总长度        int k = n - 1;              //k是我们试图平滑的状态。从n-1开始        for (; k >= 1; k--) {       //平滑回第一个状态            for (int dir = 0; dir < 4; dir++) {                //我们必须分别平滑每个方向                SmoothDirection(dir, observations, k, n);            }            Console.WriteLine($"Smoothing for k = {k}\n");            UpdateMapMotion(mapHistory[k]);            PrintMap();        }    }    public static void SmoothDirection(int dir, List<int[]> observations, int k, int n) {        var alphas = new double[ROWS, COLS];        var normalizer = 0.0;        int row, col;        foreach (var t in map) {            if (t.isObstacle) continue;            row = t.pos.y;            col = t.pos.x;            alphas[row, col] = mapHistory[k][row, col]                 * Backwards(k, n, t, dir, observations, moves[^(n - k)]);            normalizer += alphas[row, col];        }        UpdateHistory(k, alphas, normalizer);    }    public static void UpdateHistory(int index, double[,] alphas, double normalizer) {        for (int r = 0; r < ROWS; r++) {            for (int c = 0; c < COLS; c++) {                mapHistory[index][r, c] = alphas[r, c] / normalizer;            }        }    }    public static double Backwards(int k, int n, Tile t, int dir, List<int[]> observations, int moveDir) {        if (k == n) return 1;        double p = 0;        var nextStates = GetPossibleNextStates(t, moveDir);        foreach (var s in nextStates) {            p += Cond_Prob(s.hasObstacle[dir], observations[^(n - k)][dir] == 1) * Trans_Prob(t, s, moveDir)                 * Backwards(k+1, n, s, dir, observations, moves[^(n - k)]);         }        return p;    }    public static List<Tile> GetPossibleNextStates(Tile t, int direction) {        var tiles = new List<Tile>();                   //下一状态        var perpDirs = GetPerpendicularDir(direction);  //垂直方向        //如果Tile t前方或侧面有障碍物,Tile t是可能的下一状态。        if (t.hasObstacle[direction] || t.hasObstacle[perpDirs[0]] || t.hasObstacle[perpDirs[1]])            tiles.Add(t);        //如果Tile t前方没有障碍物,那么那个位置是可能的下一状态。        if (!t.hasObstacle[direction])            tiles.Add(GetTileAtPos(t.pos + directions[direction]));        //如果Tile t的侧面没有障碍物,那么那些位置是可能的下一状态。        foreach (var dir in perpDirs) {            if (!t.hasObstacle[dir])                tiles.Add(GetTileAtPos(t.pos + directions[dir]));        }        return tiles;    }

简而言之:当每个状态有4个证据而不是1个时,如何在隐马尔可夫模型中执行平滑(后向算法)?


回答:

已解决!

实际上,这比我想象的要简单得多。

我实际上不需要在每个方向上分别进行每次迭代。

我只需要用Joint_Cond_Prob()函数替换Cond_Prob()函数,后者可以找到给定状态下所有方向观测的联合概率。

所以P(Zk|Sk)实际上是P(Zk1:Zk4|Sk),也就是P(Zk1|Sk)P(Zk2|Sk)P(Zk3|Sk)P(Zk4|Sk)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注