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

PyTorch实现拉格朗日对偶优化时反向传播报错的解决咨询

PyTorch线性规划对偶优化反向传播报错解决

问题根源

报错核心原因是**lagrange_multiplier的计算逻辑放在了循环外部**,导致它的计算图在第一次反向传播后被自动释放,第二次循环时试图复用已销毁的计算图。注意:zero_grad()只是清空参数的梯度值,并不会保留或重建计算图。

修复方案

把lagrange_multiplier = torch.nn.functional.softplus(_lagrange_multiplier)移到循环内部,每次迭代都重新计算拉格朗日乘子,这样每次都会生成全新的计算图,彻底避免复用已释放的图。不需要额外添加retain_graph=True(这里完全没必要,反而会浪费内存)。

修改后的完整代码:

c_t = torch.tensor(c).float()
A_t = torch.tensor(A).float()
b_t = torch.tensor(b).float()
x_t = torch.rand(n, 1, requires_grad=True)

def max_grad(grad):
    return -grad

_lagrange_multiplier = torch.rand(m, requires_grad=True)
_lagrange_multiplier.register_hook(max_grad) # 对lambda求最大化,反转梯度方向

opt_weights = torch.optim.Adam([x_t], lr=0.1)
opt_lagrange = torch.optim.Adam([_lagrange_multiplier], lr=0.1)

for i in range(10):
    print(i)
    opt_weights.zero_grad()
    opt_lagrange.zero_grad()

    # 每次循环重新计算拉格朗日乘子,生成新的计算图
    lagrange_multiplier = torch.nn.functional.softplus(_lagrange_multiplier)

    objective = c_t.T @ x_t
    constraint = (A_t @ x_t).squeeze() - b_t
    lagrangian = objective + lagrange_multiplier.T @ constraint

    lagrangian.backward()

    opt_weights.step()
    opt_lagrange.step()

补充说明

  • softplus是可微分操作,必须每次迭代基于当前的_lagrange_multiplier重新计算,才能让梯度正确流经这个操作。如果放在循环外,第一次反向传播后该操作的中间张量会被释放,第二次循环时无法构建有效的反向传播路径。
  • register_hook绑定在_lagrange_multiplier上,不需要移动位置,它会持续作用于这个参数的梯度计算过程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:25:11