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軸。