为了学习pytorch是如何工作的,我试图对多元正态分布中的一些参数进行最大似然估计。然而,它似乎不适用于任何协方差相关的参数。在
所以我的问题是:为什么这个代码不起作用?在
import torch
def make_covariance_matrix(sigma, rho):
return torch.tensor([[sigma[0]**2, rho * torch.prod(sigma)],
[rho * torch.prod(sigma), sigma[1]**2]])
mu_true = torch.randn(2)
rho_true = torch.rand(1)
sigma_true = torch.exp(torch.rand(2))
cov_true = make_covariance_matrix(sigma_true, rho_true)
dist_true = torch.distributions.MultivariateNormal(mu_true, cov_true)
samples = dist_true.sample((1_000,))
mu = torch.zeros(2, requires_grad=True)
log_sigma = torch.zeros(2, requires_grad=True)
atanh_rho = torch.zeros(1, requires_grad=True)
lbfgs = torch.optim.LBFGS([mu, log_sigma, atanh_rho])
def closure():
lbfgs.zero_grad()
sigma = torch.exp(log_sigma)
rho = torch.tanh(atanh_rho)
cov = make_covariance_matrix(sigma, rho)
dist = torch.distributions.MultivariateNormal(mu, cov)
loss = -torch.mean(dist.log_prob(samples))
loss.backward()
return loss
lbfgs.step(closure)
print("mu: {}, mu_hat: {}".format(mu_true, mu))
print("sigma: {}, sigma_hat: {}".format(sigma_true, torch.exp(log_sigma)))
print("rho: {}, rho_hat: {}".format(rho_true, torch.tanh(atanh_rho)))
输出:
^{pr2}$换句话说,为什么log_sigma
和{
创建协方差矩阵的方法不可回溯:
从(多个)张量创建新张量时,只保留输入张量的值。所有来自输入张量的附加信息都被剥离了,因此与参数的所有图连接都从这一点切断,因此反向传播无法通过。在
下面是一个简短的例子来说明这一点:
^{pr2}$输出:
如您所见,由参数}的梯度。在
param1
和param2
创建的张量并不跟踪param1
和{因此您可以使用以下代码来保持图形连接,并且可以回溯到中:
这些值用}的连接。在
torch.cat
连接到平面张量。然后使用view()
将它们变成正确的形状。这将产生与函数中相同的矩阵输出,但它保持与参数
log_sigma
和{以下是步骤前后的输出,其中
make_covariance_matrix
已更改。如您所见,现在您可以优化参数,并且值会发生更改:希望这有帮助!在
相关问题 更多 >
编程相关推荐