天天看點

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

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

什麼是線性代數?

在深度學習中,線性代數是一個非常有用的數學工具,提供同時操作多組數值的方法。它提供多種可以放置資料的結構,如向量(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個機關。 參考: http://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)。

點積

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

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

np.dot(y,x) = 20

hadamard乘積

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

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

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

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

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

 [1,2],

 [3,4]

a + b

[[2, 4],

 [6, 8]]

a — b

[[0, 0],

 [0, 0]]

numpy 庫的 broadcasting 方法*

這個方法不能不提,因為它在實踐中被廣泛使用。在 numpy中,矩陣的元素操作對矩陣次元的要求,通過一種叫做 broadcasting的機制實作。我們稱兩個矩陣相容(compatible),如果它們互相對應的次元(行對行,列對列)滿足以下條件: 

1.     對應的次元均相等, 或

2.    有一個次元的大小是1

 [1],

 [2]

 [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]]

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

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

[[2,3],

 [2,3]])

b = np.array(

[[3,4],

 [5,6]])

# uses python's multiply operator

# 使用 python 的乘法運算

[[ 6, 12],

 [10, 18]]

在 numpy 中,隻要矩陣和向量的次元滿足 broadcasting的要求,你便可以對他們使用 hadamard 乘積運算.

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

矩陣轉置 matrix transpose

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

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

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

以将矩陣 m 轉置成 t為例:

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

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

 [1, 2]

 ])

a.shape == (1,2)

 [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”微信公衆号