機器學習系列 02:感知機

  本內容將介紹機器學習中的 感知機模型,並說明感知機學習算法的原始形式和對偶形式。

  感知機(perceptron)是二分類線性分類模型,屬於判別模型,是一種監督學習算法
  其輸入爲實例的特徵向量,輸出爲實例的類別,取 +1 和 -1 二值。感知機對應於輸入空間(特徵空間)中將實例劃分爲正負兩類的分離超平面,屬於判別模型。感知機學習旨在求出將訓練數據進行線性劃分的分離超平面,爲此,導入基於誤分類的損失函數,利用梯度下降法對損失函數進行極小化,求得感知機模型。感知機學習算法具有簡單而易於實現的優點,分爲原始形式對偶形式。感知機預測是用學習得到的感知機模型對新的輸入實例進行分類。感知機 1957 年由 Rosenblatt 提出,是神經網絡支持向量機的基礎。

一、感知機模型

  假設輸入空間(特徵空間)是 XRn\mathcal{X} \subseteq \mathbf{R}^n,輸出空間是 Y={+1,1}\mathcal{Y}=\{+1,-1\}。輸入 xXx\in\mathcal{X} 表示實例的特徵向量,對應於輸入空間(特徵空間)的點;輸出 yYy\in\mathcal{Y} 表示實例的類別。由輸入空間到輸出空間的如下函數:

f(x)=sign(wx+b)1.1f(x)=sign(w\cdot x+b) (1.1)

稱爲感知機。其中,wwbb 爲感知機模型參數,wRnw\in \mathbf{R}^n 叫作權值(weight)或權值向量(weight vector),bRb\in \mathbf{R} 叫作偏置(bias),wxw\cdot x 表示 wwxx 的點積。sign 是符號函數,即

