133
技術社區[雲棲]
機器學習中的線性代數:關於常用操作的新手指南
什麼是線性代數?
在深度學習中,線性代數是一個非常有用的數學工具,提供同時操作多組數值的方法。它提供多種可以放置數據的結構,如向量(vectors)和矩陣(matrices, 即spreadsheets)兩種結構,並定義了一係列的加減乘除規則來操作這些結構。
為什麼有用?
線性代數可以將各種複雜問題轉化為簡單、直觀、高效的計算問題。下麵這個Python例子展現了線性代數的高速與簡潔。
# Multiply two arrays 將兩個數組直接相乘
x = [1,2,3]
y = [2,3,4]
product = []
for i in range(len(x)):
product.append(x[i]*y[i])
# Linear algebra version 線性代數版操作
x = numpy.array([1,2,3])
y = numpy.array([2,3,4])
x * y
通過將數組初始化「numpy.array()」, 線性代數方法較數組相乘快了三倍。
它是怎樣用於深度學習的?
神經網絡(Neural networks)將權值(weights)存放於矩陣(matrices)中。線性代數使得矩陣操作快速而簡單,特別是通過 GPU 進行運算。事實上,GPU 的設計便是受啟發自向量和矩陣的運算。類似於用像素的多維數組(arrays of pixels)來表示圖形圖像,視頻遊戲通過大規模且持續的矩陣計算,帶來了極具吸引力的遊戲體驗。GPU 是並行操作整個矩陣中的各個像素,而不是一個接一個地去處理單個像素。
向量
向量是關於數字或數據項的一維數組的表示。從幾何學上看,向量將潛在變化的大小和方向存儲到一個點。向量 [3, -2] 表示的是左移3個單位下移2個單位。我們將 具有多個維度的向量稱為矩陣。
向量記法
應用中有多種表達向量的方式,下式是閱讀中常見的幾種表示。
幾何學中的向量
向量通常用於代表從一個點出發的移動。它們用一個點存儲了大小(magnitude)和方向(direction)的潛在變化。如向量 [-2,5] 表示左移2個單位並上移5個單位。 參考: https://mathinsight.org/vector_introduction.
v = [-2, 5]
一個向量可以應用於空間中的任何點。向量的方向等於向上5個單位和向左2個單位的斜線的斜率,它的大小等於該斜線的長度。
標量操作
標量操作涉及到一個向量和一個數。你可以通過對向量中的所有項進行加、減、乘操作,實現對一個向量的原地修改(in-place modification) 。
Scalar addition (標量相加)
元素操作Elementwise operations
在向量的元素操作中,如加減除,相應位置的值被組合生成了新的向量。向量 A中的第一個值與向量 B 中的第一個值相加,然後第二個值與第二個值配對,如此循環。這意味著,兩個向量必須要有相同的維度才能進行元素操作。 *
Vector addition (向量相加)
y = np.array([1,2,3])
x = np.array([2,3,4])
y + x = [3, 5, 7]
y - x = [-1, -1, -1]
y / x = [.5, .67, .75]
*細節請參考下麵關於numpy 中的 broadcasting 方法。
向量乘法
向量乘法有兩種:點積(Dot product) 和 Hadamard乘積(Hadamard product)。
點積
兩個向量的點積是一個標量。向量的點積和矩陣的乘法是深度學習中最重要的操作之一。
y = np.array([1,2,3])
x = np.array([2,3,4])
np.dot(y,x) = 20
Hadamard乘積
Hadamard 乘積是元素相乘,它的輸出是一個向量。
y = np.array([1,2,3])
x = np.array([2,3,4])
y * x = [2, 6, 12]
向量場
如果我們對某點 (x,y) 應用了一個加法或乘法的向量函數,向量場表示了該點理論上可以移動多遠。在空間中給定一個點,向量場顯示了圖中各個點的可能的變化力度(power)和方向(direction)。
向量場參考
上圖這個向量場非常有趣,因為它隨起點差異而向不同方向移動。原因是,該向量場背後的向量存儲著如2x 或x² 這樣的元素,而不是 -2 和 5這樣的標量值。對於圖中的每個點,我們將 x 軸的值帶入 2x 或 x² 中,並繪製一個從開始點指向新位置的箭頭。向量場對於機器學習技術的可視化非常有用,如繪製梯度下降(Gradient Descent)的方向。
矩陣
一個矩陣是數字或元素的矩形網格(如Excel表格),有著特別加、減、乘的運算規則。
矩陣維度
我們用m行n列( rows by columns)來描述矩陣的維度.
a = np.array([
[1,2,3],
[4,5,6]
])
a.shape == (2,3)
b = np.array([
[1,2,3]
])
b.shape == (1,3)
矩陣的標量運算 Matrix scalar operations
矩陣的標量運算與向量相同。隻需將標量與矩陣中的每個元素進行加、減、乘、除等操作。
Matrix scalar addition (矩陣的標量相加)
a = np.array(
[[1,2],
[3,4]])
a + 1
[[2,3],
[4,5]]
矩陣的元素操作Matrix elementwise operations
為了實現兩個矩陣的加、減、除操作,他們必須有著相同的維度。 * 我們對兩個矩陣的對應元素值操作,組合生成新的矩陣。
a = np.array([
[1,2],
[3,4]
])
b = np.array([
[1,2],
[3,4]
])
a + b
[[2, 4],
[6, 8]]
a — b
[[0, 0],
[0, 0]]
Numpy 庫的 broadcasting 方法*
這個方法不能不提,因為它在實踐中被廣泛使用。在 numpy中,矩陣的元素操作對矩陣維度的要求,通過一種叫做 broadcasting的機製實現。我們稱兩個矩陣相容(compatible),如果它們相互對應的維度(行對行,列對列)滿足以下條件:
1. 對應的維度均相等, 或
2. 有一個維度的大小是1
a = np.array([
[1],
[2]
])
b = np.array([
[3,4],
[5,6]
])
c = np.array([
[1,2]
])
# Same no. of rows
# Different no. of columns
# but a has one column so this works
# 相同行數,不同列數,但 a 僅有一列,所以可行。
a * b
[[ 3, 4],
[10, 12]]
# Same no. of columns
# Different no. of rows
# but c has one row so this works
# 相同列數,不同行數,但 c 僅有一行,所以可行。
b * c
[[ 3, 8],
[5, 12]]
# Different no. of columns
# Different no. of rows
# but both a and c meet the
# size 1 requirement rule
# 不同列數、不同行數,但 a 和 c 都滿足大小為1的規則。
a + c
[[2, 3],
[3, 4]]
在更高的維度上(3維,4維),情況會變得有點詭異,但現在我們不必擔心。理解2維上的操作是一個好的開始。
矩陣的 Hadamard 乘積 Matrix Hadamard product
矩陣的Hadamard 乘積是一個元素運算,就像向量一樣。對應位置的值相乘產生新的矩陣。
a = np.array(
[[2,3],
[2,3]])
b = np.array(
[[3,4],
[5,6]])
# Uses python's multiply operator
# 使用 python 的乘法運算
a * b
[[ 6, 12],
[10, 18]]
在 numpy 中,隻要矩陣和向量的維度滿足 broadcasting的要求,你便可以對他們使用 Hadamard 乘積運算.
矩陣轉置 Matrix transpose
神經網絡經常需要處理不同大小的輸入矩陣和權值矩陣,它們的維度常常不滿足矩陣相乘的規則。矩陣轉置提供了一種方法來“旋轉”其中的一個矩陣,使其滿足乘法操作的要求。轉置一個矩陣分兩個步驟:
1. 將矩陣順時針旋轉 90°
2. 反轉每行元素的順序(例如,[a b c] 變成 [c b a])。
以將矩陣 M 轉置成 T為例:
a = np.array([
[1, 2],
[3, 4]])
a.T
[[1, 3],
[2, 4]]
矩陣的乘法 Matrix multiplication
矩陣的乘法定義了一係列關於矩陣相乘生成新矩陣的規則。
規則
不是所有的矩陣都可以進行乘法運算。並且,對於輸出的結果矩陣也有維度要求。 參考.
1. 第一個矩陣的列數 必須等於第二個矩陣的行數
2.一個 M x N 矩陣和 N x K 矩陣的乘積結果是一個 M x K 矩陣. 新的矩陣取 第一個矩陣的行M 和 第二個矩陣的列K 。
步驟
矩陣的乘法依賴於點積與各個行列元素的組合。 以下圖為例(取自 Khan學院的線性代數課程),矩陣 C中的每個元素都是矩陣 A 中的行與矩陣B中的列的點積。
參考
操作 a1 · b1 意味著我們對矩陣A的第一行(1, 7) 和矩陣B 的第一列 (3, 5) 做點積運算.
也可以換一種角度來看:
為什麼矩陣乘法以這種方式工作?
矩陣的乘法很有用,但它的背後並沒有什麼特別的數學的定律。數學家們把它發明出來是因為它的規範簡化了之前乏味的運算。這是一個人為的設計,但卻非常有效。
用這些例子自我測試下
使用 numpy 做矩陣乘法
Numpy 使用函數 np.dot(A,B) 做向量和矩陣的乘法運算。它有一些其他有趣的特性和問題,所以我建議你在使用之前先閱讀該說明文檔 (https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html)。
a = np.array([
[1, 2]
])
a.shape == (1,2)
b = np.array([
[3, 4],
[5, 6]
])
b.shape == (2,2)
# Multiply
mm = np.dot(a,b)
mm == [13, 16]
mm.shape == (1,2)
原文發布時間為:2017-04-20
本文來自雲棲社區合作夥伴“大數據文摘”,了解相關信息可以關注“BigDataDigest”微信公眾號
最後更新:2017-05-17 13:33:03