pytorch张量维度操作(拼接、维度扩展、压缩、转置、重复)

目录

  • 一、拼接张量

  • 1、torch.cat()

  • 2、torch.stack()

  • 二、扩大张量

  • 1、torch.Tensor.expand()

  • 2、torch.unsqueeze()

  • 三、压缩张量

  • 1、torch.squeeze()

  • 四、重复张量

  • 1、torch.Tensor.repeat()

  • 2、torch.Tensor.unfold()

  • 五、缩小张量

  • 1、torch.Tensor.narrow()

  • 六、张量变形 z

  • 1、torch.Tensor.view()

  • 七、重设张量尺寸

  • 1、torch.Tensor.resize_()

  • 2、torch.reshape()

  • 八、置换张量维度

  • 1、torch.Tensor.permute()

一、拼接张量
1、torch.cat()

torch.cat(tensors, dim=0, out=None) → Tensor

在指定的维度dim上对序列 seq 进行连接操作,注意:张量可以有多个,不一定只是两个。

参数:

tensors (sequence of Tensors) - 相同类型的张量的任何python序列。所提供的非空张量必须具有相同的形状,除了cat尺寸。
dim (int, optional) - 沿着此维度连接张量
out (Tensor, optional) - 输出参数

例子:

 
   
  1. >>> x = torch.Tensor([[1, 2, 3],[4, 5, 6]])

  2. >>> x

  3. tensor([[1., 2., 3.],

  4. [4., 5., 6.]])

  5. >>> >>> x.shape # 打印原始形状

  6. torch.Size([2, 3])

  7. >>> y = torch.cat((x, x, x), 0) # 在0维进行拼接

  8. tensor([[1., 2., 3.],

  9. [4., 5., 6.],

  10. [1., 2., 3.],

  11. [4., 5., 6.],

  12. [1., 2., 3.],

  13. [4., 5., 6.]])

  14. >>> y.shape # 打印形状,发现0维形状由 2-->6

  15. torch.Size([6, 3])

  16. >>> z = torch.cat((x, x, x), 1) # 在1维进行拼接

  17. tensor([[1., 2., 3., 1., 2., 3., 1., 2., 3.],

  18. [4., 5., 6., 4., 5., 6., 4., 5., 6.]])

  19. >>> z.shape # 打印形状,发现1维形状由 3-->9

  20. torch.Size([2, 9])

2、torch.stack()

torch.stack(tensors, dim=0, out=None) → Tensor

沿着一个新的维数串联张量序列,所有的张量必须是相同的大小。这个和cat()的不同之处在于新增加了一个维度,新增的维度的位置就是dim。

参数:

tensors (sequence of Tensors) - 连接的张量序列
dim (int, optional) - 维插入。必须在0和连接张量的维数之间(包括)
out (Tensor, optional) - 输出参数

例子:

  1. >>> a = torch.IntTensor([[1,2,3],[11,22,33]])

  2. >>>> a

  3. tensor([[ 1, 2, 3],

  4. [11, 22, 33]], dtype=torch.int32)

  5. >>> a.shape

  6. torch.Size([2, 3])

  7. >>> b= torch.IntTensor([[4,5,6],[44,55,66]])

  8. >>> b

  9. tensor([[ 4, 5, 6],

  10. [44, 55, 66]], dtype=torch.int32)

  11. >>> b.shape

  12. torch.Size([2, 3])

  13. >>> c=torch.stack([a,b],0)

  14. >>> c

  15. tensor([[[ 1, 2, 3],

  16. [11, 22, 33]],

  17. [[ 4, 5, 6],

  18. [44, 55, 66]]], dtype=torch.int32)

  19. >>> c.shape # 在第0维将这两个张量进行拼接,而原始的0维度向后移动

  20. torch.Size([2, 2, 3])

  21. >>> d=torch.stack([a,b],1)

  22. >>> d

  23. tensor([[[ 1, 2, 3],

  24. [ 4, 5, 6]],

  25. [[11, 22, 33],

  26. [44, 55, 66]]], dtype=torch.int32)

  27. >>> d.shape # 在第1维将这两个张量进行拼接,而原始的1维度向后移动

  28. torch.Size([2, 2, 3])

  29. >>> e=torch.stack([a,b],2)

  30. >>> e

  31. tensor([[[ 1, 4],

  32. [ 2, 5],

  33. [ 3, 6]],

  34. [[11, 44],

  35. [22, 55],

  36. [33, 66]]], dtype=torch.int32)

  37. >>> e.shape # 在第2维将这两个张量进行拼接

  38. torch.Size([2, 3, 2])

