【pytorch学习1】pytorch中的cat、stack、tranpose、permute、unsqeeze详解

【pytorch学习1】pytorch中的cat、stack、tranpose、permute、unsqeeze详解

  • cat
  • stack
  • transpose
  • permute
  • squeeze 和 unsqueeze

首先导入pytorch,利用linspace生成两个4*3的2维tensor

>>> import torch as t
# t.linspace(start,end,num)   
# start到end均匀分为num个,返回值是tensor
>>> a=t.linspace(1,23,12).reshape(4,3)
>>> a
tensor([[ 1.,  3.,  5.],
        [ 7.,  9., 11.],
        [13., 15., 17.],
        [19., 21., 23.]])

>>> b=t.linspace(2,24,12).reshape(4,3)
>>> b
tensor([[ 2.,  4.,  6.],
        [ 8., 10., 12.],
        [14., 16., 18.],
        [20., 22., 24.]])

cat

对数据沿着某一维度拼接,cat后数据的总维数不变。
比如下对tensor a和 tensor b(分别为4×3,4×3)进行拼接。

>>> c=t.cat((a,b),0) # 0表示对行拼接,1表示对列拼接,这个值不能超过a,b的最大维数
>>> c
tensor([[ 1.,  3.,  5.],
        [ 7.,  9., 11.],
        [13., 15., 17.],
        [19., 21., 23.],
        [ 2.,  4.,  6.],
        [ 8., 10., 12.],
        [14., 16., 18.],
        [20., 22., 24.]])
>>> c.shape
torch.Size([8, 3])



>>> c=t.cat((a,b),1)
>>> c
tensor([[ 1.,  3.,  5.,  2.,  4.,  6.],
        [ 7.,  9., 11.,  8., 10., 12.],
        [13., 15., 17., 14., 16., 18.],
        [19., 21., 23., 20., 22., 24.]])
>>> c.shape
torch.Size([4, 6])

stack

增加新的维度进行堆叠
如对tensor a,b在第0个维度上stack,则会变为2×4×3的tensor;在第1个维度上stack,则会变为4×2×3的tensor。
我们先分别测试在各个维度上stack,再输出shape

# 测试第0个维度
>>> d=t.stack((a,b),0)
>>> d
tensor([[[ 1.,  3.,  5.],
         [ 7.,  9., 11.],
         [13., 15., 17.],
         [19., 21., 23.]],

        [[ 2.,  4.,  6.],
         [ 8., 10., 12.],
         [14., 16., 18.],
         [20., 22., 24.]]])
>>> d.shape
torch.Size([2, 4, 3])

# 测试第1个维度
>>> e=t.stack((a,b),1)
>>> e
tensor([[[ 1.,  3.,  5.],
         [ 2.,  4.,  6.]],

        [[ 7.,  9., 11.],
         [ 8., 10., 12.]],

        [[13., 15., 17.],
         [14., 16., 18.]],

        [[19., 21., 23.],
         [20., 22., 24.]]])
>>> e.shape
torch.Size([4, 2, 3])

# 测试第2个维度
>>> f=t.stack((a,b),2)
>>> f
tensor([[[ 1.,  2.],
         [ 3.,  4.],
         [ 5.,  6.]],

        [[ 7.,  8.],
         [ 9., 10.],
         [11., 12.]],

        [[13., 14.],
         [15., 16.],
         [17., 18.]],

        [[19., 20.],
         [21., 22.],
         [23., 24.]]])
>>> f.shape
torch.Size([4, 3, 2])

不知道大家有没有发现,stack里的维度参数和cat的维度参数不一样,cat里dim=1,意味着列拼接,而stack并不是!!!我自己的理解是这样的,有错请大家指正:

stack((tensor1,tensor2,...,tensorn),dim)
参数1:要拼接的tensor,放到一个圆括号里()
参数2,即维度,tensor1的shape从左往右数,在第int(dim)的维度堆叠
      举个栗子:tensor a.shape = 4 × 3,dim=0,
      那么新维度将会在第0个维度上堆叠,第0维的值=N=要堆叠tensor的个数,新tensor.shape=N × 4 × 3
      dim=1 or 2, 同理4 × N × 34 × 3 × N 

transpose

