Python軟件基金會成員(Contibuting Member)Vihar Kurama簡要介紹了深度學習算法背后的數(shù)學。
深度學習(Deep Learning)是機器學習的子領域。而線性代數(shù)(linear algebra)是有關連續(xù)值的數(shù)學。許多計算機科學家在此方面經驗不足(傳統(tǒng)上計算機科學更偏重離散數(shù)學)。想要理解和使用許多機器學習算法,特別是深度學習算法,對線性代數(shù)的良好理解是不可或缺的。
為什么要學數(shù)學?
線性代數(shù)、概率論和微積分是確切地表達機器學習的“語言”。學習這些主題有助于形成對機器學習算法底層機制的深入理解,也有助于開發(fā)新的算法。
如果我們查看的尺度足夠小,那么深度學習背后的一切都是數(shù)學。所以在開始深度學習之前,有必要理解基本的線性代數(shù)。
標量、向量、矩陣、張量;圖片來源:hadrienj.github.io
深度學習背后的核心數(shù)據(jù)結構是標量(Scalar)、向量(Vector)、矩陣(Matrix)、張量(Tensor)。讓我們通過編程,使用這些數(shù)據(jù)結構求解基本的線性代數(shù)問題。
標量
標量是單個數(shù)字,或者說,0階(0th-order)張量。x ∈ ?表示x是一個屬于實數(shù)集?的標量。
在深度學習中,有不同的數(shù)字集合。?表示正整數(shù)集(1,2,3,…)。?表示整數(shù)集,包括正數(shù)、負數(shù)和零。?表示有理數(shù)集(可以表達為兩個整數(shù)之比的數(shù))。
在Python中有幾個內置的標量類型:int、float、complex、bytes、Unicode。Numpy又增加了二十多個新的標量類型。
import numpy as np
np.ScalarType
返回:
(int,
float,
complex,
int,
bool,
bytes,
str,
memoryview,
numpy.bool_,
numpy.int8,
numpy.uint8,
numpy.int16,
numpy.uint16,
numpy.int32,
numpy.uint32,
numpy.int64,
numpy.uint64,
numpy.int64,
numpy.uint64,
numpy.float16,
numpy.float32,
numpy.float64,
numpy.float128,
numpy.complex64,
numpy.complex128,
numpy.complex256,
numpy.object_,
numpy.bytes_,
numpy.str_,
numpy.void,
numpy.datetime64,
numpy.timedelta64)
其中,以下劃線(_)結尾的數(shù)據(jù)類型和對應的Python內置類型基本上是等價的。
在Python中定義標量和一些運算
下面的代碼演示了一些張量的算術運算。
a = 5
b = 7.5
print(type(a))
print(type(b))
print(a + b)
print(a - b)
print(a * b)
print(a / b)
輸出:
12.5
-2.5
37.5
0.6666666666666666
下面的代碼段檢查給定的變量是否是標量:
import numpy as np
def isscalar(num):
if isinstance(num, generic):
returnTrue
else:
returnFalse
print(np.isscalar(3.1))
print(np.isscalar([3.1]))
print(np.isscalar(False))
輸出:
True
False
True
向量
向量是由單個數(shù)字組成的有序數(shù)組,或者說,1階張量。向量是向量空間這一對象的組成部分。向量空間是特定長度(又叫維度)的所有可能的向量的整個集合。三維實數(shù)向量空間(?3)常用于表示現(xiàn)實世界中的三維空間。
為了指明向量的分量(component),向量的第i個標量元素記為x[i]。
在深度學習中,向量通常用來表示特征向量。
在Python中定義向量和一些運算
聲明向量:
x = [1, 2, 3]
y = [4, 5, 6]
print(type(x))
輸出:
+并不表示向量的加法,而是列表的連接:
print(x + y)
輸出:
[1, 2, 3, 4, 5, 6]
需要使用Numpy進行向量加法:
z = np.add(x, y)
print(z)
print(type(z))
輸出:
[579]
向量的叉積(cross product)
兩個向量的叉積向量,大小等于以這兩個向量為鄰邊的平行四邊形面積,方向與這兩個向量所在平面垂直:
圖片來源:維基百科
np.cross(x, y)
返回:
[-36 -3]
向量的點積(dot product)
向量的點積為標量,對于給定長度但方向不同的兩個向量而言,方向差異越大,點積越小。
圖片來源:betterexplained.com
np.dot(x, y)
返回:
32
矩陣
矩陣是由數(shù)字組成的矩形數(shù)組,或者說,2階張量。如果m和n為正整數(shù),即,m, n ∈ ?,那么,一個m x n矩陣包含m * n個數(shù)字,m行n列。
m x n可表示為以下形式:
有時簡寫為:
在Python中定義矩陣和一些運算
在Python中,我們使用numpy庫創(chuàng)建n維數(shù)組,也就是矩陣。我們將列表傳入matrix方法,以定義矩陣。
x = np.matrix([[1,2],[3,4]])
x
返回:
matrix([[1, 2],
[3, 4]])
矩陣第0軸的元素均值:
x.mean(0)
返回:
matrix([[2., 3.]]) # (1+3)/2, (3+4)/2
矩陣第1軸的元素均值:
x.mean(1)
返回:
z = x.mean(1)
z
返回:
matrix([[1.5], # (1+2)/2
[3.5]]) # (3+4)/2
shape屬性返回矩陣的形狀:
z.shape
返回:
(2, 1)
所以,矩陣z有2行1列。
順便提下,向量的shape屬性返回由單個數(shù)字(向量的長度)組成的元組:
np.shape([1, 2, 3])
返回:
(3,)
而標量的shape屬性返回一個空元祖:
np.shape(1)
返回:
()
矩陣加法和乘法
矩陣可以和標量及其他矩陣相加、相乘。這些運算在數(shù)學上都有精確的定義。機器學習和深度學習經常使用這些運算,所以有必要熟悉這些運算。
對矩陣求和:
x = np.matrix([[1, 2], [4, 3]])
x.sum()
返回:
10
矩陣-標量加法
在矩陣的每個元素上加上給定標量:
x = np.matrix([[1, 2], [4, 3]])
x + 1
返回:
matrix([[2, 3],
[5, 4]])
矩陣-標量乘法
類似地,矩陣-標量乘法就是在矩陣的每個元素上乘以給定標量:
x * 3
返回:
matrix([[ 3, 6],
[12, 9]])
矩陣-矩陣加法
形狀相同的矩陣才能相加。兩個矩陣對應位置的元素之和作為新矩陣的元素,而新矩陣的形狀和原本兩個矩陣一樣。
x = np.matrix([[1, 2], [4, 3]])
y = np.matrix([[3, 4], [3, 10]])
x和y的形狀均為(2, 2)。
x + y
返回:
matrix([[ 4, 6],
[ 7, 13]])
矩陣-矩陣乘法
形狀為m x n的矩陣與形狀為n x p的矩陣相乘,得到形狀為m x p的矩陣。
圖片來源:hadrienj.github.io
從編程的角度,矩陣乘法的一個直觀解釋是,一個矩陣是數(shù)據(jù),另一個矩陣是即將應用于數(shù)據(jù)的函數(shù)(操作):
圖片來源:betterexplained.com
x = np.matrix([[1, 2], [3, 4], [5, 6]])
y = np.matrix([[7], [13]]
x * y
返回:
matrix([[ 33],
[ 73],
[113]])
上面的代碼中,矩陣x的形狀為(3, 2),矩陣y的形狀為(2, 1),故所得矩陣的形狀為(3, 1)。如果x的列數(shù)不等于y的行數(shù),則x和y不能相乘,強行相乘會報錯shapes not aligned。
矩陣轉置
矩陣轉置交換原矩陣的行和列(行變?yōu)榱校凶優(yōu)樾校?,即?/p>
x = np.matrix([[1, 2], [3, 4], [5, 6]])
x
返回:
matrix([[1, 2],
[3, 4],
[5, 6]])
使用numpy提供的transpose()方法轉置矩陣:
x.transpose()
返回:
matrix([[1, 3, 5],
[2, 4, 6]])
張量
比標量、向量、矩陣更通用的是張量概念。在物理科學和機器學習中,有時有必要使用超過二階的張量(還記得嗎?標量、向量、矩陣分別可以視為0、1、2階張量。)
圖片來源:refactored.ai
在Python中定義張量和一些運算
張量當然也可以用numpy表示(超過二階的張量不過是超過二維的數(shù)組):
import numpy as np
t = np.array([
[[1,2,3], [4,5,6], [7,8,9]],
[[11,12,13], [14,15,16], [17,18,19]],
[[21,22,23], [24,25,26], [27,28,29]],
])
t.shape
返回:
(3, 3, 3)
張量加法
s = np.array([
[[1,2,3], [4,5,6], [7,8,9]],
[[10, 11, 12], [13, 14, 15], [16, 17, 18]],
[[19, 20, 21], [22, 23, 24], [25, 26, 27]],
])
s + t
返回:
array([[[ 2, 4, 6],
[ 8, 10, 12],
[14, 16, 18]],
[[21, 23, 25],
[27, 29, 31],
[33, 35, 37]],
[[40, 42, 44],
[46, 48, 50],
[52, 54, 56]]])
張量乘法
s * t得到的是阿達馬乘積(Hadamard Product),也就是分素相乘(element-wise multiplication),將張量s和t中的每個元素相乘,所得乘積為結果張量對應位置的元素。
s * t
返回:
array([[[ 1, 4, 9],
[ 16, 25, 36],
[ 49, 64, 81]],
[[110, 132, 156],
[182, 210, 240],
[272, 306, 342]],
[[399, 440, 483],
[528, 575, 624],
[675, 728, 783]]])
張量積(Tensor Product)需要使用numpy的tensordot方法計算。
圖片來源:維基百科
計算s ? t:
s = np.array([[[1, 2], [3, 4]]])
t = np.array([[[5, 6], [7, 8]]])
np.tensordot(s, t, 0)
返回:
array([[[[[[ 5, 6],
[ 7, 8]]],
[[[10, 12],
[14, 16]]]],
[[[[15, 18],
[21, 24]]],
[[[20, 24],
[28, 32]]]]]])
其中,最后一個參數(shù)0表示求張量積。當該參數(shù)為1時,表示求張量的點積(tensor dot product),這一運算可以視為向量點積概念的推廣;當該參數(shù)為2時,表示求張量的縮并(tensor double contraction),這一運算可以視為矩陣乘法概念的推廣。
當然,由于張量常用于深度學習,因此我們也經常直接使用深度學習框架表達張量。比如,在PyTorch中,創(chuàng)建一個形狀為(5, 5)的張量,然后用浮點數(shù)1填充該張量:
torch.ones(5, 5)
返回:
tensor([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
-
線性代數(shù)
+關注
關注
5文章
50瀏覽量
11063 -
深度學習
+關注
關注
73文章
5500瀏覽量
121111
原文標題:深度學習線性代數(shù)簡明教程
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論