对于高维张量操作理解的时候:比如上面在拼接一维的时候,将二维就看成一个元素,这样就好理解了,如果还不理解,来看看下面的过程:

 
   
  1. c, dim = 0时, c = [ a, b]

  2. d, dim =1 时, d = [ [a[0] , b[0] ] , [a[1], b[1] ] ]

  3. e, dim = 2 时, e=[ [ [ a[0][0], b[0][0] ], [ a[0][1], b[0][1]], [a[0][2], b[0][2]] ], [ [a[1][0], b[1][0] ], [a[1][1], b[0][1] ], [a[1][2], b[1][2] ] ] ]

二、扩大张量
1、torch.Tensor.expand()

torch.Tensor.expand(sizes) → Tensor

返回张量的一个新视图,可以将张量的单个维度(维度为1)扩大为更大的尺寸。张量也可以扩大为更高维,新增加的维度将在最外层。 扩大张量不需要分配新内存,仅仅是新建一个张量的视图。任意一个一维张量在不分配新内存情况下都可以扩展为任意的维度。传入-1则意味着维度扩大不涉及这个维度。

参数:

sizes (torch.Size or int…) – 想要扩展的目标维度

例子:

 
   
  1. x = torch.tensor([[1], [2], [3]])

  2. >>> x.shape

  3. torch.Size([3, 1])

  4. >>> x.expand(3, 4)

  5. tensor([[1, 1, 1, 1],

  6. [2, 2, 2, 2],

  7. [3, 3, 3, 3]])

  8. >>> x.expand(-1, 4) # -1 意味着不改变维度的大小

  9. tensor([[ 1, 1, 1, 1],

  10. [ 2, 2, 2, 2],

  11. [ 3, 3, 3, 3]])

  12. >>> y = x.expand(4,3,4) # 维度的扩增,注意:只能在最外层

  13. >>> y

  14. tensor([[[1, 1, 1, 1],

  15. [2, 2, 2, 2],

  16. [3, 3, 3, 3]],

  17. [[1, 1, 1, 1],

  18. [2, 2, 2, 2],

  19. [3, 3, 3, 3]],

  20. [[1, 1, 1, 1],

  21. [2, 2, 2, 2],

  22. [3, 3, 3, 3]],

  23. [[1, 1, 1, 1],

  24. [2, 2, 2, 2],

  25. [3, 3, 3, 3]]])

  26. >>> y.shape

  27. torch.Size([4, 3, 4])

2、torch.unsqueeze()

torch.unsqueeze(input, dim) → Tensor

返回一个新的张量,其维数为1插入到指定的位置。返回的张量与这个张量共享相同的基础数据。

参数:

input (Tensor) – 输入的张量
dim (int) – 要插入维数的索引

例子:

  1. >>> x = torch.tensor([1, 2, 3, 4])

  2. >>> y = torch.unsqueeze(x, 0)

  3. >>> y

  4. tensor([[ 1, 2, 3, 4]])

  5. >>> y.shape

  6. torch.Size([1, 4])

  7. >>> z = torch.unsqueeze(x, 1)

  8. >>> z

  9. tensor([[ 1],

  10. [ 2],

  11. [ 3],

  12. [ 4]])

  13. >>> z.shape

  14. torch.Size([4, 1])

当然unsqueeze()也可以作为对象的方法调用,看下面例子:

 
   
  1. >>> x = torch.tensor([1, 2, 3, 4])

  2. >>> x.shape

  3. torch.Size([4])

  4. >>> y = x.unsqueeze(0)

  5. >>> y

  6. tensor([[1, 2, 3, 4]])

  7. >>> y.shape

  8. torch.Size([1, 4])

  9. >>> z = x.unsqueeze(1)

  10. >>> z

  11. tensor([[1],

  12. [2],

  13. [3],

  14. [4]])

  15. >>> z.shape

  16. torch.Size([4, 1])

