Способ создания вашей ковариационной матрицы не backprob-способен :
def make_covariance_matrix(sigma, rho):
return torch.tensor([[sigma[0]**2, rho * torch.prod(sigma)],
[rho * torch.prod(sigma), sigma[1]**2]])
При создании нового тензора из (нескольких) тензоров только значения входных тензоров будутбыть сохраненнымВся дополнительная информация от входных тензоров отбрасывается, поэтому все graph-connection к вашим параметрам обрезается с этой точки, поэтому обратное распространение не может пройти.
Вот короткийПример для иллюстрации этого:
import torch
param1 = torch.rand(1, requires_grad=True)
param2 = torch.rand(1, requires_grad=True)
tensor_from_params = torch.tensor([param1, param2])
print('Original parameter 1:')
print(param1, param1.requires_grad)
print('Original parameter 2:')
print(param2, param2.requires_grad)
print('New tensor form params:')
print(tensor_from_params, tensor_from_params.requires_grad)
Вывод:
Original parameter 1:
tensor([ 0.8913]) True
Original parameter 2:
tensor([ 0.4785]) True
New tensor form params:
tensor([ 0.8913, 0.4785]) False
Как видите, тензор, созданный из параметров param1
и param2
, не отслеживает градиенты param1
и param2
.
Так что вместо этого вы можете использовать этот код, который сохраняет графическое соединение и с возможностью обратной проверки :
def make_covariance_matrix(sigma, rho):
conv = torch.cat([(sigma[0]**2).view(-1), rho * torch.prod(sigma), rho * torch.prod(sigma), (sigma[1]**2).view(-1)])
return conv.view(2, 2)
Значения объединяются в плоский тензор с использованием torch.cat
.Затем они приводятся в правильную форму, используя view()
.
В результате получается тот же матричный вывод, что и в вашей функции, но он сохраняет соединение с вашими параметрами log_sigma
и atanh_rho
.
Вот выход до и после шага с измененным make_covariance_matrix
.Как видите, теперь вы можете оптимизировать свои параметры, и значения действительно меняются:
Before:
mu: tensor([ 0.1191, 0.7215]), mu_hat: tensor([ 0., 0.])
sigma: tensor([ 1.4222, 1.0949]), sigma_hat: tensor([ 1., 1.])
rho: tensor([ 0.2558]), rho_hat: tensor([ 0.])
After:
mu: tensor([ 0.1191, 0.7215]), mu_hat: tensor([ 0.0712, 0.7781])
sigma: tensor([ 1.4222, 1.0949]), sigma_hat: tensor([ 1.4410, 1.0807])
rho: tensor([ 0.2558]), rho_hat: tensor([ 0.2235])
Надеюсь, это поможет!