根据索引是列表还是整数,我正面临着pythorch的某种不一致的行为。看一下这段代码:
pytorch
在第二个示例中,我不明白为什么t
无法更新aaa , aab , aac
!
答案 0 :(得分:2)
查看两个索引之间的区别:
In []: t[0, 0].shape
Out[]: torch.Size([])
In []: t[[0], [0]].shape
Out[]: torch.Size([1])
当直接为(0, 0)
的第t
个元素建立索引时,您将对该条目进行引用,并且可以在其中插入add_
。 t[0,0]
的形状为[]
-即返回标量-(0,0)
条目的内容。
但是,当您使用列表索引([0], [0])
时,您将获得一维张量,形状为[1]
。也就是说,您得到t
的子张量的副本。然后,将add_
放置到该子张量副本中,对原始t
无效:
In []: r = t[[0], [0]].add_(10)
In []: t
Out[]:
tensor([[0, 1],
[1, 0]])
In []: r
Out[]: tensor([10])
也许您想研究index_add_()
来完成任务。
更新
当您使用列表索引分配给t
时,您并不是在创建副本(没有意义。
t[[0], [0]] += 10
翻译为
t[[0], [0]] = t[[0], [0]] + 10
也就是说,在右侧,我们有(0,0)
的{{1}}子张量的副本,并且我们在该子张量上加了10,其形状为t
的形状[1]
张量。在左侧,我们将此[10]
分配给[10]
的{{1}}子张量(而不是它的副本-没有意义)。
因此(0,0)
的输出是
t
答案 1 :(得分:2)
那是因为花式索引(即使用列表进行索引)返回一个副本,而直接索引则将视图返回到原始张量。一种简单的检查方法是比较基础的storage
In [16]: a = torch.arange(3)
In [17]: a.storage()
Out[17]:
0
1
2
[torch.LongStorage of size 3]
In [18]: a[0].storage()
Out[18]:
0
1
2
[torch.LongStorage of size 3]
In [19]: a[[0]].storage()
Out[19]:
0
[torch.LongStorage of size 1]
请注意a[0]
是如何单个元素,但是由于它只是原始张量的视图,因此它的存储仍然是完整数组。