我正在尝试为结构方程模型编写一个估计器。因此,基本上我从模型B
,gamma
,phi_diag
,psi
的随机参数开始。并以此计算隐式协方差矩阵sigma
。我的优化函数f_ml
是根据sigma
和数据S
的协方差矩阵计算出来的。这是我的计算代码:
device = torch.device('cpu')
dtype = torch.float
B_s = (4, 4)
gamma_s = (4, 1)
phi_s = (1, 1)
psi_s = (4, 4)
# Covariance matrix of data
S = torch.tensor(data.cov().values, dtype=dtype, device=device, requires_grad=False)
# Defining parameters of the model
B = torch.rand(*B_s, dtype=dtype, device=device, requires_grad=True)
B_lower = B.tril(diagonal=-1)
gamma = torch.rand(*gamma_s, dtype=dtype, device=device, requires_grad=True)
phi_diag = torch.rand(phi_s[0], dtype=dtype, device=device, requires_grad=True)
phi = torch.diag(phi_diag)
psi = torch.rand(*psi_s, dtype=dtype, device=device, requires_grad=True)
psi_sym = psi @ psi.t()
B_inv = (torch.eye(*B_s, dtype=dtype, device=device, requires_grad=False) - B_lower).inverse()
sigma_yy = B_inv @ (gamma @ phi @ gamma.t() + psi_sym) @ B_inv.t()
sigma_xy = phi @ gamma.t() @ B_inv.t()
sigma_yx = sigma_xy.t()
sigma_xx = phi
# Computing the covariance matrix from the parameters
sigma = torch.cat((torch.cat((sigma_yy, sigma_yx), 1), torch.cat((sigma_xy, sigma_xx), 1)), 0)
我正在尝试进行以下优化:
optim = torch.optim.Adam([B, gamma, phi_diag, psi], lr=0.01)
for t in range(5000):
optim.zero_grad()
f_ml = sigma.logdet() + (S @ sigma.inverse()).trace() - S.logdet() - (4 + 1)
f_ml.backward(retain_graph=True)
optim.step()
我面临的问题是在优化过程中不会更新参数值。我尝试调试一下问题,我注意到的是,在优化的第一个循环中,已计算出梯度,但参数的值未得到更新。这是一个使用pdb(在for循环后立即设置断点)的示例:
> <ipython-input-232-c6a6fda6610b>(14)<module>()
-> optim.zero_grad()
(Pdb) B
tensor([[ 6.0198e-01, 8.7188e-01, 5.4234e-01, 6.0800e-01],
[-4.9971e+03, 9.3324e-01, 8.1482e-01, 8.3517e-01],
[-1.4002e+04, 2.6706e+04, 2.6412e-01, 4.7804e-01],
[ 1.1382e+04, -2.1603e+04, -6.0834e+04, 1.2768e-01]],
requires_grad=True)
(Pdb) c
> <ipython-input-232-c6a6fda6610b>(13)<module>()
-> import pdb; pdb.set_trace()
(Pdb) B.grad
tensor([[ 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00],
[ 1.6332e+04, 0.0000e+00, 0.0000e+00, 0.0000e+00],
[ 4.6349e+04, -8.8694e+04, 0.0000e+00, 0.0000e+00],
[-3.7612e+04, 7.1684e+04, 2.0239e+05, 0.0000e+00]])
(Pdb) B
tensor([[ 6.0198e-01, 8.7188e-01, 5.4234e-01, 6.0800e-01],
[-4.9971e+03, 9.3324e-01, 8.1482e-01, 8.3517e-01],
[-1.4002e+04, 2.6706e+04, 2.6412e-01, 4.7804e-01],
[ 1.1382e+04, -2.1603e+04, -6.0834e+04, 1.2768e-01]],
requires_grad=True)
我不知道我在做什么错。有什么想法吗?
答案 0 :(得分:1)
问题在于sigma
的值没有在每次迭代中都得到计算。基本上,计算代码需要在函数中移动,并且需要在每次迭代中进行计算。