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

PyTorch执行.backward后i1.grad、i2.grad返回None的问题求解

问题根本原因

你代码中的计算逻辑完全切断了i1、i2和输出z之间的梯度计算链路,这是i1、i2梯度为None的核心原因,具体分为两点:

  • 使用math.cos、math.sin处理PyTorch张量时,会自动将张量转为无梯度信息的Python普通浮点数,直接丢失计算图跟踪关系。
  • 对x、y的计算结果额外包裹tr.tensor(),相当于用无梯度关联的普通数值创建新张量,彻底断开了i1、i2到x、y的依赖关系。此时z的计算图仅将x、y作为叶子节点,反向传播的梯度只会传递到x、y为止,i1、i2完全不在z的计算链路中,因此无论是否调用retain_grad()都无法获取梯度。
修复方案

仅需要调整x、y的计算逻辑即可:

  1. 替换所有math库的三角函数为PyTorch自带的张量运算函数tr.cos、tr.sin,保证运算过程中计算图不会中断。
  2. 删除x、y赋值时外层的tr.tensor()包裹,PyTorch张量运算的结果本身就是合法张量,会自动继承上游张量的梯度属性,保留计算链路。

修正后可正常获取梯度的代码如下:

import torch as tr
import math

i1 = tr.tensor(0.0, requires_grad=True)
i2 = tr.tensor(0.0, requires_grad=True)
# 移除tr.tensor包裹,替换math函数为torch内置函数
x = 2*(tr.cos(i1)*tr.cos(i2) - tr.sin(i1)*tr.sin(i2)) + 3*tr.cos(i1)
y = 2*(tr.sin(i1)*tr.cos(i2) + tr.cos(i1)*tr.sin(i2)) + 3*tr.sin(i1)
    
z = (x - (-2))**2 + (y - 3)**2
z.backward()
dz_t1 = i1.grad
dz_t2 = i2.grad
print(dz_t1)
print(dz_t2)

如果需要保留x、y的梯度,仅需要额外对x、y调用retain_grad()即可,不需要主动设置requires_grad=True,运算会自动继承上游的梯度属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:15:08