log_prob 与人工计算有出入
Discrepancy between log_prob and manual calculation
我想用均值 [1, 1, 1]
和对角线 0.3
的方差协方差矩阵定义多元正态分布。之后我想计算数据点的对数似然 [2, 3, 4]
通过火炬分发
import torch
import torch.distributions as td
input_x = torch.tensor([2, 3, 4])
loc = torch.ones(3)
scale = torch.eye(3) * 0.3
mvn = td.MultivariateNormal(loc = loc, scale_tril=scale)
mvn.log_prob(input_x)
tensor(-76.9227)
从零开始
通过使用对数似然公式:
我们得到张量:
first_term = (2 * np.pi* 0.3)**(3)
first_term = -np.log(np.sqrt(first_term))
x_center = input_x - loc
tmp = torch.matmul(x_center, scale.inverse())
tmp = -1/2 * torch.matmul(tmp, x_center)
first_term + tmp
tensor(-24.2842)
我在哪里使用
我的问题是 - 这种差异的来源是什么?
您正在将协方差矩阵传递给 scale_tril
而不是 covariance_matrix
。来自 PyTorch's Multivariate Normal
的文档
scale_tril (Tensor) – lower-triangular factor of covariance, with positive-valued diagonal
因此,将 scale_tril
替换为 covariance_matrix
会产生与手动尝试相同的结果。
In [1]: mvn = td.MultivariateNormal(loc = loc, covariance_matrix=scale)
In [2]: mvn.log_prob(input_x)
Out[2]: tensor(-24.2842)
然而,根据作者的说法,使用 scale_tril
效率更高:
...Using scale_tril will be more efficient:
您可以使用 torch.cholesky
计算下 choelsky
In [3]: mvn = td.MultivariateNormal(loc = loc, scale_tril=torch.cholesky(scale))
In [4]: mvn.log_prob(input_x)
Out[4]: tensor(-24.2842)
我想用均值 [1, 1, 1]
和对角线 0.3
的方差协方差矩阵定义多元正态分布。之后我想计算数据点的对数似然 [2, 3, 4]
通过火炬分发
import torch
import torch.distributions as td
input_x = torch.tensor([2, 3, 4])
loc = torch.ones(3)
scale = torch.eye(3) * 0.3
mvn = td.MultivariateNormal(loc = loc, scale_tril=scale)
mvn.log_prob(input_x)
tensor(-76.9227)
从零开始
通过使用对数似然公式:
我们得到张量:
first_term = (2 * np.pi* 0.3)**(3)
first_term = -np.log(np.sqrt(first_term))
x_center = input_x - loc
tmp = torch.matmul(x_center, scale.inverse())
tmp = -1/2 * torch.matmul(tmp, x_center)
first_term + tmp
tensor(-24.2842)
我在哪里使用
我的问题是 - 这种差异的来源是什么?
您正在将协方差矩阵传递给 scale_tril
而不是 covariance_matrix
。来自 PyTorch's Multivariate Normal
scale_tril (Tensor) – lower-triangular factor of covariance, with positive-valued diagonal
因此,将 scale_tril
替换为 covariance_matrix
会产生与手动尝试相同的结果。
In [1]: mvn = td.MultivariateNormal(loc = loc, covariance_matrix=scale)
In [2]: mvn.log_prob(input_x)
Out[2]: tensor(-24.2842)
然而,根据作者的说法,使用 scale_tril
效率更高:
...Using scale_tril will be more efficient:
您可以使用 torch.cholesky
In [3]: mvn = td.MultivariateNormal(loc = loc, scale_tril=torch.cholesky(scale))
In [4]: mvn.log_prob(input_x)
Out[4]: tensor(-24.2842)