尝试使用自定义损失函数时,遇到错误“RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn”。错误发生在loss.backward()期间。
我知道所有计算必须在’require_grad = True’的张量上进行。我在实现这一点时遇到了麻烦,因为我的代码需要嵌套的for循环。我认为可能是for循环的问题。有没有办法创建一个空张量并添加元素呢?下面是我的代码。
def Gaussian_Kernal(x, mu, sigma): p = (1./(math.sqrt(2. * math.pi * (sigma**2)))) * torch.exp((-1.) * (((Variable(x)**2) - mu)/(2. * (sigma**2)))) return pclass MEE(torch.nn.Module): def __init__(self): super(MEE,self).__init__() def forward(self,output, target, mu, variance): error = torch.subtract(Variable(output),Variable(target)) error_diff = [] for i in range(0, error.size(0)): for j in range(0, error.size(0)): error_diff.append(error[i] - error[j]) error_diff = torch.cat(error_diff) torch.tensor(error_diff,requires_grad=True) loss = (1./(target.size(0)**2)) * torch.sum(Gaussian_Kernal(Variable(error_diff), mu, variance*(2**0.5))) loss = Variable(loss) return loss
回答:
只要你在张量上操作并应用PyTorch函数和基本运算符,就应该能正常工作。因此,无需用torch.tensor
或Variable
来包装你的变量。后者自从v0.4版起已被废弃(我认为)。
Variable API已被废弃:使用requires_grad设置为True的张量时,不再需要使用Variable来使用autograd。 PyTorch文档
我假设output
和target
是张量,而mu
和variance
是实数而不是张量?那么,output
和target
的第一个维度将是批次。
def Gaussian_Kernel(x, mu, sigma): p = (1./(math.sqrt(2. * math.pi * (sigma**2)))) * torch.exp((-1.) * (((x**2) - mu)/(2. * (sigma**2)))) return pclass MEE(torch.nn.Module): def __init__(self): super(MEE, self).__init__() def forward(self, output, target, mu, variance): error = output - target error_diff = [] for i in range(0, error.size(0)): for j in range(0, error.size(0)): error_diff.append(error[i] - error[j]) # 假设这是所需的操作 error_diff = torch.cat(error_diff) kernel = Gaussian_Kernel(error_diff, mu, variance*(2**0.5)) loss = (1./(target.size(0)**2))*torch.sum(kernel) return loss