次元擴張舉例
在張量的運算中,有時候兩個張量的次元并不一緻。
比如張量A和标量B的求和運算A+B可能會有Broadcasting存在。
A的張量的次元是[2,3,2,2],代表的意義是經過卷積運算後的一個Feature maps,2張圖檔3個通道,2行3列特征向量:
A = torch.randn(2,3,2,2)
print(A.shape)
運作結果:
torch.Size([2, 3, 2, 2])
tensor([[[[ 1., 2.],
[ 3., 4.]],
[[ 5., 6.],
[ 7., 8.]],
[[ 9., 10.],
[11., 12.]]],
[[[13., 14.],
[15., 16.]],
[[17., 18.],
[19., 20.]],
[[21., 22.],
[23., 24.]]]])
而B可能是一個标量,代表的意義可能是偏置Bias。
B = 3
print(B)
運作結果:3
由于A和B的次元并不一緻,Pytorch通過Broadcasting(廣播),能夠自動實作标量B的次元的擴充,使其擴充到[2,3,2,2]這個次元,進而實作A和B的加法運算。
C = A+B
print(C.shape)
print(C)
運作結果:
3
torch.Size([2, 3, 2, 2])
tensor([[[[ 4., 5.],
[ 6., 7.]],
[[ 8., 9.],
[10., 11.]],
[[12., 13.],
[14., 15.]]],
[[[16., 17.],
[18., 19.]],
[[20., 21.],
[22., 23.]],
[[24., 25.],
[26., 27.]]]])
從運作結果看,A的每個特征值都加上了偏置3.
次元擴張的關鍵點
- Broadcasting(廣播)也就是自動實作了若幹
和unsqueeze
操作,以使兩個Tensor的shape一緻,進而完成某些操作(往往是加法)expand
- Broadcasting能夠實作自動次元擴充,有點像
的功能,但是是自動完成的,而且不需要像expand
那樣對資料進行拷貝,可以節省記憶體。repeat
使用Broadcasting情況
1、不需要增加次元,隻需要對應擴張
這種情況對應的是A和B的次元一緻,但是B某些次元的size隻是1例如:
A.shape : [4,32,14,14]
B.shape : [1,32,1,1]
對于B的Broadcasting過程是直接expand到 [4,32,14,14]
2、需要增加次元,還需要擴充
- 從最後面的次元開始比對。
- 在前面插入若幹次元。
- 将次元的size從1通過expand變到和某個Tensor相同的次元。
A.shape : [4,32,14,14]
B.shape : [14,14]
對于B的Broadcasting過程是先
unsqueeze
插入新的次元變成 [1,1,14,14],再expand新的次元成[4,32,14,14]
例如[batch,channel,height,width]=[2,3,2,2]:如果加上一個[2,2] 的Tensor,意思就是不管是2張圖檔中的哪一張,也不管是什麼通道,都加上一個2*2的Feature Map;如果加上一個[3,1,1],意思就是對3個通道分别加上一個值;如果加上一個[1,1,1,1],這和加上一個[1]一樣,也就是對每個元素都加上一個相同的Bais值。
3、不能使用Broadcasting的情況
A.shape : [4,32,14,14]
B.shape : [2,32,14,14]
B的0次元的size已經不是0或者1了,是以不能通過unsqueeze插入或者擴充次元。