【问题标题】:Difference between tensor addition assignment and assignment in pytorchpytorch中张量加法赋值和赋值的区别
【发布时间】:2021-10-06 10:55:01
【问题描述】:

我发现 pytorch 对待张量赋值和加法赋值的方式不同。示例如下所示

x = torch.tensor(3.0)
print(id(x))
x = x + 5
print(id(x))

结果是

1647247869184
1647248066816

如果我们运行以下代码

x = torch.tensor(3.0)
print(id(x))
x += 5
print(id(x))

,结果是

1647175563712
1647175563712

从这两个例子中,我们可以看出使用加法赋值不会改变变量地址,而加法会改变地址。这对训练神经网络有影响。例如,在 pytorch 教程“什么是torch.nn 到底是什么?”中,有一段代码如下所示

from IPython.core.debugger import set_trace

lr = 0.5  # learning rate
epochs = 2  # how many epochs to train for

for epoch in range(epochs):
    for i in range((n - 1) // bs + 1):
        #         set_trace()
        start_i = i * bs
        end_i = start_i + bs
        xb = x_train[start_i:end_i]
        yb = y_train[start_i:end_i]
        pred = model(xb)
        loss = loss_func(pred, yb)

        loss.backward()
        with torch.no_grad():
            weights -= weights.grad * lr
            bias -= bias.grad * lr
            weights.grad.zero_()
            bias.grad.zero_()

我们可以看到在 torch.no_grad() 上下文中,使用了减号赋值。如果我们将减号赋值更改为如下所示的正常赋值,则代码不起作用。

        with torch.no_grad():
            weights = weights - weights.grad * lr
            bias = bias - bias.grad * lr
            weights.grad.zero_()
            bias.grad.zero_()

现在,我知道如果我们不想更改变量,应该使用 += 或 -=。但是,在python中,+=和=没有区别,两者都改变​​变量地址。示例如下:

x = 3
print(id(x))
x += 1
print(id(x))
x = x + 1
print(id(x))
140736084850528
140736084850560
140736084850592

我的问题是

  • 为什么 pytorch 中存在 += 和 = 的区别?这是故意的吗?
  • 允许差异存在有什么好处?

【问题讨论】:

    标签: pytorch compound-assignment


    【解决方案1】:

    += 是一个就地操作,即它修改原始变量的内容而不复制它(保留相同的内存地址)。

    其他例子:

    • x *= 3
    • X[…] = …
    • X.add_(1)

    weights = weights - weights.grad * lr 中,它不起作用,因为您正在创建一个新变量(地址不同,只是它也有名称权重)。

    顺便说一句,在pytorch的optimizers中是这样实现的:

    weights.add_(weights.grad, alpha=-lr)
    

    【讨论】:

    • @Andy 如果解决了您的问题,您可以点击“正确符号”来接受答案:)
    猜你喜欢
    • 2021-08-01
    • 2015-01-19
    • 2015-07-22
    • 2011-03-04
    • 2016-12-27
    • 2020-05-05
    • 2016-09-06
    • 1970-01-01
    • 2014-05-02
    相关资源
    最近更新 更多