[英]Vectorize multivariate normal pdf python (PyTorch/NumPy)
I have N Gaussian distributions (multivariate) with N different means (covariance is the same for all of them) in D dimensions.我有 N 个高斯分布(多元),在 D 维中具有 N 个不同的均值(协方差对所有这些均值相同)。
I also have N evaluation points, where I want to evaluate each of these (log) PDFs.我还有 N 个评估点,我想评估这些(日志)PDF 中的每一个。
This means I need to get a NxN matrix, call it "kernels".这意味着我需要得到一个 NxN 矩阵,称之为“内核”。 That is, the (i,j)-th entry is the j-th Gaussian evaluated at the i-th point.
也就是说,第 (i,j) 个条目是在第 i 个点评估的第 j 个高斯。 A naive approach is:
一种天真的方法是:
from torch.distributions.multivariate_normal import MultivariateNormal
import numpy as np
# means contains all N means as rows and is thus N x D
# same for eval_points
# cov is not a problem , just a DxD matrix that is equal for all N Gaussians
kernels = np.empty((N,N))
for i in range(N):
for j in range(N):
kernels[i][j] = MultivariateNormal(means[j], cov).log_prob(eval_points[i])
Now one for loop we can get rid of easily, since for example if we wanted all the evaluations of the first Gaussian, we simply do:现在我们可以轻松摆脱一个 for 循环,因为例如,如果我们想要第一个高斯的所有评估,我们只需这样做:
MultivariateNormal(means[0], cov).log_prob(eval_points).squeeze()
and this gives us a N x 1 list of values, that is the first Gaussian evaluated at all N points.这给了我们一个 N x 1 的值列表,这是在所有N 个点上评估的第一个高斯。
My problem is that, in order to get the full N x N matrix, this doesn't work:我的问题是,为了获得完整的 N x N 矩阵,这不起作用:
kernels = MultivariateNormal(means, cov).log_prob(eval_points).squeeze()
It doesn't figure out that it should evaluate each mean with all evaluation points in eval_points, and it doesn't return a NxN matrix with these which would be what I want.它没有弄清楚它应该用 eval_points 中的所有评估点评估每个平均值,并且它不会返回一个包含我想要的这些的 NxN 矩阵。 Therefore, I am not able to get rid of the second for loop, over all N Gaussians.
因此,我无法摆脱所有 N 高斯的第二个 for 循环。
You are passing wrong shaped tensors to MultivariateNormal
's constructor.您将错误形状的张量传递给
MultivariateNormal
的构造函数。 You should pass a collection of mean vectors of shape (N, D)
and a collection of precision matrix cov
of shape (N, D, D)
for N
D
-dimensional gaussian.您应该为
N
D
维高斯传递形状(N, D)
(N, D, D)
精度矩阵cov
集合。
You are passing mu of shape (N, D)
but your precision matrix is not well-shaped.您正在传递形状为
(N, D)
的 mu,但您的精度矩阵形状不佳。 You will need to repeat the precision matrix N
number of times before passing it to the MultivariateNormal
constructor.在将精度矩阵传递给
MultivariateNormal
构造函数之前,您需要重复N
次。 Here's one way to do it.这是一种方法。
N = 10
D = 3
# means contains all N means as rows and is thus N x D
# same for eval_points
# cov is not a problem , just a DxD matrix that is equal for all N Gaussians
mu = torch.from_numpy(np.random.randn(N, D))
cov = torch.from_numpy(make_spd_matrix(D, D))
cov_n = cov[None, ...].repeat_interleave(N, 0)
assert cov_n.shape == (N, D, D)
kernels = MultivariateNormal(mu, cov_n)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.