无监督学习自定义损失函数报错:RuntimeError梯度问题求助
解决方案
你的问题核心是手动调用backward()获取的梯度张量没有计算图关联,导致最终损失无法反向传播到网络参数。改用torch.autograd.grad计算梯度,就能保留计算图的连续性,解决这个问题。
修改后的损失函数代码如下:
def loss_function(points, outputs): a, b = minA, minB r, mul = 0.1, 1000 N = len(points) grad_summed = 0.0 for i, c in enumerate(points): # 启用输入张量的梯度追踪 c.requires_grad_(True) # 计算XA、XB和q XA = 0.5 - 0.5 * torch.tanh(mul * (((c[0] - a[0])**2 + (c[1] - a[1])**2) - (r + 0.02)**2)) XB = 0.5 - 0.5 * torch.tanh(mul * (((c[0] - b[0])**2 + (c[1] - b[1])**2) - (r + 0.02)**2)) q = (1 - XA) * ((1 - XB) * outputs[i] + XB) # 计算q对c的梯度,create_graph=True保留计算图以支持二次反向传播 grad_q_c = torch.autograd.grad(q, c, create_graph=True)[0] # 计算梯度的平方和 grad_sq_sum = (grad_q_c ** 2).sum() grad_summed += grad_sq_sum # 清空当前张量的梯度,避免跨样本累积 c.grad.zero_() grad_avg = grad_summed / N return grad_avg
关键修改说明:
- 移除
c.detach():保留输入c与网络输出outputs的计算图关联,确保梯度能传递到网络参数。 - 替换
q.backward()为torch.autograd.grad:create_graph=True参数让返回的梯度张量保留计算图,后续的平方和操作会被纳入整个反向传播链路。 - 手动清空
c.grad:避免不同样本的梯度互相干扰,保证每个样本的梯度计算独立。
修改后调用loss.backward()时,PyTorch会沿着完整计算图将损失梯度正确传递到网络的可训练参数,完成目标函数的最小化。
内容的提问来源于stack exchange,提问作者eliss
相关产品推荐
相关产品推荐

