Pytorch 不同输出之间的转置

조수호*_*조수호 2 python numpy view reshape pytorch

令我的张量维度为 (B, N^2, C),并将其重塑为 (B, C, N, N)。

我认为我有以下两个选择

A = torch.rand(5, 100, 20) # Original Tensor

# First Method
B = torch.transpose(2, 1)
B = B.view(5, 20, 10, 10)

# Second Method
C = A.view(5, 20, 10, 10)
Run Code Online (Sandbox Code Playgroud)

两种方法都有效,但输出略有不同,我无法理解它们之间的区别。

谢谢

Iva*_*van 5

B和 的区别C在于,你已经使用了torch.transpose,这意味着你已经交换了两个轴,这意味着你已经改变了内存的布局。最后的视图只是一个很好的界面,供您访问数据,但它对张量的基础数据没有影响。归根结底就是一个连续的内存数据缓冲区。

如果举一个更小的例子,我们可以更容易理解:

>>> A = torch.rand(1, 4, 3)
tensor([[[0.2656, 0.5920, 0.3774],
         [0.8447, 0.5984, 0.0614],
         [0.5160, 0.8048, 0.6260],
         [0.1644, 0.3144, 0.1040]]])
Run Code Online (Sandbox Code Playgroud)

这里的交换axis=1归结axis=2为批量转置(用数学术语来说):

>>> B = A.transpose(2, 1)
tensor([[[0.4543, 0.7447, 0.7814, 0.3444],
         [0.9766, 0.2732, 0.4766, 0.0387],
         [0.0123, 0.7260, 0.8939, 0.8581]]])
Run Code Online (Sandbox Code Playgroud)

从内存布局来看A有以下内存排列:

>>> A.flatten()
tensor([0.4543, 0.9766, 0.0123, 0.7447, 0.2732, 0.7260, 0.7814, 0.4766, 0.8939,
        0.3444, 0.0387, 0.8581])
Run Code Online (Sandbox Code Playgroud)

虽然B有不同的布局。我所说的布局是指内存排列,我并不是指它的形状,这是不相关的:

>>> B.flatten()
tensor([0.4543, 0.7447, 0.7814, 0.3444, 0.9766, 0.2732, 0.4766, 0.0387, 0.0123,
        0.7260, 0.8939, 0.8581])
Run Code Online (Sandbox Code Playgroud)

正如我所说,重塑(即在张量之上构建视图)不会改变其内存布局,它是更好地操作张量的抽象级别。

所以最后,是的,您最终会得到两个不同的结果:C与 共享相同的数据A,而B是副本并具有不同的内存布局。