Hello!
I want to implement Gaussian Scale Mixtures. I tried to follow this do it.
So here is my code
class GaussianFunction(Function):
@staticmethod
def forward(ctx, input, var, phi, nScale):
ctx.save_for_backward(input, var, phi)
covar_inv = 1. / var
covar_inv = covar_inv.cuda()
det = (2 * math.pi * var).prod(dim=1)
coeff = 1. / det.sqrt()
input = input.repeat(nScale, 1, 1)
exponent = (input ** 2) * covar_inv.unsqueeze(2)
exponent = -0.5 * exponent
exponent = exponent.cpu()
exponent = exponent.exp().cuda()
likelihood = coeff.view(nScale, 1, 1) * exponent
# relative likelihood
likelihood = likelihood.squeeze(2)
# posterior
likelihood_sum = torch.sum(likelihood, dim=0, keepdim=True)
# p(z|k)
posterior = likelihood / likelihood_sum
# log_likelihood
temp_cf = phi.unsqueeze(1)
temp_cf = temp_cf.unsqueeze(2)
sum_over_k = torch.sum(temp_cf * posterior, dim=0)
sum_over_m = torch.sum(torch.log(sum_over_k))
result = - sum_over_m / posterior.size(1)
output = result
return output
@staticmethod
def backward(ctx, grad_output):
input, var, phi = ctx.saved_tensors
grad_input = grad_var = grad_phi = None
return grad_input, grad_var, grad_phi
class gsm_model(nn.Module):
def __init__(self, nChannel, nScale):
super(gsm_model, self).__init__()
self.nScale = nScale
self.var = nn.Parameter(torch.Tensor(nScale, nChannel))
self.phi = nn.Parameter(torch.Tensor(nScale))
self.var.data.uniform_(-1, 1)
self.phi.data.uniform_(0, 1)
def forward(self, x):
result = GaussianFunction.apply(x, self.var, self.phi, self.nScale)
return result
But I have error TypeError: unbound method backward() must be called with GaussianFunction instance as first argument (got GaussianFunctionBackward instance instead)
Can you help me with this error?