理解重塑张量时的顺序

2024-10-02 00:27:32 发布

您现在位置:Python中文网/ 问答频道 /正文

对于张量:

x = torch.tensor([
    [
        [[0.4495, 0.2356],
          [0.4069, 0.2361],
          [0.4224, 0.2362]],
                   
         [[0.4357, 0.6762],
          [0.4370, 0.6779],
          [0.4406, 0.6663]]
    ],    
    [
        [[0.5796, 0.4047],
          [0.5655, 0.4080],
          [0.5431, 0.4035]],
         
         [[0.5338, 0.6255],
          [0.5335, 0.6266],
          [0.5204, 0.6396]]
    ]
])

首先,我们想把它分成2个(x.shape[0])张量,然后再把它们合并。在这里,只要我得到正确的输出,我就不需要实际拆分它,但是对我来说,在视觉上拆分它然后将它们合并在一起会更有意义

例如:

# the shape of the splits are always the same
split1 = torch.tensor([
    [[0.4495, 0.2356],
    [0.4069, 0.2361],
    [0.4224, 0.2362]],

    [[0.4357, 0.6762],
    [0.4370, 0.6779],
    [0.4406, 0.6663]]
])
split2 = torch.tensor([
    [[0.5796, 0.4047],
    [0.5655, 0.4080],
    [0.5431, 0.4035]],

    [[0.5338, 0.6255],
    [0.5335, 0.6266],
    [0.5204, 0.6396]]
])

split1 = torch.cat((split1[0], split1[1]), dim=1)
split2 = torch.cat((split2[0], split2[1]), dim=1)
what_i_want = torch.cat((split1, split2), dim=0).reshape(x.shape[0], split1.shape[0], split1.shape[1])

enter image description here

对于上面的结果,我认为直接重塑x.Reforme([2,3,4])会起作用,它会导致正确的尺寸,但结果不正确

总的来说,我是:

  1. 不确定如何将张量拆分为x形[0]张量
  2. 对重塑的工作原理感到困惑。大多数时候,我都能得到正确的尺寸,但数字的顺序总是不正确的

多谢各位


Tags: ofthe尺寸torch视觉alwaysarecat
2条回答

您的示例使用numpy方法(我没有安装tensorflow):

In [559]: x = np.array([
     ...:     [
     ...:         [[0.4495, 0.2356],
     ...:           [0.4069, 0.2361],
     ...:           [0.4224, 0.2362]],
     ...: 
     ...:          [[0.4357, 0.6762],
     ...:           [0.4370, 0.6779],
     ...:           [0.4406, 0.6663]]
     ...:     ],
     ...:     [
     ...:         [[0.5796, 0.4047],
     ...:           [0.5655, 0.4080],
     ...:           [0.5431, 0.4035]],
     ...: 
     ...:          [[0.5338, 0.6255],
     ...:           [0.5335, 0.6266],
     ...:           [0.5204, 0.6396]]
     ...:     ]
     ...: ])
In [560]: x.shape
Out[560]: (2, 2, 3, 2)

In [562]: s1=np.concatenate((x[0,0],x[0,1]), axis=1)
In [563]: s2=np.concatenate((x[1,0],x[1,1]), axis=1)
In [564]: s1.shape
Out[564]: (3, 4)

In [565]: new =np.concatenate((s1,s2), axis=0)
In [566]: new.shape
Out[566]: (6, 4)
In [567]: new.reshape(2,3,4)
Out[567]: 
array([[[0.4495, 0.2356, 0.4357, 0.6762],
        [0.4069, 0.2361, 0.437 , 0.6779],
        [0.4224, 0.2362, 0.4406, 0.6663]],

       [[0.5796, 0.4047, 0.5338, 0.6255],
        [0.5655, 0.408 , 0.5335, 0.6266],
        [0.5431, 0.4035, 0.5204, 0.6396]]])

numpy有一个stack将数组连接到一个新的轴上,因此我们可以跳过最后一个连接并使用

np.stack((s1,s2))    # or
np.array((s1,s2))

直接的方法是交换中间的两个维度:

In [569]: x.transpose(0,2,1,3).shape
Out[569]: (2, 3, 2, 2)

In [571]: x.transpose(0,2,1,3).reshape(2,3,4)
Out[571]: 
array([[[0.4495, 0.2356, 0.4357, 0.6762],
        [0.4069, 0.2361, 0.437 , 0.6779],
        [0.4224, 0.2362, 0.4406, 0.6663]],

       [[0.5796, 0.4047, 0.5338, 0.6255],
        [0.5655, 0.408 , 0.5335, 0.6266],
        [0.5431, 0.4035, 0.5204, 0.6396]]])

reshape可用于组合“相邻”维度,但不会对基础数据重新排序。也就是说x.ravel()reshape保持相同。虽然允许将(2,2,3,2)重塑为(2,3,4),但值的明显顺序可能不是您想要的。如果您尝试重塑,这可能更容易看到

In [572]: np.arange(6).reshape(2,3)
Out[572]: 
array([[0, 1, 2],
       [3, 4, 5]])
In [573]: _.reshape(3,2)
Out[573]: 
array([[0, 1],
       [2, 3],
       [4, 5]])

将其与转置进行比较:

In [574]: np.arange(6).reshape(2,3).transpose(1,0)
Out[574]: 
array([[0, 3],
       [1, 4],
       [2, 5]])

我在[569]中所做的转置/交换可能很难理解。有足够多不同的方法对维度进行重新排序,很难一概而论

< Python、PyTrk、NuMPy、C++等内存中元素的顺序为row-major排序:

[ first, second
  third, forth  ]

在matlab、fortran等语言中,顺序为column major

[ first,  third
  second, fourth ]

对于高维张量,这意味着元素的顺序是从最后一维到第一维

您可以使用^{}后跟^{}轻松地将其可视化:

a = torch.arange(24)
a.view(2,3,4)

结果与

tensor([[[ 0,  1,  2,  3],
    [ 4,  5,  6,  7],
    [ 8,  9, 10, 11]],

   [[12, 13, 14, 15],
    [16, 17, 18, 19],
    [20, 21, 22, 23]]])

如您所见,元素首先按行(最后一个维度)排序,然后按列排序,最后按第一个维度排序

当你reshape一个张量时,你不会改变元素的基本顺序,只会改变张量的shape。但是,如果使用^{}张量,则会更改元素的基本顺序

看一下a.view(3,2,4)a.permute(0,1,2)之间的区别——得到的两个张量的shape是相同的,但不是元素的顺序:

In []: a.view(3,2,4)
Out[]:
tensor([[[ 0,  1,  2,  3],
         [ 4,  5,  6,  7]],

        [[ 8,  9, 10, 11],
         [12, 13, 14, 15]],

        [[16, 17, 18, 19],
         [20, 21, 22, 23]]])

In []: a.permute(1,0,2)
Out[]:
tensor([[[ 0,  1,  2,  3],
         [12, 13, 14, 15]],

        [[ 4,  5,  6,  7],
         [16, 17, 18, 19]],

        [[ 8,  9, 10, 11],
         [20, 21, 22, 23]]])

相关问题 更多 >

    热门问题