邁向深度學習的第一步!零基礎深度學習:感知機

歡迎訪問景略集智的官方網站(jizhi.im)。

快來參加2017無人駕駛智能車Hackathon 挑戰賽吧!

本篇是零基礎深度學習的第二部分:感知機。回顧前一章請點擊:零基礎深度學習Part I:計算圖

學習本章不需要任何機器學習或者神經網路的基礎。跟上教程,它將帶領你入門深度神經網路的數學和演算法基礎。然後我們將效仿 TensorFlow API,自己動手用 Python 實現一個神經網路庫。如果學習過程中遇到困難,請寫在原帖評論里或通過結尾聯繫方式聯繫我們。

本篇教程全部配有代碼演練,點擊運行代碼,可以在集智主站看到代碼運行結果。


原文:Deep Learning From Scratch II: Perceptrons - deep ideas

翻譯: @孫一萌

教程編輯: @孫一萌

感知機(Perceptrons)

令人激動的例子

感知機是神經網路的一種小型形態,是構成更複雜的結構的基本塊。

在詳細介紹之前,我們先看看這個令人激動的例子。假設我們有一個數據集,包含平面上的一百個點,其中有一半的點是紅色的,另一半是藍色。

點擊運行代碼,觀察點的分布。

# 創建一些集中於 (-2, -2) 的紅點nred_points = np.random.randn(50, 2) - 2*np.ones((50, 2))nn# 創建一些集中於 (2, 2) 的藍點nblue_points = np.random.randn(50, 2) + 2*np.ones((50, 2))nn# 把紅點和藍點都在圖上畫出來nplt.scatter(red_points[:,0], red_points[:,1], color=red)nplt.scatter(blue_points[:,0], blue_points[:,1], color=blue)n

如圖,紅點集中在 (?2,?2)(?2,?2),而藍點集中在 (2,2)(2,2)。看了數據,你認為有沒有一種方法,可以判斷某個點是紅的還是藍的?

如果問你 (3,2)(3,2) 是什麼顏色,你馬上就會回答藍色,即便這個點不在上面的數據裡頭,我們依然可以依據它所位於的區域(藍色),判斷出它的顏色。

但有沒有更加通用的方法,能得出藍色的可能性更大的結論?顯然,我們可以在上面圖上畫一條線 y=?x,把空間完美地分為紅色和藍色兩個區域。

點擊運行代碼

# 畫一條線 y = -xnx_axis = np.linspace(-4, 4, 100)ny_axis = -x_axisnplt.plot(x_axis, y_axis)n

我們可以用一個 權向量 w 和一個 偏置 b 來隱式地代表這條線,線上的點 x 符合 w^Tx+b=0

代入上例中的數據,得到 w=(1,1)^T , b=0 。因此 w^Tx+b 等於  (1,1)^T?x =0。

因此這條線可以表示為:

(1,1)^T?x=0

好了,現在要判斷是紅色還是藍色,只要判斷它在線的上方還是下方即可:把點 x 代入 w^Tx+b ,根據結果的符號,如果正的,x 就在線的上方,負的就在下方。

比如上面說的點 (3,2):

begin{pmatrix} 1 & 1 end{pmatrix}cdot begin{pmatrix} 3  2 end{pmatrix}=5

5>0,所以點在線上方,因此是藍色。

感知機的定義

往往而言,一個分類器classifier)函數: hat{c}:R^d?> { 1,2,…,C},可以將一個點映射到一個類別(類別總共 C 個)。

而一個二元分類器就是總共有兩個類別( C=2)的分類器

我們判斷紅點藍點時所用的感知機,就是一個二元分類器,其中  w∈R^d偏置 b∈R^d

這個 hat{c}(x) ,將 R^d 分為了兩個空間,各對應一個類別。

紅藍點的例子是二維(維度 d=2 )的,在二維情況下,空間是沿著一條線被劃分的。推廣到 d維的情況下,平面的劃分總是沿著一個 d?1 維的超平面。

從劃分類別到計算概率

在實際應用中,我們不光想知道點最可能是哪個類別的,我們也好奇這個點屬於某個類別的概率是多少。

