pytorch中view,reshape,transpose,permute的作用与异同

pytorch中view,reshape,transpose,permute的作用与异同

view与reshape的功能与异同

  • view与reshape都可以改变目标的形状

  • 示例:

    >>> # view的例子
    >>> x = torch.randn(4, 4)  # 生成一个结构为(4,4)的随机Tensor
    >>> x.size()  # 打印x的结构
    torch.Size([4, 4])
    >>> y = x.view(16)  # 改变x的结构为(16)
    >>> y.size()
    torch.Size([16])
    >>> z = x.view(-1, 8)  # 改变x的结构为(自适应,8),-1即pytorch框架会自己推断出是多少
    >>> z.size()
    torch.Size([2, 8])
    
    >>> # reshape的例子
    >>> a = torch.arange(4.)  # 生成一个结构为(4)的连续整型Tensor
    >>> a
    [ 0. , 1. , 2. , 3. ]
    >>> torch.reshape(a, (2, 2))  # 改变a的结构为(2,2)
    tensor([[ 0.,  1.],
            [ 2.,  3.]])
    >>> b = torch.tensor([[0, 1], [2, 3]])
    >>> c = b.reshape((-1,))  # 改变b的结构为自适应推算结构
    >>> c
    tensor([ 0,  1,  2,  3])
    
  • 那么view与reshape功能都一样,区别在哪里喃?

    区别在于:view生成的对象y与原来的对象x是共用一个存储空间,x的某个值改变了,y也会跟着改变。而reshape生成的对象不一定与原来的对象共用一个存储空间。

  • 除此之外,pytorch官方文档建议,如果要生成一个对象的复制对象(即不使用同一存储空间),建议使用clone()方法。如果要生成一个对象的引用对象(即使用同一存储空间),建议使用view()方法

view与transpose的异同,以及transpose的功能

  • transpose的功能是交换目标的两个维度

  • 示例:

    >>> x = torch.randn(2, 3)
    >>> x.shape
    torch.Size([2, 3])
    >>> x 
    tensor([[-0.7859, -0.6206, -1.0093],
            [-0.3472,  0.2701,  2.5651]])
    >>> y = torch.transpose(x, 0, 1)  # 交换x的0维与1维即交换x.shape的2与3
    >>> y.shape
    torch.Size([3, 2])
    >>> y 
    tensor([[-0.7859, -0.3472],
            [-0.6206,  0.2701],
            [-1.0093,  2.5651]])
    
  • view虽然与transpose都能改变目标的形状,且都是返回一个共用存储空间的对象

    但是区别有:

    1. transpose是交换目标的维度,而view是将目标的数据重排成新的形状

    2. pytorch中有个概念contiguous,即相邻的数据在存储结构中是相邻的

      而transpose会将一个本来contiguous的Tensor变为一个不contiguous的Tensor,view不会有这种效果。

      也即x的x[0,0]与x[0,1]是在存储空间是连续的,有y=x.transpose(…)后虽然y[0,0]==x[0,0] and y[0,1]==x[0,1]但是y[0,0]可能与y[0,1]的存储空间不是连续的了

      示例:

      >>> x = torch.tensor([[1, 2, 3], [4, 5, 6]])
      >>> y = x.transpose(0, 1)
      >>> print(x.data_ptr())
      ... print(y.data_ptr())  # 可以看到他们的存储空间是同一个
      2413295081664
      2413295081664
      >>> print(x.is_contiguous())
      ... print(y.is_contiguous())  # 可以看到他们的contiguous特性是不一样的
      True
      False
      
    3. view方法只能处理contiguous的Tensor

      示例:

      >>> # 接上面的代码
      >>> y.view(2,3)
      Traceback (most recent call last):
        File "**********************************************************", line 3553, in run_code
          exec(code_obj, self.user_global_ns, self.user_ns)
        File "", line 1, in <module>
          y.view(2,3)
      RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
      >>> y.reshape(2,3)  # reshape是可以的
      tensor([[10,  4,  2],
              [ 5,  3,  6]])
      

transpose与permute的异同,以及permute的功能

  • permute 与tranpose() 是相似的,但是 transpose() 只能交换两个维度,而 permute() 可以一次性交换所有的维度。

    示例:

    >>> x = torch.randn(2, 3, 5)
    >>> x.size()
    torch.Size([2, 3, 5])
    >>> torch.permute(x, (2, 0, 1)).size()
    torch.Size([5, 2, 3])
    

    值得注意的是,再permute()中,你必须提供所有维度的一个排列,而在transpose()中只需要提供两个维度的顺序。transpose()可以视为一个特殊的permute()方法。

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