閱讀133 返回首頁    go 阿裏雲 go 技術社區[雲棲]


機器學習中的線性代數:關於常用操作的新手指南


0?wx_fmt=png


什麼是線性代數?


在深度學習中,線性代數是一個非常有用的數學工具,提供同時操作多組數值的方法。它提供多種可以放置數據的結構,如向量(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個單位。我們將 具有多個維度的向量稱為矩陣。


向量記法

應用中有多種表達向量的方式,下式是閱讀中常見的幾種表示。

0?wx_fmt=png


幾何學中的向量

向量通常用於代表從一個點出發的移動。它們用一個點存儲了大小(magnitude)和方向(direction)的潛在變化。如向量 [-2,5] 表示左移2個單位並上移5個單位。 參考: https://mathinsight.org/vector_introduction.

0?wx_fmt=png

v = [-2, 5]

一個向量可以應用於空間中的任何點。向量的方向等於向上5個單位和向左2個單位的斜線的斜率,它的大小等於該斜線的長度。


標量操作

標量操作涉及到一個向量和一個數。你可以通過對向量中的所有項進行加、減、乘操作,實現對一個向量的原地修改(in-place modification) 。

0?wx_fmt=png

Scalar addition (標量相加)


元素操作Elementwise operations

在向量的元素操作中,如加減除,相應位置的值被組合生成了新的向量。向量 A中的第一個值與向量 B 中的第一個值相加,然後第二個值與第二個值配對,如此循環。這意味著,兩個向量必須要有相同的維度才能進行元素操作。 *

0?wx_fmt=png

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)。


點積

兩個向量的點積是一個標量。向量的點積和矩陣的乘法是深度學習中最重要的操作之一。

0?wx_fmt=png

y = np.array([1,2,3])
x = np.array([2,3,4])
np.dot(y,x) = 20


Hadamard乘積

Hadamard 乘積是元素相乘,它的輸出是一個向量。

0?wx_fmt=png

y = np.array([1,2,3])
x = np.array([2,3,4])
y * x = [2, 6, 12]


向量場

如果我們對某點 (x,y) 應用了一個加法或乘法的向量函數,向量場表示了該點理論上可以移動多遠。在空間中給定一個點,向量場顯示了圖中各個點的可能的變化力度(power)和方向(direction)。

0?wx_fmt=png


向量場參考

上圖這個向量場非常有趣,因為它隨起點差異而向不同方向移動。原因是,該向量場背後的向量存儲著如2x 或x² 這樣的元素,而不是 -2 和 5這樣的標量值。對於圖中的每個點,我們將 x 軸的值帶入 2x 或 x² 中,並繪製一個從開始點指向新位置的箭頭。向量場對於機器學習技術的可視化非常有用,如繪製梯度下降(Gradient Descent)的方向。

矩陣

一個矩陣是數字或元素的矩形網格(如Excel表格),有著特別加、減、乘的運算規則。


矩陣維度

我們用m行n列( rows by columns)來描述矩陣的維度.

0?wx_fmt=png

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

矩陣的標量運算與向量相同。隻需將標量與矩陣中的每個元素進行加、減、乘、除等操作。

0?wx_fmt=png


Matrix scalar addition (矩陣的標量相加)

a = np.array(
[[1,2], 
 [3,4]])
a + 1
[[2,3], 
 [4,5]]

矩陣的元素操作Matrix elementwise operations

為了實現兩個矩陣的加、減、除操作,他們必須有著相同的維度。 * 我們對兩個矩陣的對應元素值操作,組合生成新的矩陣。

0?wx_fmt=png

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 乘積是一個元素運算,就像向量一樣。對應位置的值相乘產生新的矩陣。

0?wx_fmt=png

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 乘積運算.

0?wx_fmt=png



矩陣轉置 Matrix transpose

神經網絡經常需要處理不同大小的輸入矩陣和權值矩陣,它們的維度常常不滿足矩陣相乘的規則。矩陣轉置提供了一種方法來“旋轉”其中的一個矩陣,使其滿足乘法操作的要求。轉置一個矩陣分兩個步驟:

1. 將矩陣順時針旋轉 90°

2. 反轉每行元素的順序(例如,[a b c] 變成 [c b a])。

以將矩陣 M 轉置成 T為例:

0?wx_fmt=png

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中的列的點積。

0?wx_fmt=png

參考

操作 a1 · b1 意味著我們對矩陣A的第一行(1, 7)  和矩陣B 的第一列 (3, 5) 做點積運算.

0?wx_fmt=png

也可以換一種角度來看:

0?wx_fmt=png


為什麼矩陣乘法以這種方式工作?

矩陣的乘法很有用,但它的背後並沒有什麼特別的數學的定律。數學家們把它發明出來是因為它的規範簡化了之前乏味的運算。這是一個人為的設計,但卻非常有效。

用這些例子自我測試下


0?wx_fmt=png


使用 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

  上一篇:go  用100美元攢一個懂人臉識別又能對話的門鈴
  下一篇:go  看我如何躺在床上黑掉自家智能電視