1.reshape实现矩阵的维度变化

1)reshape函数参数-1的意思

大意是说,数组新的shape属性应该要与原来的配套,如果等于-1的话,那么Numpy会根据剩下的维度计算出数组的另外一个shape属性值。例如:有一个数组z,它的shape属性是(4, 4)

z = np.array([[1, 2, 3, 4],
          [5, 6, 7, 8],
          [9, 10, 11, 12],
          [13, 14, 15, 16]])
z.shape
(4, 4)

z.reshape(-1)
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16])

z.reshape(-1, 1)

先前我们不知道z的shape属性是多少,但是想让z变成只有一列,行数不知道多少,通过`z.reshape(-1,1)`,Numpy自动计算出有12行,新的数组shape属性为(16, 1),与原来的(4, 4)配套。

Python5维图_Python5维图

 z.reshape(-1, 2)

newshape等于-1,列数等于2,行数未知,reshape后的shape等于(8, 2)

Python5维图_Python5维图_02

 同理,只给定行数,newshape等于-1,Numpy也可以自动计算出新数组的列数。

2)改变矩阵或者张量的维度,将四维转换成三维

例如:(B1, C1, H1, W1) = A.shape。A为四维矩阵

如果想把A变成三维的,可以使用reshape方法,即:B = A.reshape(B1, C1, -1)

此时,B.shape = (B1, C1, H1*W1),上式中的-1,就是把剩下的H1,W1维度拼接起来,即H1*W1。

注意:在使用reshape方法时一定要沿着原来的矩阵改变维度,例如:

(B1, C1, H1, W1) = A.shape
B = A.reshape(B1, C1, -1) 正确示例
B.shape = (B1, C1, H1*W1)

C = A.reshape(B1, H1*W1, -1)  错误示例 
C.shape = (B1, H1*W1,C1)

A -> B,B1就是A中的B1,C1也是A中的C1维度,然后-1就是把A中剩余的H1,W1变成一个维度,即H1*W1.

A -> C,B1就是A中的B1,H1*W1是从A中的C1维度中取出数据,所以这里的数据是不对的,同样,-1是把H1,W1中的数据变成了C1维度,所以,虽然最后的维度是对的,但是数据是错误的。

如果想对数组的维度进行转换,比如把(B1,C1,H1*W1)变成 (B1,H1*W1, C1)则使用permute()函数

3)将三维转成四维

例如:

new_feats.shape = (4, 65536, 32)
>>>new_feats = new_feats.reshape(4, 256, 256, 32)
>>>new_feats = new-feats.permute(0, 3, 1, 2)
new_feats.shape = (4, 32, 256, 256)

4)tensor.view方法和tensor,reshape方法基本一致

2.对tensoe(张量)转置使用permute()函数

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

注意:

1)Tensor.permute(a,b,c,d, ...):permute函数可以对任意高维矩阵进行转置,但没有 torch.permute() 这个调用方式, 只能 Tensor.permute():

>>> torch.randn(2,3,4,5).permute(3,2,0,1).shape
torch.Size([5, 4, 2, 3])

torch.transpose(Tensor, a,b):transpose只能操作2D矩阵的转置,有两种调用方式;

另:连续使用transpose也可实现permute的效果:

>>> torch.randn(2,3,4,5).transpose(3,0).transpose(2,1).transpose(3,2).shape
torch.Size([5, 4, 2, 3])
>>> torch.randn(2,3,4,5).transpose(1,0).transpose(2,1).transpose(3,1).shape
torch.Size([3, 5, 2, 4])

从以上操作中可知,permute相当于可以同时操作于tensor的若干维度,transpose只能同时作用于tensor的两个维度

3.numpy实现矩阵转置

1)np.transpose,适用于一次同时交换多个轴数据

np.transpose(a, axes=None)

参数 a:输入数组
axis: int类型的列表,这个参数是可选的。默认情况下,反转的输入数组的维度,当给定这个参数时,按照这个参数所定的值进行数组变换。

例如:对于二维数组

>>> two=np.arange(16).reshape(4,4)
>>> two
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
>>> two.transpose()
array([[ 0,  4,  8, 12],
       [ 1,  5,  9, 13],
       [ 2,  6, 10, 14],
       [ 3,  7, 11, 15]])
>>> two.transpose(1,0)
array([[ 0,  4,  8, 12],
       [ 1,  5,  9, 13],
       [ 2,  6, 10, 14],
       [ 3,  7, 11, 15]])

有以上可见,原数组two的数组两个轴为(x,y),对应的下标为(0,1),np.transpose()传入的参数为(1,0),即将原数组的x,y轴互换。综上,对二维数组的transpose操作就是对原数组的转置操作。

对于三维数组:

>>> three=np.arange(18).reshape(2,3,3)
>>> three
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]]])
>>> three.transpose()
array([[[ 0,  9],
        [ 3, 12],
        [ 6, 15]],

       [[ 1, 10],
        [ 4, 13],
        [ 7, 16]],

       [[ 2, 11],
        [ 5, 14],
        [ 8, 17]]])

这是numpy.transpose()函数对three数组默认的操作,即将原数组的各个axis进行reverse一下,three原始axis排列为(0,1,2),那numpy.transpose()默认的参数为(2,1,0)得到转置后的数组的视图,不影响原数组的内容以及大小。axis(0,1,2)———>axis(2,1,0) ,transpose后的数组相对于原数组来说,相当于交换了原数组的0轴和2轴。