之前判斷紅藍色,我們把點 x 的數據代入,如果得到的  w^Tx+b 值越大,那點距離分割線的距離肯定就越遠,我們也更自信它是藍色的。

但是當我們得到一個  w^Tx+b 的值的時候,我們沒辦法說它到底算不算大。那麼為了把這個值轉化為一種概率,我們可以把值壓縮,讓它們分布在 0 和 1 之間。

這可以用 sigmoid 函數 σ 實現:

p(hat{c}(x)=1|x)=σ(w^Tx+b)

其中 σ(a)=frac{1}{1+e^{?a}}

sigmoid 的計算圖

我們來看看 sigmoid 函數的實現:

點擊運行代碼

# 創建從 -5 到 5 的間隔,步長 0.01na = np.arange(-5, 5, 0.01)nn# 計算對應的 sigmoid 函數的值ns = 1 / (1 + np.exp(-a))nn# 畫出結果nplt.plot(a, s)nplt.grid(True)nplt.show()n

如圖,當 w^Tx+b=0 ,即點位於分割線上時,sigmoid 函數得到這個值對應的概率為 0.5。當漸近線越接近 1, w^Tx+b=0 的值就越大;漸近線越接近 0, w^Tx+b=0 值就越小。

符合我們的期待。

現在來定義一個 sigmoid 函數的 Operation,這個 Operation 我們後面會用到:

點擊運行代碼

class sigmoid(Operation):n """返回元素 x 的 sigmoid 結果。n """nn def __init__(self, a):n """構造 sigmoidnn 參數列表:n a: 輸入節點n """n super().__init__([a])nn def compute(self, a_value):n """計算本 sigmoid operation 的輸出nn 參數列表:n a_value: 輸入值n """n return 1 / (1 + np.exp(-a_value))n

1. 舉個例子

現在我們可以用 Python 做一個感知機,解決之前的紅/藍問題。再用這個感知機算一下 (3,2)^T 是藍點的概率

點擊運行代碼

# 創建一個新 graphnGraph().as_default()nnx = placeholder()nw = Variable([1, 1])nb = Variable(0)np = sigmoid( add(matmul(w, x), b) )nnsession = Session()nprint(session.run(p, {n x: [3, 2]n}))n

多分類感知機

目前為止,我們只用感知機做過個二元分類器,用來推算一個點,屬於某一類別(共兩個類別)的概率 p,那麼自然,屬於另一類別的概率就是 1-p 了。

但是往往實際情況下,類別的數量都會超過兩個。比方說,在給圖片做分類的時候,要輸出的類別可能有很多種(比如狗、椅子、人、房子等等)。

因此我們要把感知機拓展一下,讓它能支持輸出多種類別下的可能性。

我們依然取常量 C 作為類別的數量。但不再用之前二元時的權向量 w,而是引入權矩陣 W∈R^{d×C}

權矩陣的每一列包含一個單獨的線性分類器中的權,每一個類別對應一個 分類器

二元的時候,我們要計算 w^Tx點積,而現在我們要計算 xW 。計算 xW 返回的是一個位於 R^C 的向量,它的各項可以看作權矩陣不同列的點積的結果。

然後,我們再將向量 xW 加上 偏置向量 b∈R^C 。向量 b 的一項對應一種類別。

這樣就生成了一個位於 R^C 的向量,這個向量每一項分別代表點屬於某一種類別(共 C 個類別)的可能性。

過程看上去可能很複雜,但其實這個矩陣乘法,只不過並行地為 C 個類別中的每一個,分別執行了它們各自對應的線性分類器而已,它們每一個都有自己的分割線,而這分割線依然可以像之前的紅藍問題一樣,由給定的權向量和 偏置 隱式表示,只不過在這裡,權向量權矩陣的各列提供,而 偏置 則是 b 向量的各項。

多類型感知機的計算圖

1. Softmax

原本的感知機生成單個標量,通過 sigmoid,我們把這個標量壓縮,得到分布於 0 到 1 之間的一個概率。

