0402-Tensor和Numpy的區別
pytorch完整教程目錄:https://www.cnblogs.com/nickchen121/p/14662511.html
由於tensor和ndarray具有很高的相似性,並且兩者相互轉化需要的開銷很小。但是由於ndarray出現時間較早,相比較tensor有更多更簡便的方法,因此在某些時候tensor無法實現某些功能,可以把tensor轉換為ndarray格式進行處理后再轉換為tensor格式。
一、tensor數據和ndarray數據相互轉換
import numpy as np
a = np.ones([2, 3], dtype=np.float32)
a
array([[1., 1., 1.],
[1., 1., 1.]], dtype=float32)
b = t.from_numpy(a) # 把ndarray數據轉換為tensor數據
b
tensor([[1., 1., 1.],
[1., 1., 1.]])
b = t.Tensor(a) # 把ndarray數據轉換為tensor數據
b
tensor([[1., 1., 1.],
[1., 1., 1.]])
a[0, 1] = 100
b
tensor([[ 1., 100., 1.],
[ 1., 1., 1.]])
c = b.numpy() # 把tensor數據轉換為ndarray數據
c
array([[ 1., 100., 1.],
[ 1., 1., 1.]], dtype=float32)
二、廣播法則
廣播法則來源於numpy,它的定義如下:
- 讓所有輸入數組都向其中shape最長的數組看齊,shape中不足部分通過在前面加1補齊
- 兩個數組要么在某一個維度的長度一致,要么其中一個為1,否則不能計算
- 當輸入數組的某個維度的長度為1時,計算時沿此維度復制擴充×一樣的形狀
torch當前支持自動廣播法則,但更推薦使用以下兩個方法進行手動廣播,這樣更直觀,更不容出錯:
- unsqueeze或view:為數據某一維的形狀補1
- expand或expand_as:重復數組,實現當輸入的數組的某個維度的長度為1時,計算時沿此維度復制擴充成一樣的形狀
注:repeat與expand功能相似,但是repeat會把相同數據復制多份,而expand不會占用額外空間,只會在需要的時候才擴充,可以極大地節省內存。
a = t.ones(3, 2)
b = t.zeros(2, 3, 1)
自動廣播法則:
- a是二維,b是三維,所在現在較小的a前面補1(等價於
a.unsqueeze(0)
,a的形狀變成(0,2,3)) - 由於a和b在第一維和第三維的形狀不一樣,利用廣播法則,兩個形狀都變成了(2,3,2)
a + b
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
對上述自動廣播可以通過以下方法實現手動廣播
a.unsqueeze(0).expand(2, 3, 2) + b.expand(
2, 3, 2) # 等價於a.view(1,3,2).expand(2,3,2) + b.expand(2,3,2)
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])