當(dāng)下流行的深度學(xué)習(xí)框架,都會涉及一個基本的概念,就是張量(Tensor)。張量是什么?簡單的理解,就是數(shù)據(jù)的容器。零維張量就是數(shù)字或者標量,一維張量就是向量,二維或者更高維就是矩陣。因為機器只能處理數(shù)字相關(guān)的信息,所以無論是圖片還是自然語言的處理,都需要把輸入信息轉(zhuǎn)化為高維數(shù)字矩陣的形式。
那為何需要新引入張量,而不直接使用numpy的ndarray呢?Tensor提供了一些輔助神經(jīng)網(wǎng)絡(luò)訓(xùn)練的功能,比ndarray更適合深度學(xué)習(xí)。
簡而言之一句話,就像python里的int,float,string等數(shù)據(jù)類型一樣,tensor就是深度學(xué)習(xí)框架的基本數(shù)據(jù)類型,以至于Google的深度學(xué)習(xí)框架名字就叫TensorFlow,就是“張量的流”的意思。
我們初始化一個3行2列的矩陣,直接把數(shù)組直接賦值給torch.Tensor,可以通過Tensor的size函數(shù)查看張量的維度。
>>>import torch
>>> a = torch.Tensor([[1,1],[2,2],[3,3]])
>>> a
tensor([[ 1., 1.],
[ 2., 2.],
[ 3., 3.]])
>>> a.size()
torch.Size([3, 2])
在實際的應(yīng)用場景中,我們難得會直接從數(shù)組中初始化Tensor,更多情況下,會初始化一個全0或全1亦或是隨機初始值的特定維度的張量。
有幾種常用的方法,比如得到3行2列值全為0的張量:
>>> a = torch.zeros((3,2))
>>> a
tensor([[ 0., 0.],
[ 0., 0.],
[ 0., 0.]])
比如得到3行2列的隨機值的張量:
>>> b = torch.randn((3,2))
>>> b
tensor([[-0.0648, -1.2692],
[ 0.9562, 0.0018],
[-1.3293, 0.0097]])
對于張量內(nèi)的數(shù)據(jù)訪問,與numpy是一樣的,直接通過索引訪問和修改。
>>> b
tensor([[-0.0648, -1.2692],
[ 0.9562, 0.0018],
[-1.3293, 0.0097]])
>>>b[0,0]
tensor(1.00000e-02 *
-6.4819)
>>>b[0,1]
tensor(-1.2692)
>>>b[0,1]=888
>>> b
tensor([[-6.4819e-02, 8.8800e+02],
[ 9.5625e-01, 1.8241e-03],
[-1.3293e+00, 9.7056e-03]])
關(guān)于Pytorch的Tensor,還有重要一點,就是可以和numpy的ndarray互轉(zhuǎn)。
>>>np_b = b.numpy()
>>> np_b
array([[-6.4819142e-02, 8.8800000e+02],
[ 9.5624775e-01, 1.8241187e-03],
[-1.3292531e+00, 9.7055538e-03]],dtype=float32)
從numpy的ndarray轉(zhuǎn)為torch的tensor同樣簡單,代碼如下:
>>> a = np.array([[1,1],[2,2]])
>>> a
array([[1, 1],
[2, 2]])
>>>tensor_a = torch.from_numpy(a)
>>> tensor_a
tensor([[ 1, 1],
[ 2, 2]], dtype=torch.int32)
張量加法有兩種形式,一種是直接使用加號,另一種使用torch.add方法:
>>> a = torch.Tensor([1,1])
>>> b = torch.Tensor([2,2])
>>>a+b
tensor([ 3., 3.])
>>>torch.add(a,b)
tensor([ 3., 3.])
這里需要特別說明,深度學(xué)習(xí)里的張量計算,不是線性代數(shù)里的矩陣運算,而且元素直接計算,兩個參與計算的張量順序無關(guān),比如a*b=b*a(線性代數(shù)里的矩陣是不可以的),另外是張量的元素直接加減或乘除,各張量之間行數(shù)與列數(shù)必須相同,有幾個例外:
1, 標量,直接把標題作用于張量的每個元素。
>>> a
tensor([[ 1., 1.],
[ 2., 2.]])
>>> a+1
tensor([[ 2., 2.],
[ 3., 3.]])
2, 一維向量,向量長度需等于張量列數(shù),各元素作用于列元素
>>> a =torch.Tensor([[1,1],[2,2]])
>>> a
tensor([[ 1., 1.],
[ 2., 2.]])
>>>b = torch.Tensor([0.5,1.5]) #b是行向量
>>> a*b
tensor([[ 0.5000, 1.5000],
[ 1.0000, 3.0000]]) #行向量,元素操作在列上
3, 行數(shù)相同,列數(shù)為1,元素使用于各行
>>>c = torch.Tensor([[0.5],[1.5]]) #c是2行1列的張量
>>> a*c
tensor([[ 0.5000, 0.5000],
[ 3.0000, 3.0000]])#列向量,元素操作在各行上
view方法,就是對矩陣進行reshape,這個方法很重要,因為多層神經(jīng)網(wǎng)絡(luò)在相互連接的時候,前后兩個層的維度是需要對齊的,這時需要對tensor的size進行view:
>>> x = torch.randn(4, 4)
>>> y = x.view(-1,8) #負1表示這一個維度通過推斷得到。
>>> z = x.view(16)
(torch.Size([4, 4]), torch.Size([2, 8]),torch.Size([16]))
關(guān)于作者:魏佳斌,互聯(lián)網(wǎng)產(chǎn)品/技術(shù)總監(jiān),北京大學(xué)光華管理學(xué)院(MBA),特許金融分析師(CFA),資深產(chǎn)品經(jīng)理/碼農(nóng)。偏愛python,深度關(guān)注互聯(lián)網(wǎng)趨勢,人工智能,AI金融量化。致力于使用最前沿的認知技術(shù)去理解這個復(fù)雜的世界。
聯(lián)系客服