注意和numpy的transpose 有区别:
torch.transpose 只能交换2维的tensor
numpy.transpose 可以交换任意维的数组

>>> a.transpose(0,1) # 第0维和第1维交换
tensor([[ 1.,  7., 13., 19.],
        [ 3.,  9., 15., 21.],
        [ 5., 11., 17., 23.]])
>>> a.transpose(1,0)  # 效果一样,都是交换第0维和第1tensor([[ 1.,  7., 13., 19.],
        [ 3.,  9., 15., 21.],
        [ 5., 11., 17., 23.]])

# transpose 只能交换2维的tensor,输入三个参数会报错,
# 想要交换多维tensor,可以用permute,别急,马上就要介绍了
>>> f.transpose(0,2,1)
Traceback (most recent call last):
  File "", line 1, in <module>
    f.transpose(0,2,1)
TypeError: transpose() takes 2 positional arguments but 3 were given


# np的transpose是可以交换多维数组的,习惯使用transpose交换的同学,可以把tensor转为np的array,
# 再使用transpose,这样就不会限制维度了,
# torch和np共享内存,转换耗时非常短,而且不会开辟新的内存,很方便
>>> import numpy as np
>>>> g=np.array(f)
>>> g
array([[[ 1.,  2.],
        [ 3.,  4.],
        [ 5.,  6.]],

       [[ 7.,  8.],
        [ 9., 10.],
        [11., 12.]],

       [[13., 14.],
        [15., 16.],
        [17., 18.]],

       [[19., 20.],
        [21., 22.],
        [23., 24.]]], dtype=float32)
>>> np.shape(g)
(4, 3, 2)
>>> g.transpose(0,2,1)
array([[[ 1.,  3.,  5.],
        [ 2.,  4.,  6.]],

       [[ 7.,  9., 11.],
        [ 8., 10., 12.]],

       [[13., 15., 17.],
        [14., 16., 18.]],

       [[19., 21., 23.],
        [20., 22., 24.]]], dtype=float32)

permute

permute是更灵活的transpose,可以灵活的对原数据的维度进行调换,而数据本身不变。适合多维tensor

>>> f.shape
torch.Size([4, 3, 2])

>>> h=f.permute(2,1,0)
>>> h.shape
torch.Size([2, 3, 4])

>>> h
tensor([[[ 1.,  7., 13., 19.],
         [ 3.,  9., 15., 21.],
         [ 5., 11., 17., 23.]],

        [[ 2.,  8., 14., 20.],
         [ 4., 10., 16., 22.],
         [ 6., 12., 18., 24.]]])

permute这个函数使用不习惯的可以先把多维tensor转换为np.array,再使用np.transpose交换维度

squeeze 和 unsqueeze

squeeze(dim_n)压缩,即去掉元素数量为1的dim_n维度。unsqueeze(dim_n),增加dim_n维度。
大家还记得tensor a吗?我们把它reshape成1×12的tensor,依旧是二维,只不过有一个维度是1

>>> a
tensor([[ 1.,  3.,  5.],
        [ 7.,  9., 11.],
        [13., 15., 17.],
        [19., 21., 23.]])
>>> a=a.reshape(1,-1)
>>> a
tensor([[ 1.,  3.,  5.,  7.,  9., 11., 13., 15., 17., 19., 21., 23.]])
>>> a.shape
torch.Size([1, 12])

接下来我们先使用squeeze 把新的a,压缩为一维的tensor,再让它变回原来的1×12的二维tenor

>>> a_=a.squeeze ()  #  squeeze 不写参数,默认把所有等于1的维度都给压缩了
>>> a_
tensor([ 1.,  3.,  5.,  7.,  9., 11., 13., 15., 17., 19., 21., 23.])
>>> a_.shape
torch.Size([12])

>>> a__=a.squeeze(0)  # 指定压缩第0维,和上面的结果一样
>>> a__.shape
torch.Size([12])

接下来,我们让a__ 变回1×12的二维tenor

>>> _a=a__.unsqueeze(0) # 指定在第0维上扩展
>>> _a.shape
torch.Size([1, 12])
>>> _a
tensor([[ 1.,  3.,  5.,  7.,  9., 11., 13., 15., 17., 19., 21., 23.]])

你可能感兴趣的:(pytorch)