我有 N 个高斯分布(多变量),在 D 维度上有 N 个不同的均值(所有均值的协方差是相同的)。
我也有N个评估点,我想评估这些(对数)PDF中的每一个。
这意味着我需要得到一个NxN矩阵,称之为 "核"。也就是说,第(i,j)-个条目是在第i个点评估的第j个高斯。一个天真的方法是。
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])
现在一个for循环我们可以很容易地去掉,因为比如说,如果我们想得到第一个高斯的所有评价,我们只需要:
MultivariateNormal(means[0], cov).log_prob(eval_points).squeeze()
这样我们就得到了一个N×1的值列表 就是第一个高斯的值在 都 N点。
我的问题是,为了得到完整的N×N矩阵,这个方法行不通。
kernels = MultivariateNormal(means, cov).log_prob(eval_points).squeeze()
它不知道应该用eval_points中的所有评估点来评估每一个平均数, 而且它也没有返回一个我想要的NxN矩阵. 因此,我无法摆脱第二个for循环,在所有N个高斯分布上。
您正在传递错误的形状的时值到 MultivariateNormal
的构造函数。你应该传递一个形状为 (N, D)
和精密矩阵的集合 cov
形状 (N, D, D)
对于 N
D
-二维高斯。
你是通过mu的形状 (N, D)
但你的精密矩阵形状不好。您需要重复精密矩阵 N
的次数,然后再传给 MultivariateNormal
构造函数。这里有一个方法。
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)