推廣到多類別感知機,它會生成一個向量 a∈R^m 。同樣地,向量 a 的第 i 項值越大,我們就更有自信認為輸入的點屬於第 i 個類別。

因此,我們也希望將向量 a 轉化為概率向量,向量的各項分別代表輸入值屬於各個類別的概率,向量的每一項都分布在 0 和 1 之間,且全部項相加總和為 1。

要實現這一點,通常做法是使用 softmax 函數。Softmax 函數其實是 sigmoid 在多類別輸出情況下的一種推廣:

σ(a)_i=frac{e^ai}{∑^C_{j=1^{e^aj}}}

點擊運行代碼

class softmax(Operation):n """返回 a 的 softmax 函數結果.n """nn def __init__(self, a):n """構造 softmaxnn 參數列表:n a: 輸入節點n """n super().__init__([a])nn def compute(self, a_value):n """計算 softmax operation 的輸出值nn 參數列表:n a_value: 輸入值n """n return np.exp(a_value) / np.sum(np.exp(a_value), axis=1)[:, None]n

2. 批量計算

我們可以通過矩陣的形式,一次傳入多個值。也就是說,之前我們一次只能傳入一個點,現在我們可以每次傳入一個矩陣 X∈R^{N×d} ,矩陣的每一行都包含一個點(共 N 行,包含 N 個 d維點)。

我們把這種矩陣稱為批量。

這樣的話,我們計算的就是 XW 而非 xW。計算 XW 會返回一個 N×C 的矩陣,矩陣的每一行包含各個點的 xW。

我們再把每一行都加上一個 偏置向量 b(此時 b 是一個 1×m 的行向量)。

因此這一整個過程就是計算了一個函數 f:R^{N×d}?>R^m ,其中 f(X)=σ(XW+b) 。此處 計算圖 如下:

批量計算圖

3. 示例

我們來推廣之前的紅/藍例子,讓它能夠支持批量計算和多類別輸出。

點擊運行代碼

# 創建一個新 graphnGraph().as_default()nnX = placeholder()nn# 為兩種輸出類別創建一個權矩陣:n# 藍色的權向量是 (1, 1) ,紅色是 (-1, -1) nW = Variable([n [1, -1],n [1, -1]n])nb = Variable([0, 0])np = softmax( add(matmul(X, W), b) )nn# 創建一個 Session,針對我們的藍色/紅色點運行 perceptronnsession = Session()noutput_probabilities = session.run(p, {n X: np.concatenate((blue_points, red_points))n})nn# 列印前 10 行, 也就是前 10 個點的概率nprint(output_probabilities[:10])n

由於數據集中的前 10 個點都是藍色的,感知機輸出的藍色的可能性(左邊一列)要比紅色的高。

本章的課程到這裡就結束啦!如果有什麼學習上的問題歡迎你前往集智社區發帖諮詢,我們會安排專人解答。


學習了這麼久的人工智慧技術你是否想要實戰或與更多行業大佬進行交流呢?

快來參加景略集智攜手KITTCAMP無人駕駛社區、太庫舉辦的2017無人駕駛智能車Hackathon挑戰賽吧!

詳情請點擊:2017無人駕駛智能車Hackathon 我們提供完備的設施和豐厚獎品,歡迎報名!

快加入學習人工智慧的行列里來吧!

有哪些「本來以為已經是巔峰,沒想到才是開始」的例子?

從乾貨到練習題,你想要的人工智慧知識資源,都在這裡(十一月)

人工智慧可以作曲嗎?

官方微博:@景略集智

微信公眾號:jizhi-im

商務合作: @軍師

投稿轉載:kexiyang@jizhi.im

集智QQ群:557373801


推薦閱讀:

各單位注意,集智主站計劃明晨進行維護。
從入門到進階,人工智慧資源匯總(十二月)
快速上手:用你自己的數據集快速打造一個圖像識別器
比現在的智能會議不知道高到哪裡去了!
用20行Python代碼生成雞湯,打造AI咪蒙指日可待。

TAG:深度学习DeepLearning | 人工智能 | 景略集智 |