`squeeze()` 与 `unsqueeze()`

问题描述 投票:0回答:4

即使在查看了文档和

相关问题
之后,我也不明白
squeeze()
unsqueeze()对张量做了什么。

我试图通过自己用Python探索来理解它。我首先创建了一个随机张量

x = torch.rand(3,2,dtype=torch.float)
>>> x
tensor([[0.3703, 0.9588],
        [0.8064, 0.9716],
        [0.9585, 0.7860]])

但是无论我如何挤压它,我最终都会得到相同的结果:

torch.equal(x.squeeze(0), x.squeeze(1))
>>> True

如果我现在尝试松开,我会得到以下信息,

>>> x.unsqueeze(1)
tensor([[[0.3703, 0.9588]],
        [[0.8064, 0.9716]],
        [[0.9585, 0.7860]]])
>>> x.unsqueeze(0)
tensor([[[0.3703, 0.9588],
         [0.8064, 0.9716],
         [0.9585, 0.7860]]])
>>> x.unsqueeze(-1)
tensor([[[0.3703],
         [0.9588]],
        [[0.8064],
         [0.9716]],
        [[0.9585],
         [0.7860]]])

但是,如果我现在创建一个张量

 x = torch.tensor([1,2,3,4])
,并且尝试将其解开,那么
1
-1
会使其成为一列,而
0
保持不变。

x.unsqueeze(0)
tensor([[1, 2, 3, 4]])
>>> x.unsqueeze(1)
tensor([[1],
        [2],
        [3],
        [4]])
>>> x.unsqueeze(-1)
tensor([[1],
        [2],
        [3],
        [4]])

有人可以解释一下

squeeze()
unsqueeze()
对张量做了什么吗?提供论据
0
1
-1
有什么区别?

python machine-learning deep-learning pytorch tensor
4个回答
53
投票

这是

squeeze
/
unsqueeze
对有效二维矩阵的作用的直观表示:

enter image description here

当您解压缩张量时,您希望将其“解压缩”到哪个维度(如行或列等)是不明确的。

dim
参数决定了这一点 - 即要添加的新维度的位置。

因此,得到的未压缩张量具有相同的信息,但用于访问它们的索引不同。


20
投票

简单地说,

unsqueeze()
向张量“添加”表面
1
维度(在指定维度),而
squeeze
从张量中删除所有表面
1
维度。

您应该查看张量的

shape
属性才能轻松看到它。在你的最后一种情况下,它将是:

import torch

tensor = torch.tensor([1, 0, 2, 3, 4])
tensor.shape # torch.Size([5])
tensor.unsqueeze(dim=0).shape # [1, 5]
tensor.unsqueeze(dim=1).shape # [5, 1]

它对于向网络提供单个样本很有用(这需要第一维是批量的),对于图像来说它是:

# 3 channels, 32 width, 32 height
tensor = torch.randn(3, 32, 32)
# 1 batch, 3 channels, 32 width, 32 height
tensor.unsqueeze(dim=0).shape
如果您创建 1 维的

unsqueeze

,则可以看到 
tensor
,例如像这样:

# 3 channels, 32 width, 32 height and some 1 unnecessary dimensions
tensor = torch.randn(3, 1, 32, 1, 32, 1)
# 1 batch, 3 channels, 32 width, 32 height again
tensor.squeeze().unsqueeze(0) # [1, 3, 32, 32]

4
投票
  1. torch.unsqueeze(input, dim)
    Tensor

    a = torch.randn(4, 4, 4)
    torch.unsqueeze(a, 0).size()
    
    >>> torch.Size([1, 4, 4, 4])
    
    a = torch.randn(4, 4, 4)
    torch.unsqueeze(a, 1).size()
    
    >>> torch.Size([4, 1, 4, 4])
    
    a = torch.randn(4, 4, 4)
    torch.unsqueeze(a, 2).size()
    
    >>> torch.Size([4, 4, 1, 4])
    
    a = torch.randn(4, 4, 4)
    torch.unsqueeze(a, 3).size()
    
    >>> torch.Size([4, 4, 4, 1])
    
  2. torch.squeeze(input, dim=None, out=None)
    Tensor

    b = torch.randn(4, 1, 4)
    
    >>> tensor([[[ 1.2912, -1.9050,  1.4771,  1.5517]],
    
            [[-0.3359, -0.2381, -0.3590,  0.0406]],
    
            [[-0.2460, -0.2326,  0.4511,  0.7255]],
    
            [[-0.1456, -0.0857, -0.8443,  1.1423]]])
    
    b.size()
    
    >>> torch.Size([4, 1, 4])
    
    
    c = b.squeeze(1)
    
    
    b
    >>> tensor([[[ 1.2912, -1.9050,  1.4771,  1.5517]],
    
            [[-0.3359, -0.2381, -0.3590,  0.0406]],
    
            [[-0.2460, -0.2326,  0.4511,  0.7255]],
    
            [[-0.1456, -0.0857, -0.8443,  1.1423]]])
    
    
    b.size()
    >>> torch.Size([4, 1, 4])
    
    c
    >>> tensor([[ 1.2912, -1.9050,  1.4771,  1.5517],
            [-0.3359, -0.2381, -0.3590,  0.0406],
            [-0.2460, -0.2326,  0.4511,  0.7255],
            [-0.1456, -0.0857, -0.8443,  1.1423]])
    
    
    c.size()
    >>> torch.Size([4, 4])
    

