简体   繁体   English

向量化多元正态 pdf python (PyTorch/NumPy)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM