Pytorch中 permute、transpose 和 view 、resize函数

1 transpose与permute

transpose() 和 permute() 都是返回转置后矩阵,

transpose用法:tensor.transpose(dim0, dim1)
只能操作2D矩阵的转置, transpose每次只能交换两个维度, 这是相比于permute的一个不同点,每次输入两个index,实现转置,,参数顺序无所谓。
permute用法:tensor.permute(dim0, dim1, ...., dimn)
permute可以进行多维度转置, permute每次可以交换多个维度,但所有的维度也必须都写上,参数顺序表示交换结果是原值的哪个维。

permute操作可以有1至多步的Transpose操作实现

注意:使用transpose或permute之后,若要使用view,必须先contiguous()

# 创造二维数据x,dim=0时候2,dim=1时候3
x = torch.randn(2,3)       'x.shape  →  [2,3]'
# 创造三维数据y,dim=0时候2,dim=1时候3,dim=2时候4
y = torch.randn(2,3,4)   'y.shape  →  [2,3,4]'

"""
操作dim不同:
transpose()只能一次操作两个维度;permute()可以一次操作多维数据,
且必须传入所有维度数,因为permute()的参数是int*。
"""

# 对于transpose
x.transpose(0,1)     'shape→[3,2] '  
x.transpose(1,0)     'shape→[3,2] '  
y.transpose(0,1)     'shape→[3,2,4]' 
y.transpose(0,2,1)  'error,操作不了多维'

# 对于permute()
x.permute(0,1)     'shape→[2,3]'
x.permute(1,0)     'shape→[3,2], 注意返回的shape不同于x.transpose(1,0) '
y.permute(0,1)     "error 没有传入所有维度数"
y.permute(1,0,2)  'shape→[3,2,4]'

"""
操作dim不同:
transpose()只能一次操作两个维度, 维度的顺序不影响结果;permute()可以一次操作多维数据,
且必须传入所有维度数,因为permute()的参数是int*。
"""
# 对于transpose, (0,1) 和 (1,0) 都是指变换 维度 0 和 1, 输入顺序不影响 
x1 = x.transpose(0,1)   'shape→[3,2] '  
x2 = x.transpose(1,0)   '也变换了,shape→[3,2] '  

# 对于permute(),
x1 = x.permute(0,1)     '保持原理tensor不变, 不同transpose,shape→[2,3] '  
x2 = x.permute(1,0)     'shape→[3,2] '  

y1 = y.permute(0,1,2)     '保持不变,shape→[2,3,4] '  
y2 = y.permute(1,0,2)     'shape→[3,2,4] '  
y3 = y.permute(1,2,0)     'shape→[3,4,2] ' 

用view()函数改变通过转置后的数据结构,导致报错

RuntimeError: invalid argument 2: view size is not compatible with input tensor's....

这是因为tensor经过转置后数据的内存地址不连续导致的,也就是tensor . is_contiguous()==False
虽然在torch里面,view函数相当于numpy的reshape,但是这时候reshape()可以改变该tensor结构,但是view()不可以

x = torch.rand(3,4)
x = x.transpose(0,1)
print(x.is_contiguous()) # 是否连续
'False'
# 会发现
x.view(3,4)
'''
RuntimeError: invalid argument 2: view size is not compatible with input tensor's....
就是不连续导致的
'''
# 但是这样是可以的。
x = x.contiguous()
x.view(3,4)

x = torch.rand(3,4)
x = x.permute(1,0) # 等价x = x.transpose(0,1)
x.reshape(3,4)
'''这就不报错了
说明x.reshape(3,4) 这个操作
等于x = x.contiguous().view()
尽管如此,但是我们还是不推荐使用reshape
除非为了获取完全不同但是数据相同的克隆体
'''

调用contiguous()时,会强制拷贝一份tensor,让它的布局和从头创建的一毛一样。
只需要记住了,每次在使用view()之前,该tensor只要使用了transpose()和permute()这两个函数一定要contiguous().

2 view 与transpose与permute的区别与联系

transpose与permute会实实在在的根据需求(要交换的dim)把相应的Tensor元素的位置进行调整, 而view 会将Tensor所有维度拉平成一维 (即按行,这也是为什么view操作要求Tensor是contiguous的原因),然后再根据传入的的维度(只要保证各维度的乘积=总元素个数即可)信息重构出一个Tensor。

a = torch.Tensor([[[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15]], 
                  [[-1,-2,-3,-4,-5], [-6,-7,-8,-9,-10], [-11,-12,-13,-14,-15]]])
>>> a.shape
torch.Size([2, 3, 5])
# 还是上面的Tensor a
>>> print(a.shape)
torch.Size([2, 3, 5])
>>> print(a.view(2,5,3))
tensor([[[  1.,   2.,   3.],
         [  4.,   5.,   6.],
         [  7.,   8.,   9.],
         [ 10.,  11.,  12.],
         [ 13.,  14.,  15.]],

        [[ -1.,  -2.,  -3.],
         [ -4.,  -5.,  -6.],
         [ -7.,  -8.,  -9.],
         [-10., -11., -12.],
         [-13., -14., -15.]]])
>>> c = a.transpose(1,2)
>>> print(c, c.shape)
(tensor([[[  1.,   6.,  11.],
          [  2.,   7.,  12.],
          [  3.,   8.,  13.],
          [  4.,   9.,  14.],
          [  5.,  10.,  15.]],
 
         [[ -1.,  -6., -11.],
          [ -2.,  -7., -12.],
          [ -3.,  -8., -13.],
          [ -4.,  -9., -14.],
          [ -5., -10., -15.]]]),
torch.Size([2, 5, 3]))

即使view()transpose()最终得到的Tensor的shape是一样的,但二者内容并不相同。view函数只是按照给定的(2,5,3)的Tensor维度,将元素按顺序一个个填进去;而transpose函数,则的确是在进行第一个第二维度的转置

3 view与reshape的区别

不同点:

而.reshape()方法不受此限制;如果对 tensor 调用过 transpose, permute等操作的话会使该 tensor 在内存中变得不再连续。

view()方法只适用于满足连续性(contiguous)条件的tensor,并且该操作不会开辟新的内存空间,只是产生了对原存储空间的一个新别称和引用,返回值是视图。如果tensor 不满足连续性条件,需要先调用.contiguous()方法

也就是说view不会改变原来数据的存放方式,并且,也不会产生数据的副本,view返回的是视图。

而reshape,而reshape()方法的返回值既可以是视图,也可以是副本,当tensor满足连续性条件时返回view,否则返回副本 reshape() 此时等价于先调用contiguous()方法, 再使用view() 。

也就是说reshape返回的可以是view的值,也可以是先contiuous,再view的值

PyTorch:view() 与 reshape() 区别详解_地球被支点撬走啦的博客-CSDN博客_reshape view

你可能感兴趣的:(AI之路,-,Face,pytorch,python,numpy)