数学运算符差异* =或+ =

时间:2018-03-16 13:16:07

标签: python pytorch

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

代码:

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值。

2 个答案:

答案 0 :(得分:4)

执行dd = cc时,ddcc现在都是对同一对象的引用(bb = aa相同)。什么都没有被复制!

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

执行dd *= 2后,dd引用的对象(以及cc也引用的对象)会发生变化。

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

x *= yx = x * y的行为不同,可能违反直觉,但这些是语言的语义,而不是错误。

答案 1 :(得分:0)

重复测试,但另外打印对象的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