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

PyTorch二次反向传播报错求助:retain_graph=True无效

问题分析与解决

首先看代码里的几个明显错误:

  • 函数名大小写不统一:定义的是CalculateLoss,但闭包里调用的是calculateLosses(),拼写错误会导致找不到函数。
  • 优化器调用时传的是closure1,但定义的闭包函数是closure,参数名错误。

而核心的RuntimeError问题,根源在于LBFGS优化器的特性:它会多次调用传入的闭包函数(用来反复计算损失和梯度、做线搜索),但你的代码把前向传播(solution1 = my_neural_network(x))和梯度计算(grads_sol = gradients(...))放在了闭包外面,每个epoch只计算一次。当LBFGS第二次调用闭包时,会复用之前的计算图,而第一次backward()已经释放了图中的中间张量,就会触发"反向传播第二次"的错误——哪怕加retain_graph=True也没用,因为你复用的是旧的计算图,而不是当前参数下的新图。

修正后的代码

optimizer1 = torch.optim.LBFGS(my_neural_network.parameters(), lr=lr1)
StepLR1 = torch.optim.lr_scheduler.StepLR(optimizer1, step_size=..., gamma=...)  # 假设你已定义调度器参数

# 如果x是固定输入不需要优化,设置requires_grad=False
x = torch.tensor([200, 100, 0, 1, 15], dtype=torch.float32, requires_grad=False)

for epoch in range(no_of_epochs + 1):
    def calculate_loss():
        # 把前向传播移到闭包内部,每次调用都重新计算当前参数下的输出
        solution1 = my_neural_network(x)
        # 重新计算梯度,基于当前的solution1;create_graph=True保留梯度计算图,支持后续对网络参数求导
        grads_sol = torch.autograd.grad(solution1, x, create_graph=True)[0]
        
        # 你的损失计算逻辑
        loss1 = function_special(solution1, grads_sol, x)
        return loss1

    def closure():
        optimizer1.zero_grad()
        loss1 = calculate_loss()
        loss1.backward()
        return loss1

    # 调用正确的闭包函数
    optimizer1.step(closure)
    StepLR1.step()

关键说明

  1. 闭包必须包含完整前向流程:LBFGS会多次执行闭包来调整参数,所以每次闭包调用都要重新跑前向传播、梯度计算、损失计算,不能复用外部的旧张量,否则会重复使用同一个计算图。
  2. 关于create_graph=True:如果你要计算的损失function_special依赖于grads_sol(对x的梯度),而最终要对网络参数求导,那么调用torch.autograd.grad时必须加create_graph=True,这样梯度的计算图会被保留,才能继续对网络参数求导。
  3. 是否需要detach:只有当你想切断某个张量的梯度传播时才用detach。比如如果x是固定输入,设置requires_grad=False就足够;如果function_special里有不需要参与梯度的部分,可以对对应的张量调用detach()。
  4. 优化写法建议:不要在循环里重复定义函数,更好的做法是把calculate_loss改成接收网络、x等参数的外部函数,避免每次循环创建新函数对象。

内容的提问来源于stack exchange,提问作者math_guy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:13:12