三、压缩张量
1、torch.squeeze()

torch.squeeze(input, dim=None, out=None) → Tensor

除去输入张量input中数值为1的维度,并返回新的张量。如果输入张量的形状为
(A×1×B×C×1×D),那么输出张量的形状为:
(A×B×C×D)。
当通过dim参数指定维度时,维度压缩操作只会在指定的维度上进行。如果输入向量的形状为
(A×1×B),squeeze(input, 0)会保持张量的维度不变,只有在执行squeeze(input, 1)时,输入张量的形状会被压缩至
(A×B)。
如果一个张量只有1个维度,那么它不会受到上述方法的影响。
输出的张量与原张量共享内存,如果改变其中的一个,另一个也会改变。

参数:

input (Tensor) – 输入张量
dim (int, optional) – 如果给定,则只会在给定维度压缩
out (Tensor, optional) – 输出张量

例子:

 
   
  1. >>> x = torch.zeros(2, 1, 2, 1, 2)

  2. >>> x.size()

  3. torch.Size([2, 1, 2, 1, 2])

  4. >>> y = torch.squeeze(x)

  5. >>> y.size()

  6. torch.Size([2, 2, 2])

  7. >>> y = torch.squeeze(x, 0)

  8. >>> y.size()

  9. torch.Size([2, 1, 2, 1, 2])

  10. >>> y = torch.squeeze(x, 1)

  11. >>> y.size()

  12. torch.Size([2, 2, 1, 2])

四、重复张量
1、torch.Tensor.repeat()

torch.Tensor.repeat(sizes) → Tensor

沿着指定的维度重复张量。不同于expand()方法,本函数复制的是张量中的数据。

参数:

size (torch.size or int…) - 沿着每一维重复的次数

例子:

 
   
  1. >>> x = torch.tensor([1, 2, 3])

  2. >>> x.repeat(4, 2)

  3. tensor([[ 1, 2, 3, 1, 2, 3],

  4. [ 1, 2, 3, 1, 2, 3],

  5. [ 1, 2, 3, 1, 2, 3],

  6. [ 1, 2, 3, 1, 2, 3]])

  7. >>> x.repeat(4, 2, 1).size()

  8. torch.Size([4, 2, 3])

2、torch.Tensor.unfold()

torch.Tensor.unfold(dim, size, step) → Tensor

返回一个新的张量,其中元素复制于有原张量在dim维度上的数据,复制重复size次,复制时的步进值为step。

参数:

dim (int) - 目标维度
size (int) - 复制重复的次数(展开维度)
step (int) - 步长

例子:

 
   
  1. >>> x = torch.arange(1., 8)

  2. >>> x

  3. tensor([ 1., 2., 3., 4., 5., 6., 7.])

  4. >>> x.unfold(0, 2, 1) # 复制2次,步长为1

  5. tensor([[ 1., 2.],

  6. [ 2., 3.],

  7. [ 3., 4.],

  8. [ 4., 5.],

  9. [ 5., 6.],

  10. [ 6., 7.]])

  11. >>> x.unfold(0, 2, 2) # 复制2次,步长为2

  12. tensor([[ 1., 2.],

  13. [ 3., 4.],

  14. [ 5., 6.]])

  15. >>> x.unfold(0,3,1) # 复制3次,步长为1

  16. tensor([[1., 2., 3.],

  17. [2., 3., 4.],

  18. [3., 4., 5.],

  19. [4., 5., 6.],

  20. [5., 6., 7.]])

五、缩小张量
1、torch.Tensor.narrow()

torch.Tensor.narrow(dimension, start, length) → Tensor

返回一个经过缩小后的张量。操作的维度由dimension指定。缩小范围是从start开始到start+length。执行本方法的张量与返回的张量共享相同的底层内存。

参数:

dimension (int) – 要进行缩小的维度
start (int) – 开始维度索引
length (int) – 缩小持续的长度

