1. 程式人生 > 實用技巧 >tensor的維度變換

tensor的維度變換

目錄

tensor的維度變換

view以及reshape的用法

例子:

a = torch.rand(4,1,28,28)
a.view(4,28*28)

解讀:其實就是將圖片的通道數、圖片的畫素行列值都合併在一起,成為【4,784】,適合全連線層的輸入。

例子2:

a = torch.rand(4,1,28,28)
a.view(4*1,28,28)

表示我們現在只關注feature map這個屬性,而不關注它來自哪個圖片的哪個通道

注意在view之後如果想恢復到原來的維數是要進行記錄的,否則直接恢復是不行的。

squeeze與unsqueeze用法

unsqueeze

在相應的index的維度新增一維

例子:

a = torch.rand(4,1,28,28)
a.unsqueeze(0)
a.shape
#[1,4,1,28,28]

unsqueeze的引數是index,而index的範圍是[-a.dim()-1,a.dim()+1)

-5 -4  -3   -2   -1
[   4 , 1 , 28 , 28 ]
    0   1    2    3    4

如果是0 1 2 3 4的話就是在0 1 2 3 4的前面插入一維,而如果是-5 - 4- 3- 2 -1的話就是在-5 - 4- 3- 2 -1的後面插入一維

⭐例子二:

a = a.torch.tensor([1.2,2.3])#這裡的資料的維度為【2】
a.unsqueeze(-1)#在最後一個後面新增一維:【2,1】
#[ [1.2] , [2.3]   ]    於是就是先是兩維,然後是一維

a.unsqueeze(0)#在第一維前面新增一維“【1,2】
#[ [1.2 , 2.3] ]         於是就是先是一維,裡面是兩維

⭐例項:

f表示4張14*14的擁有32個通道的圖片,而b表示給圖片的每個channel上的所有的畫素新增一個偏置,我們的目標就是把b疊加在f上面,所以要將b的維度變換與f相同才可以進行,然後再進行b的擴張。

b = torch.rand(32)
f = torch.rand(4,32,14,14)
b = b.unsqueeze(1).unsqueeze(2).unsqueeze(0)
#[32]      [32,1]      [32,1,1]       [1,32,1,1]    

squeeze

刪減維度,如果沒有引數的話會把所有能進行刪減的都刪減了。

例子:

b = torch.randn(1,32,1,1)
b = b.squeeze()#所有維數是1的全部刪掉
#[32]

squeeze的索引是指哪個就刪哪個,除非該維度的維數不是1就不能刪

expand與repeat用法

進行維度的擴充套件,就像前面的b【1,32,14,14】,要想與f【4,32,14,14】進行相加的話,b就要進行維度的擴充套件。

兩種方法的區別:

兩種方法在效果方面是等效的,但是expand只在需要的時候進行資料的複製,而repeat會直接複製資料。所以推薦使用expand

expand

例子:

b = torch.randn(1,32,1,1)
b.expand(4,32,14,14)
#[4,32,14,14]

侷限性:

1.要求expand之前之後的dimension必須一樣。

2.只能在之前維數為1的地方進行expand,而如果之前的維數為3是沒有辦法擴張到m的。

【3,32,14,14】——b.expand(4,32,14,14)報錯

例子2:不像進行變動的地方使用-1代替就可以

b = torch.randn(1,32,1,1)
b.expand(4,32,-1,-1)
#[4,32,1,1]

repeat

repeat的引數表示你要在該維數位置進行多少次複製

例子:

b = torch.randn(1,32,1,1)
b.repeat(4,32,1,1)
#[ 4 , 1024 , 1 , 1 ]

表示1複製4次變為4,32複製32次變為1024,其它沒變

.t()轉置

進行tensor的轉置,但是要注意:只能進行2D tensor的轉置,即矩陣的轉置。

transpose轉置

進行某幾維之間的相互交換

例子:

b = torch.randn(4,3,32,32)
b = b.transpose(1,3)
#[4,32,32,3]
# 0  1  2  3	

例子2:這樣變換前後的二者是一樣的(contiguous()表示進行transpose之後資料不再是按順序存放的,使用該方法進行順序的調整)

a2 = b.transpose(1,3).contiguous().view(4,3*32*32).view(4,3,32,32).transpose(1,3)

注意:[B C H W] → [B W H C] → [B W * H * C] →[B C W H]這樣的變換是不行的 W與H的順序變換了,影象也會處出現變換

⭐例子3:

a = torch.rand(4,3,28,28)#[B C H W]
a.transpose(1,3)#[B W H C]
a.transpose(1,2)#[B H W C]

由於[B H W C]是numpy中儲存圖片的方式,所以這樣變換以後才能匯出numpy

permute函式

transpose中的例子3使用permute函式進行簡單的一步變換:

a = torch.rand(4,3,28,28)#[B C H W]
a.permute(0,2,3,1)#[B H W C]