数学运算符区别 *= 或 +=

math operator difference *= or +=

我在使用运算符时发现了一件奇怪的事情,例如*=+=

代码:

aa = Variable(torch.FloatTensor([[1,2],[3,4]]))
bb = aa
bb = bb*2
print(bb)
print(aa)

cc = Variable(torch.FloatTensor([[1,2],[3,4]]))
dd = cc
dd *= 2
print(cc)
print(dd)

结果如下:

Variable containing:
 2  4
 6  8
[torch.FloatTensor of size 2x2]

Variable containing:
 1  2
 3  4
[torch.FloatTensor of size 2x2]

Variable containing:
 2  4
 6  8
[torch.FloatTensor of size 2x2]

Variable containing:
 2  4
 6  8
[torch.FloatTensor of size 2x2]

如你所见,当我使用bb=bb*2时,aa并没有受到影响。但是,如果使用 dd *= 2cc 似乎指向(共享)与 cc 相同的地址,它会被更改。

他们各自的前一行是相同的,例如bb = aadd = cc。似乎 *= 运算符将原始深拷贝更改为浅拷贝,并且更改是在复制行本身之后进行的。

我想知道这是否是一个错误。如果是,这很重要,因为它会影响基本的数学运算。通常,我认为只需使用内置的操作功能,例如torch.add() 是一个很好的解决方案。

OS: Mac OS X
PyTorch version: 3.0
How you installed PyTorch (conda, pip, source): conda
Python version: 3.6
CUDA/cuDNN version: None
GPU models and configuration: None

*-------------------------------------

我明白dd *= 2是就地乘法,但是dd的值怎么转成cc?但是如果我使用 dd = dd * 2,新值不会转移到 cc?上一行没有区别:dd = ccbb =aa。 顺便说一句,在 python(不是 pytorch 变量或张量)中,dd *= 2dd = dd * 2 都不会影响 cc 值。

当您执行 dd = cc 时,ddcc 现在都是对同一对象的引用(bb = aa 也是如此)。未复制任何内容!

当您执行 bb = bb * 2 时,* 运算符会创建一个新对象,并且 bb 现在会引用该对象。没有更改现有对象。

当您执行 dd *= 2 时,dd 引用的对象(以及 cc 也引用的对象)被更改。

所以不同之处在于 * 创建了一个新对象,而 = 使变量引用了一个新对象(而不是以任何方式更改对象),而 *=更改对象。

可能 counter-intuitive x *= y 的行为与 x = x * y 不同,但这些是语言的语义,不是错误。

重复您的测试,但另外打印您的对象的 ID:

aa = Variable(torch.FloatTensor([[1,2],[3,4]]))
bb = aa
bb = bb*2
print(bb , id(bb))
print(aa , id(aa))

cc = Variable(torch.FloatTensor([[1,2],[3,4]]))
dd = cc
dd *= 2
print(cc, id(cc))
print(dd, id(dd))

这应该让您了解会发生什么。

我没有手电筒,但普通列表也有类似的做法:

aa = [1,2,3,4]
bb = aa
bb = bb*2
print(bb, id(bb))
print(aa, id(aa))

cc =[1,2,3,4]
dd = cc
dd *= 2
print(cc, id(cc))
print(dd, id(dd))

普通列表的输出(没有火花):

([1, 2, 3, 4, 1, 2, 3, 4], 140432043987888)  # bb  different ids
([1, 2, 3, 4], 140432043930400)              # aa  different ids  
([1, 2, 3, 4, 1, 2, 3, 4], 140432043916032)  # cc  same id, same object
([1, 2, 3, 4, 1, 2, 3, 4], 140432043916032)  # dd  same id, same object