维度不匹配:数组 '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
。
【问题讨论】:
能否包含定义kf
和mes
的代码(或虚拟代码)?我无法弄清楚你的代码想要做什么。
错误本身很简单:在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 == 4
和 dim_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) 的数组