【问题标题】:Inplace arithmetic operation versus normal arithmetic operation in PyTorch TensorsPyTorch 张量中的就地算术运算与普通算术运算
【发布时间】:2025-12-18 03:25:02
【问题描述】:

我正在尝试使用 Pytorch 框架构建线性回归,并在实现梯度下降时,根据我在 Python 代码中使用算术运算的方式观察到两种不同的输出。下面是代码:

 #X and Y are input and target labels respectively
 X = torch.randn(100,1)*10
 Y = X + 3*torch.randn(100,1) +2
 plt.scatter(X.numpy(),Y.numpy())


 #Initialiation of weight and bias
 w = torch.tensor(1.0,requires_grad=True)
 b = torch.tensor(1.0,requires_grad=True)

 #forward pass
 def forward_feed(x):
   y = w*x +b
   return y

 #Parameters Learning
 epochs = 100
 lr = 0.00008
 loss_list = []
 for epoch in range(epochs):
   print('epoch',epoch)
   Y_pred = forward_feed(X)
   loss = torch.sum((Y - Y_pred)**2)
   loss_list.append(loss)
   loss.backward()
   with torch.no_grad():
     w -= lr*w.grad
     b -= lr*b.grad
     w.grad.zero_()
     b.grad.zero_()

如果我使用此代码,我会得到预期的结果,即我的代码能够估计权重和偏差。但是,如果我改变梯度下降代码行如下:

  w =w- lr*w.grad
  b =b- lr*b.grad

我收到以下错误:

 AttributeError                            Traceback (most recent call 
 last)
 <ipython-input-199-84b86804d4d5> in <module>()
 ---> 41         w.grad.zero_()
      42         b.grad.zero_()

 AttributeError: 'NoneType' object has no attribute 'zero_'

谁能帮我解决这个问题?

我确实尝试在谷歌上查看答案并找到了相关链接:https://github.com/pytorch/pytorch/issues/7731。但这与我所面临的完全相反。根据此链接,他们说就地分配会导致问题,因为张量共享相同的存储。但是,对于我的代码,Inplace 操作不是正常操作。

【问题讨论】:

    标签: python machine-learning pytorch


    【解决方案1】:

    我认为原因很简单。当你这样做时:

    w = w - lr * w.grad
    b = b - lr * b.grad
    

    左侧的wb 是两个新张量,它们的.grad 为None。

    然而,当你进行就地操作时,你并没有创建任何新的张量,你只是更新了相关张量的值。因此,在这种情况下,需要就地操作。

    【讨论】:

    • 非常感谢您的帮助。这让我想到这是否也发生在其他 python 库中?如果我们对 python 变量/numpy 数组进行正常的算术运算,它们确实具有相同的属性。张量也将携带相同但不是梯度。因此,对于这种情况,我们需要就地算术运算。有道理。只是想,我们还有其他类似的例子吗?