例子:

 
   
  1. >>> x = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

  2. >>>> x

  3. tensor([[1, 2, 3],

  4. [4, 5, 6],

  5. [7, 8, 9]])

  6. >>> x.narrow(0, 0, 2)

  7. tensor([[ 1, 2, 3],

  8. [ 4, 5, 6]])

  9. >>> x.narrow(1, 1, 2)

  10. tensor([[ 2, 3],

  11. [ 5, 6],

  12. [ 8, 9]])

六、张量变形 z
1、torch.Tensor.view()

torch.Tensor.view(args) → Tensor

返回一个有相同数据但是不同形状的新的向量。返回的张量必须与原张量有相同的元素个数,但形状可以不同。

参数:

args (torch.Size or int…) - 指定的尺寸

例子:

  1. >>> x = torch.randn(4, 4)

  2. >>> x.size()

  3. torch.Size([4, 4])

  4. >>> y = x.view(16)

  5. >>> y.size()

  6. torch.Size([16])

  7. >>> z = x.view(-1, 8) # 大小-1是从其他维度推断出来的,也就是自适应

  8. >>> z.size()

  9. torch.Size([2, 8])

  10. >>> a = torch.randn(1, 2, 3, 4)

  11. >>> a.size()

  12. torch.Size([1, 2, 3, 4])

  13. >>> b = a.transpose(1, 2) # Swaps 2nd and 3rd dimension

  14. >>> b.size()

  15. torch.Size([1, 3, 2, 4])

  16. >>> c = a.view(1, 3, 2, 4) # Does not change tensor layout in memory

  17. >>> c.size()

  18. torch.Size([1, 3, 2, 4])

  19. >>> torch.equal(b, c)

  20. False

七、重设张量尺寸
1、torch.Tensor.resize_()

torch.Tensor.resize_(sizes, memory_format=torch.contiguous_format)

将张量的尺寸调整为指定的大小。如果元素个数比当前的内存大小大,就将底层存储大小调整为与新元素数目一致的大小。

如果元素个数比当前内存小,则底层存储不会被改变。原来张量中被保存下来的元素将保持不变,但新内存将不会被初始化。

参数:

sizes (torch.Size or int…) - 需要调整的大小
memory_format (torch.memory_format, optional) – 所需的张量存储格式。默认值:torch.contiguous_format。注意,如果self.size()匹配大小,self的内存格式将不受影响。

例子:

  1. >>> x = torch.tensor([[1, 2], [3, 4], [5, 6]])

  2. >>> x.resize_(2, 2)

  3. tensor([[ 1, 2],

  4. [ 3, 4]])

注意:resize()_会把原来张量设置为重置张量尺寸,而resize()会返回重置张量而不会改变原始张量。

2、torch.reshape()

torch.reshape(input, shape) → Tensor

返回与输入相同数据和元素数目的张量,但具有指定的形状。如果可能,返回的张量将是输入的视图。否则,它将是一个副本。连续输入和具有兼容跨距的输入可以在不复制的情况下进行重塑,但是您不应该依赖于复制和查看行为。

参数:

input (Tensor) – 要重塑的张量
shape (tuple of python:ints) – 新的形状

例子:

 
   
  1. >>> a = torch.arange(4.)

  2. >>> torch.reshape(a, (2, 2))

  3. tensor([[ 0., 1.],

  4. [ 2., 3.]])

  5. >>> b = torch.tensor([[0, 1], [2, 3]])

  6. >>> torch.reshape(b, (-1,))

  7. tensor([ 0, 1, 2, 3])

八、置换张量维度
1、torch.Tensor.permute()

torch.Tensor.permute(dims) → Tensor

将执行本方法的张量的维度换位。

参数:

dim (int) - 指定换位顺序

例子:

  1. >>> x = torch.randn(2, 3, 5)

  2. >>> x.size()

  3. torch.Size([2, 3, 5])

  4. >>> x.permute(2, 0, 1).size()

  5. torch.Size([5, 2, 3])

你可能感兴趣的:(pytorch,深度学习,人工智能)