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

PyTorch导数计算存疑:为何梯度输出为[6,6,6]而非[4,4,4]?

问题原因解析

你的计算偏差来自对PyTorch中backward()方法的理解误区,具体拆解如下:

1. 张量y的实际构成

你的代码中y = 3*x + x.sum()生成的是长度为3的张量,每个元素的表达式为:

  • $y_0 = 3x_0 + (x_0+x_1+x_2) = 4x_0 + x_1 + x_2$
  • $y_1 = 3x_1 + (x_0+x_1+x_2) = x_0 + 4x_1 + x_2$
  • $y_2 = 3x_2 + (x_0+x_1+x_2) = x_0 + x_1 + 4x_2$

2. backward(torch.ones(3))的计算逻辑

当对非标量张量调用backward()时,传入的参数是梯度权重向量,PyTorch会计算雅可比向量积:即把权重向量与y对x的雅可比矩阵做乘积,最终得到x的梯度。

你传入的torch.ones(3)是[1,1,1],以$x_0$的梯度为例:
$$\text{grad}(x_0) = 1*\frac{\partial y_0}{\partial x_0} + 1*\frac{\partial y_1}{\partial x_0} + 1*\frac{\partial y_2}{\partial x_0} = 14 + 11 + 1*1 = 6$$
同理$x_1$和$x_2$的梯度也是6,最终得到[6,6,6]。

3. 如何得到你预期的[4,4,4]

如果你想让每个$x_i$对应$y_i$的偏导数(即4),有两种方式:

  • 方式一:将y转为标量后求导(本质是对所有y元素求和,此时权重默认是1):
    x = torch.arange(3,dtype=float)
    x.requires_grad_(True)
    y = (3*x + x.sum()).sum()  # 转为标量
    y.backward()
    print(x.grad)  # 输出tensor([4., 4., 4.])
    
  • 方式二:若要保留y的张量形态,需明确你要计算的是每个y_i对x的梯度,但此时无法同时得到所有x_i对应y_i的4,只能单独计算单个y_i的梯度,比如:
    x = torch.arange(3,dtype=float)
    x.requires_grad_(True)
    y = 3*x + x.sum()
    y[0].backward()  # 仅对y[0]求导
    print(x.grad)  # 输出tensor([4., 1., 1.])
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:31:15