sign(x)={+1,x01,x<01.2sign(x)=\left \{\begin{array}{cc}+1, &x\geq0\\ -1,& x<0 \end{array}\right. (1.2)

  感知機模型的假設空間是定義在特徵空間中的所有線性分類模型(linear classification model)或線性分類器(linear classifier),即函數 {ff(x)=wx+b}\{f|f(x)=w\cdot x+b\}

二、感知機學習策略

  假設訓練數據集是線性可分的,感知機學習的目標是求得一個能夠將訓練集中正實例點和負實例點完全正確分開的分離超平面。爲了找出這樣的超平面,即確定感知機模型參數 wwbb,需要確定一個學習策略,即定義(經驗)損失函數並將損失函數極小化。
  感知機將誤分類點到超平面 SS 的總距離作爲損失函數。輸入空間 Rn\mathbf{R}^n 中任一點 x0x_0 到超平面 SS 的距離:

1wwx0+b\frac{1}{||w||}|w\cdot x_0+b|

其中,w||w||wwL2L_2 範數。
  另外,誤分類的數據 (xi,yi)(x_i,y_i) 滿足

yi(w+b)>0-y_i(w\cdot+b)>0

  因此,誤分類點 xix_i 到超平面 SS 的距離是

1wyi(wxi+b)-\frac{1}{||w||}y_i(w\cdot x_i+b)

  假設超平面 SS 的誤分類點集合爲 MM,那麼所有誤分類點到超平面 SS 的總距離爲

1wxiMyi(wxi+b)-\frac{1}{||w||}\sum_{x_i\in M}y_i(w\cdot x_i+b)

如果假設 w=1||w|| = 1,就得到感知機學習的損失函數

L(w,b)=xiMyi(wxi+b)1.3L(w,b)=-\sum_{x_i\in M}y_i(w\cdot x_i+b)(1.3)

其中 MM 爲誤分類點的集合。這個損失函數就是感知機學習的經驗風險函數。
  對一個特定的樣本點的損失函數:在誤分類時是參數 wwbb 的線性函數,並且大於0,在正確分類時是 0。因此,給定訓練數據集 TT,損失函數 L(w,b)L(w,b)wwbb 的連續可導函數,並且是非負的。
  感知機學習的策略是在假設空間中選取使損失函數式(1.3)最小的模型參數 wwbb ,即感知機模型。

三、感知機學習算法

  感知機學習問題轉化爲求解損失函數式(1.3)的最優化問題,最優化的方式是隨機梯度下降法。感知機學習算法分爲原始形式和對偶形式。

3.1 感知機學習算法的原始形式

  感知機學習算法是對以下最優化問題的算法。給定一個訓練集

T={(x1,y1),(x2,y2), ,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\}

其中 xiX=Rnx_i\in \mathcal{X}=\mathbf{R}_nyiY={1,+1}y_i\in \mathcal{Y}=\{-1,+1\}i=1,2, ,Ni=1,2,\cdots,N,求參數 wwbb,使其爲以下損失函數極小化問題的解

minw,bL(w,b)=xiMyi(wxi+b)1.4\min_{w,b}L(w,b)=-\sum_{x_i\in M}y_i(w\cdot x_i+b)(1.4)

其中 MM 爲誤分類點的集合。
  感知機學習算法是誤分類驅動的,具體採用隨機梯度下降法(stochastic gradient descent)。首先,任意選取一個超平面 w0w_0b0b_0,然後用梯度下降法不斷地極小化目標函數(1.4)。極小化過程中不是一次使 MM 中所有誤分類點的梯度下降,而是一次隨機選取一個誤分類點使其梯度下降。
  假設誤分類點集合 MM 是固定的,那麼損失函數 L(w,b)L(w,b) 的梯度由

wL(w,b)=xiMyixi\nabla_{w}L(w,b)=-\sum_{x_i\in M}y_ix_i

bL(w,b)=xiMyi\nabla_{b}L(w,b)=-\sum_{x_i\in M}y_i

給出。
  隨機選取一個誤分類點 (wi,yi)(w_i,y_i),對 wwbb 進行更新:

ww+ηyixiw\leftarrow w+\eta y_ix_i

bb+ηyib\leftarrow b+\eta y_i

式中 η(0<η1)\eta(0<\eta\leq1) 是步長,在統計學習中又稱爲學習率(learning rate)。這樣,通過迭代可以期待損失函數 L(w,b)L(w,b) 不斷減小,直到爲 0。綜上所述,得到如下算法:

  算法 1.1 (感知機學習算法的原始形式)

輸入:訓練數據集 T=(x1,y1),(x2,y2), ,(xN,yN)T={(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)},其中 xiX=Rnx_i\in \mathcal{X}=\mathbf{R}_nyiY={1,+1}y_i\in \mathcal{Y}=\{-1,+1\}i=1,2, ,Ni=1,2,\cdots,N;學習率 η(0<η1)\eta(0<\eta \leq 1)

輸出w,bw,b;感知機模型 f(x)=sign(wx+b)f(x)=sign(w\cdot x+b)

訓練步驟:

(1)選取初值 w0w_0b0b_0

(2)在訓練集中選取數據 (xi,yi)(x_i,y_i)

(3)如果 yi(wxi+b)0y_i(w\cdot x_i+b)\leq0,則更新wwbb

ww+ηyixiw\leftarrow w+\eta y_ix_i

bb+ηyib\leftarrow b+\eta y_i

(4)跳轉到(2),直至訓練集中沒有誤分類點。

  這種學習算法直觀上有如下解釋:當一個實例點被誤分類,即位於分離超平面的錯誤一側時,則調整 wwbb 的值,使分類超平面向該誤分類點的一側移動,以減少該誤分類點與超平面的距離,直至超平面越過該誤分類點使其被正確分類。

  Python 代碼實現:

import numpy as np
import matplotlib.pyplot as plt


class Perceptron:
    def __init__(self):
        pass

    def processData(self, datas):
        xArr = np.array([x[0] for x in datas])
        yArr = np.array([x[1] for x in datas])
        return xArr, yArr

    def train(self, train_datas, learning_rate = 1):
        xArr, yArr = self.processData(train_datas)
        self.w = np.zeros(xArr.shape[1])
        self.b = 0
        self.learning_rate = learning_rate
        num = 0
        while(True) :
            num = 0
            for i in range(len(train_datas)):
                # num += 1
                loss = yArr[i] * (np.dot(self.w, xArr[i]) + self.b)
                print('loss = ', loss)
                if loss <= 0:
                    self.w += learning_rate*yArr[i]*xArr[i]
                    self.b += learning_rate*yArr[i]
                    break
                num += 1
            print('num = ', num)
            if num >= len(train_datas):
                break;

    def predict(self, x):
        return np.where(np.dot(self.w, x) + self.b >= 0.0, 1, -1)


if __name__ == "__main__":
    datas = [[(1,2),-1],[(2,1),-1],[(2,2),-1],[(1,4),1],[(3,3),1],[(5,4),1],[(3, 3), 1], [(4, 3), 1], [(1, 1), -1],[(2, 3), -1], [(4, 2.5), 1]]
    perceptron = Perceptron()
    perceptron.train(datas, 0.1)

    print("w = ", perceptron.w, ", b = ", perceptron.b)

    fig = plt.figure('Input Figure')
    xArr = np.array([x[0] for x in datas])
    yArr = np.array([x[1] for x in datas])
    pPlotx, pPloty, nPlotx, nPloty = [], [], [], []
    for i in range(len(datas)):
        if yArr[i] > 0:
            pPlotx.append(xArr[i][0])
            pPloty.append(xArr[i][1])
        else :
            nPlotx.append(xArr[i][0])
            nPloty.append(xArr[i][1])
    pPlot, nPlot = plt.plot(pPlotx, pPloty, 'b+', nPlotx, nPloty, 'rx')
    plt.legend(handles=[pPlot, nPlot], labels=['Positive Sample', 'Negtive Sample'], loc='upper center')

    x0_max, x0_min = max(xArr[:, 0])+1, min(xArr[:, 0])-1
    x1_max, x1_min = max(xArr[:, 1])+1, min(xArr[:, 1])-1
    x = np.arange(x0_min, x0_max, 0.1)
    plt.plot(x, (-perceptron.b-perceptron.w[0]*x)/perceptron.w[1], 'b')

    plt.show()

運行以上代碼,將得出以下的擬合圖:
在這裏插入圖片描述
  當訓練數據集線性可分時,感知機學習算法原始形式迭代是收斂的。對於不同的選擇初值,以及迭代過程中誤分類點的不同選擇順序,感知機算法會存在多個不同的解。當訓練集線性不可分時,感知機學習算法不收斂,迭代結果會發生震盪。

3.2 感知機學習算法的對偶形式

  對偶形式的基本思想是:wwbb 表示爲實例 xix_i 和標記 yiy_i 的線性組合的形式,通過求解其係數而求得 wwbb。不失一般性,在原始形式的算法中可假設初始值 w0w_0b0b_0均爲0。對誤分類點 (xi,yi)(x_i,y_i) 通過

ww+ηyixiw\leftarrow w+\eta y_ix_i

bb+ηyib\leftarrow b+\eta y_i

逐步修改 wwbb,設修改 nn 次,則 wwbb 關於 (xi,yi)(x_i,y_i) 的增量分別是 αiyixi\alpha_iy_ix_iαiyi\alpha_iy_i,這裏 αi=niη\alpha_i=n_i\eta。這樣,從學習過程中不難看出,最後學習到的 wwbb 可以分別表示爲

w=i=1Nαiyixiw=\sum_{i=1}^{N}\alpha_iy_ix_i

b=i=1Nαiyib=\sum_{i=1}^{N}\alpha_iy_i

這裏,αi0\alpha_i\geq0i=1,2,&ThinSpace;,Ni=1,2,\cdots,N
  算法 1.2 (感知機學習算法的對偶形式)

輸入:訓練數據集 T=(x1,y1),(x2,y2),&ThinSpace;,(xN,yN)T={(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)},其中 xiX=Rnx_i\in \mathcal{X}=\mathbf{R}_nyiY={1,+1}y_i\in \mathcal{Y}=\{-1,+1\}i=1,2,&ThinSpace;,Ni=1,2,\cdots,N;學習率 η(0&lt;η1)\eta(0&lt;\eta \leq 1)

輸出α,b\alpha,b;感知機模型 f(x)=sign(j=1Nαjyjxjx+b)f(x)=sign\Big(\sum_{j=1}^{N}\alpha_jy_jx_j\cdot x+b\Big)。其中 α=(α1,α2,&ThinSpace;,αN)T\alpha=(\alpha_1,\alpha_2,\cdots,\alpha_N)^T

訓練步驟:

(1)α0\alpha\leftarrow0b0b\leftarrow0

(2)在訓練集中選取數據 (xi,yi)(x_i,y_i)

(3)如果 yi(j=1Nαjyjxjx+b)0y_i\Big(\sum_{j=1}^{N}\alpha_jy_jx_j\cdot x+b\Big)\leq0,則更新 αi\alpha_ibb

αiαi+η\alpha_i\leftarrow \alpha_i+\eta

bb+ηyib\leftarrow b+\eta y_i

(4)跳轉到(2),直至訓練集中沒有誤分類點。

  對偶形式中訓練實例僅以點積的形式出現。爲了方便,可以預先將訓練集中實例間的點積計算出來並以矩陣的形式存儲,這個矩陣就是所謂的 Gram 矩陣(Gram matrix)。

參考:
[1] 李航《統計學習方法》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章