维度不匹配:数组 'cov' 的形状为 (1, 1),但 'mean' 是长度为 2 的向量

Posted

技术标签:

【中文标题】维度不匹配:数组 \'cov\' 的形状为 (1, 1),但 \'mean\' 是长度为 2 的向量【英文标题】:Dimension mismatch: array 'cov' is of shape (1, 1), but 'mean' is a vector of length 2维度不匹配:数组 'cov' 的形状为 (1, 1),但 'mean' 是长度为 2 的向量 【发布时间】:2015-11-26 04:10:37 【问题描述】:

我正在尝试执行以下代码

p, c = [], []
for z in mes:
    print (z)
    print (c)
    print (p)
    p.append(kf.x)
    c.append(kf.P)
    kf.predict()
    kf.update(z) #error on this line

我得到了错误:

ValueError:维度不匹配:数组“cov”的形状为 (1, 1),但 'mean' 是长度为 2 的向量。

这是屏幕上显示的输出

[512  102]
[array([[ 1000.,     0.,     0.,     0.],
       [    0.,  1000.,     0.,     0.],
       [    0.,     0.,  1000.,     0.],
       [    0.,     0.,     0.,  1000.]])]
[array([[ 396.],
       [  187.],
       [    0.],
       [    0.]])]

如果我只取z 的第一个元素,它可以正常工作,但是,这不是我想要的行为。

p, c = [], []
for z in mes:
    print (z)
    print (c)
    print (p)
    p.append(kf.x)
    c.append(kf.P)
    kf.predict()
    kf.update(z[0]) 

更新附加信息

此错误来自multivariate.py in scipy。我似乎无法从(1,1) 更改cov 的形状。我可以通过使用z[0] 来更改mean 的长度,但是,这是不希望的。我想按原样使用z。我还将整个代码发布为gist here。我还将filterpy library 用于卡尔曼滤波器。有一个live python notebook 使用这个卡尔曼滤波器,但是,它不像我的场景那样使用z

【问题讨论】:

能否包含定义kfmes 的代码(或虚拟代码)?我无法弄清楚你的代码想要做什么。 错误本身很简单:在kf.update() 的实现中,有一些操作涉及一个名为c 的变量和一个名为mean 的变量(我猜这是@ 的参数987654344@),其尺寸需要兼容才能进行操作。可能是矩阵乘法。但我不能说更多,特别是如何修复它,至少不知道您正在使用哪种卡尔曼滤波器实现。对您正在尝试做的事情进行高级描述也会很方便。 @maxymoo 我已经在这里发布了整个代码作为要点gist.github.com/Omnipresent/…我正在使用来自这个库的卡尔曼过滤器github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python @DavidZ 我正在使用 github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python 来实现卡尔曼滤波器。我还添加了代码的要点gist.github.com/Omnipresent/… 你是对的。但我似乎无法弄清楚如何更新cov,使其不是(1,1)。我想如果我能改变它……一切都会奏效。 mean 的长度为 2,但我想保持这种状态。就像我提到的,如果我将它的长度更改为 1 (z[0]) 一切正常。 @Anthony 好的,这有帮助。但是让我建议将这些 cmets 的内容编辑到问题中。即使在 cmets 被删除后,这些信息也很重要。 【参考方案1】:

使用 filterpy 库时,您需要自己负责设置卡尔曼滤波器的初始状态,并且各种矩阵的维度需要兼容。如果您查看KalmanFilter.update() 方法,您可以跟踪它所做的计算并得出以下矩阵维度的约束集:

R.shape == (dim_z, dim_z)
H.shape == (dim_z, dim_x)
P.shape == (dim_x, dim_x)
x.shape == (dim_x, 1...)
z.shape == (dim_z, 1...)

1... 可以表示一些大小为 1 的维度序列,这对于两者都是相同的。例如,在您的情况下,dim_x == 4dim_z == 2 可以有 x.shape == (4, 1)z.shape == (2, 1),或者您可以有 x.shape == (4,)z.shape == (2,),但您不能混合搭配。 (请注意,KalmanFilter.__init__() 文档似乎为 H 提供了错误的所需尺寸。)

您的代码在两个地方设置了错误的尺寸:

您将 H 设置为 1x4 矩阵,而不是应有的 2x4。 (我注意到这里你已经注释掉了有效的代码。) 您将R 设置为标量值而不是2x2 矩阵。可以说卡尔曼滤波器实现应该考虑到这一点,但它仅在您将R 作为参数传递给update() 时这样做,而不是在您提前设置它时。 (不过要小心:如果您将 R 设置为标量,代码仍然会工作!不过,它会做我认为错误的事情:将 2 添加到 a矩阵而不是添加 2 倍的单位矩阵。)

当您将z 传递给update() 方法时,您传递的是一个二元素列表,该列表被转换为一个二元素向量,而不是一个2x1 矩阵,因为它应该与x 兼容(即 4x1)。 可以通过在调用 update() 之前在循环体中运行 z = np.array([z]).T 来解决此问题。但我认为有一个更好的方法:保持 z 不变,将 x 设为 4 元素向量:

x = np.array([measurements[0][0],measurements[0][1],0.,0.])

我不确定作者是否打算这样做,但(目前)确实如此,而且可能应该如此。我认为在传入之前要求将每个测量值转换为 2x1 矩阵有点愚蠢。

KalmanFilter 包含一个test_matrix_dimensions() 方法,您可以使用该方法检查设置中的错误。但我对此有点矛盾,因为如果您将 x 设置为 4 元素向量,正如我在上一段中建议的那样,它会将其标记为不正确。

【讨论】:

以上是关于维度不匹配:数组 'cov' 的形状为 (1, 1),但 'mean' 是长度为 2 的向量的主要内容,如果未能解决你的问题,请参考以下文章

ValueError:检查输入时出错:预期 permute_input 有 4 个维度,但得到了形状为 (1, 4) 的数组

检查输入时出错:预期 lstm_input 有 3 个维度,但得到的数组形状为 (4, 1)

Keras 图像分类:检查输入时出错:预期 input_1 有 4 个维度,但得到了形状为 (6885、7500) 的数组

检查目标时出错:预期 dense_24 有 3 个维度,但得到了形状为 (3283, 1) 的数组

检查输入时出错:预期 input_1 有 4 个维度,但得到了形状为 (224, 224, 3) 的数组

检查输入时出错:预期 lstm_1_input 有 3 个维度,但得到了形状为 (5, 3) 的数组