Python中矩陣和張量的維度變化和轉置


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM