一、感知機(單個神經元)
感知機是基本的處理元素。它具有輸入(其輸入可以來自外部輸入,也可以來自其他感知機)。與每個輸入xi 相關聯的
是一個鏈接權重(突觸權重)wi,而輸出y在最簡單的情況下是這些輸入的加權和(也可以是其他類型)
如上圖所示就是一個簡單的感知機。接收n個帶權重的信號,將總輸入值與閥值θ進行比較,通過激活函數f(*)產生輸出;
二、激活函數
傳統的激活函數是將輸入值映射到0到1上的輸出,如階躍函數、Sigmoid函數、tanh函數、ReLU函數:
階躍函數 sgn(x)
圖像不連續且不光滑,sgn(x)=1,x≥0 反之爲0;
Sigmoid函數 sigmoid(x)
圖像光滑平坦,但在x趨於∞時導數爲0;
sigmoid(x)= 1 / ( 1+e^(-x) )
tanh函數 tanh(x)
值域在-1到1之間,圖像連續可導。
tanh(x)= [ e^x - e^(-x) ] / [ e^x + e^(-x) ]
ReLU函數 ReLU(x)
在小於0的部分導數值爲0,在大於0的部分導數值爲常數k;
ReLU(x) = max( 0,kx )
單層感知機網絡(包含輸入層和輸出層)
只包含輸入和輸出兩層,用於解決線性可分問題。
訓練過程基本思想:(正向傳播,反向更新)
1)正向計算模型預測值a; 2)比較預測值a與真實值之間的差異(作差); 3)利用差值求解(更新)參數;
實戰—利用單層感知機實現(與 或 非問題)
import numpy as np #導入numpy數據包
from matplotlib import pyplot as plt #導pyplot
datasetX= np.array(
[[0,0,1],[0,1,1],[1,0,1],[1,1,1]]
) #數據集X:前兩列爲x1和x2,最後一列爲b
datasetY=np.array([0,1,1,1]) #數據集Y
np.random.seed(1)
w=np.random.random((1,3)) #係數(參數)
def sigmoid(x):
return 1/(1+np.exp(-x)) #sigmoid函數
rate = 0.02 #學習率
step = 1000 #學習步長
for i in range(step):
sum=np.dot(w,datasetX.T)
error=sigmoid(sum)-datasetY
w=w-rate*np.dot(error,datasetX)
#繪製圖像
X=np.array([-0.2,0.55])
print(w)
plt.scatter(0,0,c='blue') #以或問題爲例子
plt.scatter([0,1,1],[1,0,1],c='r')
plt.plot(X,-(w[0][0]*X+w[0][2])/w[0][1],c='black')
plt.show()
運行結果:
或問題訓練圖像;(源碼以或問題爲例)
與問題訓練圖像 (改數據集和繪製區間即可);
非問題訓練圖像,結合三幅圖像與實際分類大體一致。
異或不同爲1相同爲0,可以結合或問題和與問題進行求解;
下面我們推到爲什麼可以通過此種方式求解參數:(結合下圖的變化過程)
X爲列向量(x1,x2,....,xn-1,1)^T ,Y爲輸出結果這裏爲單神經元故Y爲常數(0,1),W爲(1 X n)的矩陣;
Z=WX,A = f (Z) (這裏的 f就爲激活函數),這裏定義誤差函數爲 L( A,y )= - ylnA - (1-y)ln( 1-A );(越小越好)
要結合梯度下降算法我們需要求解 △w並根據 w=w-α△w實現對w的更新。已知誤差函數L我們可以求得其對A的偏導數
爲 - ( y/A )+( 1-y )/( 1 - A )【化簡整理的 ( A - y ) / ( 1 - A )A】,結合鏈式法則我們可以求得 △w=(A-y)*x;
所以得出:wi = wi - α( A - y )xi;(注:這裏的α爲學習率,通常取值爲0.01,0.02,0.03等)
結合或問題的實例,X爲(3,4)矩陣,y爲(1,4)矩陣,W爲(1,3)矩陣(其導數與其維數相同)
W=W - α(A - y)X,這裏的X爲X的轉置(4,3)矩陣。
顯然只用一個神經元構造的網絡職能解決線性問題,對於非線性問題單層模型無法解決。
三、多層前饋神經網絡
多層前饋神經網絡,也稱爲多層感知機,包含輸入層(input layer)、隱含層(hidden layer)、輸出層(output layer)
位於隱含層和輸出層的神經元具有激活函數,通常輸入層僅接受輸入數據不具備處理功能。
多層神經網絡可以解決“非線性”問題,相比單個神經元處理特徵數據效果更好。
給定樣本數據集D={(x1,y1),(x2,y2),....,(xn,yn)},其中 xi 屬於 d 維空間,yi 屬於 l 維空間;
如上圖所示的兩層神經網絡有d個輸入,hidden層有q個結點,產生l個輸出,由輸入層到hidden層要確定的參數
個數爲 q x d個,由hidden層到輸出層要確定的參數個數爲 l x q個,故總共要求解的參數個數爲 (d + l)q個。
誤差反向傳播算法(BP算法):類似於梯度下降算法,是一種迭代算法,每一次迭代實現對模型參數的更新。
在這裏我們將樣本的誤差(error)定義爲:
X | 輸入特徵值(輸入集合) xi 表示輸入層第i個結點對應的輸入 |
Y | 輸出值,yi表示輸出層第i個結點對應的輸出 |
V |
由輸入層到隱層(hidden layer)的參數矩陣 v【ih】表示輸入層 i 結點到隱層 h 結點之間的連接權 |
W |
由隱層(hidden layer)到輸出層的參數矩陣 W【hj】表示隱層 h 結點到輸出層 j 結點之間的連接權 |
這裏的 i 屬於【1,d】 h 屬於【1,q】 j 屬於【1,l】,不大於對應層 的結點個數且取值都爲正整數 |
所謂的誤差反向傳播,就是從輸出層開始回退,逐層實現每一層之間的連接權值的更新,更新推導如下:
更新W中對應的參數w【hj】同感知機相同,只需求出△w【hj】即可,結合誤差函數
我們可以得到,下一步只需求解△Ek/△w【hj】,結合鏈式求導法則:
結合Sigmoid函數導數f(x)(1-f(x)),即上式子的中間部分可通過此替換,第三部分爲b【h】可得gj梯度項:
由此我們可以完成W參數矩陣的更新,下面繼續反向傳播,以類似的方法更新V參數矩陣。
我們只需求解eh即可,這裏的 xi 爲上一層的輸入數據(學習率*梯度項*上一層輸入)
誤差反向傳播算法(BP算法)僞代碼:
BP神經網絡的優點與缺點:
優點:實現了一個從輸入到輸出的映射功能,可實現任何複雜非線性映射,網絡能通過學習大量的正確實例
來逐步增強和完善自己。缺點:收斂速度較慢,所得到的結果未必是全局最優解;
實戰:BP神經網絡實現與或非問題:
import numpy as np#導入數據包
from matplotlib import pyplot as plt
from sklearn import datasets
def sigmoid(x):#sigmoid函數
return 1.0/(1 + np.exp(-x))
def dsigmoid(Z):#sigmoid函數的導數
return Z*(1-Z)
dataX=np.array([[0,0],[0,1],[1,0],[1,1]])
dataY=np.array([0,1,1,1]).reshape(4,1)#數據集X
learnrate=1 #學習率
studystep=2500 #最大迭代次數
#初始化網絡結構
inputlayer_size=dataX.shape[1] #輸入層結點個數
hiddenlayer_size=inputlayer_size+1 #隱含層結點個數
outputlayer_size=dataY.shape[1] #輸出層結點個數
np.random.seed(1)#在0到1之間初始化各矩陣的連接權
V=np.random.random((hiddenlayer_size,inputlayer_size)) #V矩陣的隨機初始化
W=np.random.random((outputlayer_size,hiddenlayer_size)) #W矩陣的隨機初始化
#2-神經網絡層次模型&訓練
for i in range(studystep):
#正常傳遞求解模型估計參數
hiddenvalue=sigmoid(np.dot(V,dataX.T)) #隱藏層輸出值
outputvalue=sigmoid(np.dot(W,hiddenvalue)) #模型預測值
g=dsigmoid(outputvalue)*(outputvalue-dataY.T)
e=dsigmoid(hiddenvalue)*(1-hiddenvalue)*np.dot(W.T,g) #求解梯度
W=W-learnrate*np.dot(g,hiddenvalue.T) #反向傳遞,最後更新
V=V-learnrate*np.dot(e,dataX) #更新參數W和V
#模型結果預測
predict=sigmoid(np.dot(W,sigmoid(np.dot(V,dataX.T))))
print(predict.T)
這裏以或問題爲例,運行結果如下圖所示:(對於與、非以及異或問題只需修改對應的數據集即可)
總體來說效果還是可以的,當然這僅僅是實現了一個簡單神經網路,還有許多後序問題需要解決
比如在何處取得全局最優解,如何提高模型的速率,以及梯度消失(爆炸)的解決等;
針對全局最優解的求解現有的方法有:隨機梯度下降、模擬退火、遺傳以及蟻羣算法等;