You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无监督学习自定义损失函数报错: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:22:54