0
投票

squeeze() 可以从 0D 或更多 D 张量中删除大小为

1
的零个或多个维度,如下所示:

*备注:

  • squeeze()
    可以与 torch 或张量一起使用。
  • 第一个参数(
    input
    )与
    torch
    或使用张量(必需类型:
    tensor
    int
    float
    complex
    bool
    )。
  • 带有
    torch
    的第二个参数或带有张量的第一个或多个参数是
    dim
    (可选类型:
    int
    tuple
    int
    list
    int
    ): *备注:
    • 每个号码必须是唯一的。
    • 可以去除特定的零个或多个尺寸为
      1
      的维度。
    • 如果尺寸不是
      1
      ,即使设置零个或多个尺寸也不会被删除。
import torch

my_tensor = torch.tensor([[[[0], [1]],
                           [[2], [3]],
                           [[4], [5]]]])
torch.squeeze(input=my_tensor)
my_tensor.squeeze()
torch.squeeze(input=my_tensor, dim=(0, 3))
# tensor([[0, 1],
#         [2, 3],
#         [4, 5]])

torch.squeeze(input=my_tensor, dim=0)
torch.squeeze(input=my_tensor, dim=-4)
# tensor([[[0], [1]],
#         [[2], [3]],
#         [[4], [5]]])

torch.squeeze(input=my_tensor, dim=1)
torch.squeeze(input=my_tensor, dim=2)
# tensor([[[[0], [1]],
#          [[2], [3]],
#          [[4], [5]]]])

torch.squeeze(input=my_tensor, dim=3)
torch.squeeze(input=my_tensor, dim=-1)
# tensor([[[0, 1],
#          [2, 3],
#          [4, 5]]])

unsqueeze() 可以通过设置如下所示的维度,将大小为

1
的维度添加到 0D 或更大的 D 张量:

*备注:

  • unsqueeze()
    可以与
    torch
    或张量一起使用。
  • 第一个参数(
    input
    )与
    torch
    或使用张量(必需类型:
    tensor
    int
    float
    complex
    bool
    )。
  • 带有
    torch
    的第二个参数或带有张量的第一个参数是
    dim
    (必需类型:
    int
    )。 *可以将尺寸为
    1
    的尺寸添加到特定位置。
import torch

my_tensor = torch.tensor([[0, 1, 2],
                          [3, 4, 5],
                          [6, 7, 8],
                          [10, 11, 12]])
torch.unsqueeze(input=my_tensor, dim=0)
my_tensor.unsqueeze(dim=0)
torch.unsqueeze(input=my_tensor, dim=-3)
# tensor([[[0, 1, 2],
#          [3, 4, 5],
#          [6, 7, 8]
#          [10, 11, 12]]])

torch.unsqueeze(input=my_tensor, dim=1)
torch.unsqueeze(input=my_tensor, dim=-2)
# tensor([[[0, 1, 2]],
#         [[3, 4, 5]],
#         [[6, 7, 8]]
#         [[10, 11, 12]]])

torch.unsqueeze(input=my_tensor, dim=2)
torch.unsqueeze(input=my_tensor, dim=-1)
# tensor([[[0], [1], [2]],
#         [[3], [4], [5]],
#         [[6], [7], [8]],
#         [[10], [11], [12]]])

torch.unsqueeze(input=my_tensor, dim=3)
torch.unsqueeze(input=my_tensor, dim=-1)
# 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]]]])
© www.soinside.com 2019 - 2024. All rights reserved.