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)配套。
z.reshape(-1, 2)
newshape等于-1,列数等于2,行数未知,reshape后的shape等于(8, 2)
同理,只给定行数,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轴。