1. 程式人生 > >機器學習與神經網路(二):感知器的介紹和Python程式碼實現

機器學習與神經網路(二):感知器的介紹和Python程式碼實現

前言:本篇博文主要介紹感知器的相關知識,採用理論+程式碼實踐的方式,進行感知器的學習。本文首先介紹感知器的模型,然後介紹感知器學習規則(Perceptron學習演算法),最後通過Python程式碼實現單層感知器,從而給讀者一個更加直觀的認識。

1.單層感知器模型

單層感知器是一種具有單層計算單元的神經網路,他的結構和功能都非常的簡單,以至於現在在實際問題中很少被採用,但是感知器(Perceptron)首次提出了自組織、自學習的思想,所以他在神經網路的學習中起著基礎性的作用。

1.1感知器模型

下圖是一個單層感知器的模型圖,他包含多個輸入節點X0-Xn,權值向量W0-Wn(注意,這裡X0和W0代表的是偏置因子,一般X0=1,圖中X0處應該是Xn),一個輸出節點o,啟用函式是sgn函式。(ps圖片均來自網路)


根據上圖,我們可以看出,神經元的輸出為:


2.感知器的學習規則:

前面說過,感知器具有自學習,自適應的能力,那麼他是怎麼學習的呢,我們看下圖


這裡我們解釋一下他的流程:

首先,我們輸入訓練樣本X和初始化權重向量W,將其進行向量的點乘,然後將點乘求和的結果作用於啟用函式sgn(),得到實際的輸出O,現在我們根據實際輸出O和期望輸出d之間的差距error,來調整初始化的權重向量W。如此反覆,直到W調整到合適的結果為止。

那麼,我們接著來看一下,我們怎麼根據實際輸出和期望輸出之間的差異進行權重向量W的調整呢?這就是所謂的Perceptron學習規則:


這裡還是補充一點:公式中2.19a中的eta代表學習率,他表示每次調整的幅度,這是人為設定的一個引數,一般根據經驗值或者通過實驗得出。

3.感知器的Python程式碼實現

好了,我們已經知道了感知器的模型以及相關的學習規則,那麼,我們就可以利用Python來實現他(程式碼基於Python2.7,Anaconda實現)

#! /usr/bin/env python
#coding=utf-8
import numpy as np
#感知器分類的學習
class Perceptron:
    '''
    eta:學習率
    n_iter:權重向量的訓練次數
    w_:權重向量
    errors_:記錄神經元判斷出錯的次數
    
    '''
    def __init__(self,eta=0.01,n_iter=10):
        self.eta=eta
        self.n_iter=n_iter
        
    def fit(self,X,y):
        '''
        輸入訓練資料X,訓練神經元,X輸入樣本,y為樣本分類
        x=[[1,2],[4,5]]
        y=[-1,1]
        '''
        #初始化權重向量,加1是因為W0
        self.w_=np.zeros(1+X.shape[1])
        #print(self.w_)#w_=[0,0,0]
        self.errors_=[]
        
        for i in range(self.n_iter):
            errors=0
            '''
            zip(X,y)=[[1,2,-1],[4,5,1]]
            '''
            for xi,target in zip(X,y):#每次迭代使用一個樣本去更新W
                #相當於update=$*(y-y'),這裡使用預測的結果進行誤差判斷
                update=self.eta*(target-self.predict(xi))
                '''
                xi是一個向量[1,2]
                update是一個數字
                update*xi等價於
                w1'=x1*update;w2'=x2*update
                '''
                self.w_[1:]+=update*xi
                self.w_[0]+=update*1
                #列印更新的W_
                #print self.w_
                #統計 判斷的正確與否次數
                errors+=int(update!=0)
                self.errors_.append(errors)
                
    def net_input(self,X):
        '''
        z=w0*1+w1*x1+w2x2+...+wm*xm
        其中x0=1(一般w0=0,x0=1)
        '''
        return np.dot(X,self.w_[1:])+self.w_[0]*1
    
    def predict(self,X):#相當於sign()函式
        '''
        y>=0--->1
        y<0---->-1
        '''
        return np.where(self.net_input(X)>=0.0,1,-1)