這一章介紹神經(jīng)網(wǎng)絡(luò),從簡單單元到簡單的神經(jīng)網(wǎng)絡(luò)——感知機(jī),再到復(fù)雜的多層神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)算法——BP算法,和一些常見的神經(jīng)網(wǎng)絡(luò),最后介紹了深度學(xué)習(xí)。
接下來我們就從最簡單的神經(jīng)元模型來了解神經(jīng)網(wǎng)絡(luò),
5.1神經(jīng)元模型
所謂的神經(jīng)網(wǎng)絡(luò)其實(shí)是模仿生物的神經(jīng)系統(tǒng)來對(duì)真實(shí)的事例做出反應(yīng),而我們?cè)跈C(jī)器學(xué)習(xí)中所提到的主要是神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)。
在介紹神經(jīng)元模型之前,我們先來看看生物神經(jīng)網(wǎng)絡(luò)中的神經(jīng)元,對(duì)于生物的神經(jīng)元在受到興奮信號(hào)時(shí)向其他相連的神經(jīng)元釋放化學(xué)物質(zhì),來引起它們的電位變化,一旦超過某個(gè)閾值則引起這些神經(jīng)元興奮。
M-P神經(jīng)元模型:它便是模仿上面生物神經(jīng)元情形設(shè)計(jì)出來的,該模型會(huì)接收一定的輸入值,將這些值按權(quán)重加總,然后與閾值比較,經(jīng)激活函數(shù)處理后輸出。
【注:圖中的f(x)便是激活函數(shù)】
常將Sigmoid函數(shù)作為激活函數(shù):
把多個(gè)神經(jīng)元按一定的層次結(jié)構(gòu)連接起來便得到了神經(jīng)網(wǎng)絡(luò)。所以下面我們來介紹最簡單的神經(jīng)網(wǎng)絡(luò)——感知機(jī)。
5.2感知機(jī)與多層網(wǎng)絡(luò)
感知機(jī):由兩層神經(jīng)元組成,輸入層接收信號(hào)傳遞給輸出層,輸出層是M-P神經(jīng)元(閾值邏輯單元)。感知機(jī)只有輸出層可以進(jìn)行激活函數(shù)處理,即只有一層功能神經(jīng)元,所以只能處理簡單的與、或、非等線性可分問題。
感知機(jī)的學(xué)習(xí)規(guī)則:作為神經(jīng)元我們需要得到的變量有閾值θ和權(quán)重,但是這里將閾值看作一個(gè)固定輸入-1.0的“啞結(jié)點(diǎn)”所對(duì)應(yīng)的連接權(quán)重
,所以只需要求n+1個(gè)權(quán)重即可。對(duì)訓(xùn)練樣例(x,y),若當(dāng)前感知機(jī)的輸出為
,則感知機(jī)權(quán)重將這樣調(diào)整:
,其中
,
稱為學(xué)習(xí)率。
通過感知機(jī)的學(xué)習(xí)規(guī)則對(duì)權(quán)重不斷的調(diào)整,最終使感知機(jī)輸出的預(yù)測(cè)值與樣例的值相同,便得到我們所需要的感知機(jī)了。
而對(duì)于非線性可分問題,就要使用多層功能神經(jīng)元。如下圖:在輸出層與輸入層之間的一層神經(jīng)元稱為隱層或隱含層。
【注:隱含層和輸出層神經(jīng)元都是擁有激活函數(shù)的功能神經(jīng)元】
多層前饋神經(jīng)網(wǎng)絡(luò):每層神經(jīng)元與下一層神經(jīng)元全互連,神經(jīng)元之間不存在同層連接,也不存在跨層連接。
5.3誤差逆?zhèn)鞑ニ惴?/h2>
神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)過程其實(shí)就是通過訓(xùn)練數(shù)據(jù)來調(diào)整權(quán)重和閾值,那么多層網(wǎng)絡(luò)(包含隱含層的神經(jīng)網(wǎng)絡(luò))的閾值和權(quán)重要怎么調(diào)整呢?
對(duì)于多層網(wǎng)絡(luò),主要使用的算法是誤差逆?zhèn)鞑ニ惴?簡稱BP算法)。
BP算法是怎么樣的呢?接下來我們一起來看一下吧。我們需要先定義一些變量。
BP算法
給定訓(xùn)練集,即輸入示例由d個(gè)屬性描述,輸出
維實(shí)值向量。給定一個(gè)擁有d個(gè)輸入神經(jīng)元、
個(gè)輸出神經(jīng)元、q個(gè)隱藏神經(jīng)元的多層前饋網(wǎng)絡(luò)結(jié)構(gòu),其中輸出層第
個(gè)神經(jīng)元的閾值用
表示,隱藏層第h個(gè)神經(jīng)元的閾值用
表示。輸出層第
個(gè)神經(jīng)元與隱藏層第h個(gè)神經(jīng)元之間的連接權(quán)為
,隱藏層第h個(gè)神經(jīng)元與輸出層第j個(gè)神經(jīng)元之間的連接權(quán)為
。
記隱藏層第h個(gè)神經(jīng)元接收到的輸入為:
輸出層第j個(gè)神經(jīng)元接收到的輸入為,其中
為隱藏層第h個(gè)神經(jīng)元的輸出
假設(shè)隱藏和輸出層的激活函數(shù)為Sigmoid函數(shù)。
對(duì)于訓(xùn)練例
則網(wǎng)絡(luò)在
在定義說明好變量后,我們就需要來求這些閾值和連接權(quán)了,共有個(gè)未知數(shù)要確定。
【注:輸入到隱藏層d*q個(gè)權(quán)值,隱藏到輸出
BP算法與感知機(jī)學(xué)習(xí)規(guī)則類似,都基于梯度下降策略,通過訓(xùn)練例對(duì)閾值和權(quán)重進(jìn)行不斷的調(diào)整來得到最終的閾值與權(quán)重。
調(diào)整的規(guī)則:對(duì)于任意參數(shù)
下面是以隱藏到輸出層的權(quán)重來說明如何更新:
【注:BP算法的目標(biāo)是最小化訓(xùn)練集D上的累計(jì)誤差
標(biāo)準(zhǔn)BP算法:每次針對(duì)一個(gè)訓(xùn)練集樣例來更新權(quán)重與閾值,所以更新頻繁,需要多次迭代。
累計(jì)BP算法:讀取整個(gè)訓(xùn)練集D后才對(duì)參數(shù)進(jìn)行更新,更新頻率低,但是累計(jì)誤差下降到一定程度后進(jìn)一步下降就很慢了。
試錯(cuò)法:用來調(diào)整設(shè)置隱藏層的神經(jīng)元個(gè)數(shù)。
BP神經(jīng)網(wǎng)絡(luò)因?yàn)楸硎灸芰?qiáng)大,所以常常會(huì)過擬合,如何緩解其過擬合呢?主要有兩個(gè)方法:①“早停”策略,將數(shù)據(jù)集分為訓(xùn)練集和驗(yàn)證集,訓(xùn)練集訓(xùn)練后以驗(yàn)證集來測(cè)試其誤差,若訓(xùn)練集誤差下降而驗(yàn)證集誤差上升則停止訓(xùn)練,并返回最小驗(yàn)證誤差的閾值和權(quán)重。②“正則化”策略,在誤差目標(biāo)函數(shù)增加一個(gè)用于描述網(wǎng)絡(luò)復(fù)雜度的部分,如:連接權(quán)與閾值的平方和,使誤差目標(biāo)函數(shù)變?yōu)椋?img class="math-inline" src="https://math.jianshu.com/math?formula=E%3D%7B%5Clambda%7D%7B%5Cfrac%7B1%7D%7Bm%7D%7D%7B%5Csum_%7Bk%3D1%7D%5Em%7BE_k%7D%2B(1-%5Clambda)%5Csum_iw_i%5E2%7D" alt="E={\lambda}{\frac{1}{m}}{\sum_{k=1}^m{E_k}+(1-\lambda)\sum_iw_i^2}" mathimg="1">,其中
5.4全局最小與局部極小
對(duì)和
,若存在
使得
,都有
成立,則
為局部極小值。
若對(duì)于參數(shù)空間中任意都有
,則
為全局最小值。
我們?cè)谶M(jìn)行參數(shù)尋優(yōu)過程中,若只找到一個(gè)局部極小值它就是全局最小,但是若有多個(gè)局部極小值,我們就容易陷入局部極小。
我們通常用三種策略來跳出局部極小:①以多組不同參數(shù)值初始化多個(gè)神經(jīng)元網(wǎng)絡(luò),按標(biāo)準(zhǔn)方法訓(xùn)練后,取其中誤差最小的解作為最終參數(shù)。(更接近全局最小)②“模擬退火”,每一步都以一定的概率接受比當(dāng)前解更差的結(jié)果,以此來跳出局部極小。③使用隨機(jī)梯度下降,在計(jì)算梯度時(shí)加入了隨機(jī)因素,即使陷入局部極小梯度也可能不為0。
5.5其他常見神經(jīng)網(wǎng)絡(luò)
①RBF網(wǎng)絡(luò)
該網(wǎng)絡(luò)隱藏層使用徑向基函數(shù)作為激活函數(shù),輸出層則是對(duì)隱藏層輸出的線性組合。
訓(xùn)練規(guī)則:①確定神經(jīng)元中心,常用的方法包括隨機(jī)取樣、聚類等。②利用BP算法來確定參數(shù)
。
假定輸入為d維向量x,輸出為實(shí)值,RBF網(wǎng)絡(luò)可以表示為:,其中
第i個(gè)隱層神經(jīng)元對(duì)應(yīng)的中心,
是徑向基函數(shù)。
②ART網(wǎng)絡(luò)
競(jìng)爭型學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)中常用的一種無監(jiān)督學(xué)習(xí)策略,網(wǎng)絡(luò)的輸出神經(jīng)元相互競(jìng)爭,每一時(shí)刻僅有一個(gè)競(jìng)爭勝利的神經(jīng)元被激活,其他神經(jīng)元被抑制(這種機(jī)制稱“勝利者通吃”)。
ART網(wǎng)路就是競(jìng)爭型學(xué)習(xí)的代表,該網(wǎng)絡(luò)由比較層、識(shí)別層、識(shí)別閾值和重置模塊構(gòu)成。
原理:比較層接收輸入樣本,并傳遞到識(shí)別層,識(shí)別層每個(gè)神經(jīng)元對(duì)應(yīng)一個(gè)模式類,計(jì)算輸入向量與每個(gè)識(shí)別層神經(jīng)元所對(duì)應(yīng)的模式類的代表向量之間的距離,距離最小者獲勝。然后輸入向量與獲勝神經(jīng)元所對(duì)應(yīng)的代表向量之間的相似度大于識(shí)別閾值,則將輸入樣本歸入為該代表向量所屬類別,若不大于則重置模塊將在識(shí)別層增加一個(gè)新的神經(jīng)元,其代表向量為當(dāng)前輸入向量。
③SOM網(wǎng)絡(luò)
SOM網(wǎng)絡(luò):一種競(jìng)爭型學(xué)習(xí)的無監(jiān)督神經(jīng)網(wǎng)絡(luò),它能將高維輸入數(shù)據(jù)映射到低維空間,同時(shí)保持輸入數(shù)據(jù)在高維空間的拓?fù)浣Y(jié)構(gòu),即將高維空間中相似的樣本點(diǎn)映射到網(wǎng)絡(luò)輸出層中的相鄰神經(jīng)元。
SOM訓(xùn)練的目標(biāo):每個(gè)輸出層神經(jīng)元找到合適的權(quán)向量,以達(dá)到保持拓?fù)浣Y(jié)構(gòu)的目的。
④級(jí)聯(lián)相關(guān)網(wǎng)絡(luò)
結(jié)構(gòu)自適應(yīng)網(wǎng)絡(luò):將網(wǎng)絡(luò)結(jié)構(gòu)也作為學(xué)習(xí)目標(biāo),且希望在訓(xùn)練中找到最符合數(shù)據(jù)特點(diǎn)的網(wǎng)絡(luò)結(jié)構(gòu)。
級(jí)聯(lián)相關(guān)網(wǎng)路是結(jié)構(gòu)自適應(yīng)網(wǎng)絡(luò)的代表,主要有兩個(gè)成分:“級(jí)聯(lián)”(指建立層次連接的層級(jí)結(jié)構(gòu))和“相關(guān)”(指通過最大化新神經(jīng)元的輸出與網(wǎng)絡(luò)誤差之間的相關(guān)性來訓(xùn)練相關(guān)的參數(shù))
⑤Elman網(wǎng)絡(luò)
遞歸神經(jīng)網(wǎng)絡(luò):允許網(wǎng)絡(luò)中出現(xiàn)環(huán)形結(jié)構(gòu),從而讓一些神經(jīng)元的輸出反饋回來作為輸入信號(hào)的網(wǎng)絡(luò)。
Elman網(wǎng)絡(luò)就是常用的遞歸神經(jīng)網(wǎng)絡(luò),其隱層神經(jīng)元通常使用Sigmoid激活函數(shù)。
⑥Boltzmann機(jī)
Boltzmann機(jī):為網(wǎng)絡(luò)狀態(tài)定義一個(gè)“能量”,該網(wǎng)絡(luò)追求最小化這個(gè)能量函數(shù),
令向量表示n個(gè)神經(jīng)元的狀態(tài)(Boltzmann機(jī)中的神經(jīng)元都是布爾型只有兩種狀態(tài)),
表示神經(jīng)元i與j之間的連接權(quán),
表示神經(jīng)元i的閾值,則其狀態(tài)向量
所對(duì)應(yīng)的Boltzmann機(jī)能量定義為:
。
受限Boltzmann機(jī):只保留了顯層與隱層之間的連接。
常用對(duì)比散度(簡稱CD)算法來訓(xùn)練。假定網(wǎng)路中有d個(gè)顯層神經(jīng)元和q個(gè)隱層神經(jīng)元,令分別表示顯、隱層的狀態(tài)向量,則由于同一層內(nèi)不存在連接,有。CD算法對(duì)每個(gè)訓(xùn)練樣本v,先根據(jù)第一個(gè)式子算出隱層神經(jīng)元狀態(tài)的概率分布,再根據(jù)這個(gè)概率分布采樣得到h,再根據(jù)第二個(gè)式子從h從產(chǎn)生v',再從v'產(chǎn)生h';連接權(quán)的更新公式:。
5.6深度學(xué)習(xí)
典型的深度學(xué)習(xí)模型就是很深層的神經(jīng)網(wǎng)絡(luò),而增加神經(jīng)網(wǎng)絡(luò)的復(fù)雜程度有兩個(gè)方法:
①增加隱層的數(shù)目。
②增加隱層的神經(jīng)元數(shù)目。
【注:方法①優(yōu)于②,方法①不僅增加了擁有激活函數(shù)的神經(jīng)元數(shù)目還增加了激活函數(shù)嵌套的層數(shù)】
對(duì)于多隱層的網(wǎng)絡(luò)訓(xùn)練方法主要有兩種:
①預(yù)訓(xùn)練(每次訓(xùn)練一層隱結(jié)點(diǎn))+微調(diào)(預(yù)訓(xùn)練后利用BP算法對(duì)整個(gè)網(wǎng)絡(luò)進(jìn)行調(diào)整)
②權(quán)共享,即讓每一組神經(jīng)元使用相同的連接權(quán)。
深度學(xué)習(xí)又稱特征學(xué)習(xí)或表示學(xué)習(xí):通過機(jī)器學(xué)習(xí)來自己產(chǎn)生特征,而不用事先給定。
【補(bǔ)】BP算法的例子,通過隨機(jī)給定變量和預(yù)先設(shè)定初始變量權(quán)重和輸入,發(fā)現(xiàn)隨機(jī)給定變量的迭代后的效果很可能比預(yù)先給定變量的效果來的好,而通過閾值的修改我們可以得到一個(gè)效果更好的模型,雖然可能過擬合。下面是例子代碼。
import math
import numpy as np
from numpy import *
#******設(shè)定模型所需的激活函數(shù)******#
def sigmoids(z):
a = []
for each in z:
b = 1/(1+math.exp(-each[0]))
a.append(b)
return a
#******設(shè)定前向傳播過程******#
def forwordmd(x,w,v,b1,b2):
net1 = w.T*x+b1
h = np.matrix(sigmoids(np.array(net1))).T #隱藏單元
net2 = v.T*h+b2
pred_y = np.matrix(sigmoids(np.array(net2))).T #輸出單元
return pred_y,h
#******設(shè)定模型反向傳播********#
def Bpaugorith(y,pred_y,h,v,aph,w):
errorter = 0.5*(y-pred_y).T*(y-pred_y) #給出誤差公式
#給出輸出單元對(duì)應(yīng)誤差項(xiàng)
a1 = multiply(pred_y-y,pred_y) #矩陣對(duì)應(yīng)元素相乘
a2 = multiply(a1,1-pred_y) #隱藏層到輸出層的誤差項(xiàng)
verror = h*a2.T #權(quán)重的更新值△
#計(jì)算隱藏單元的對(duì)應(yīng)誤差
werror = x*(multiply(multiply(h,1-h),(v*a2))).T
#更新權(quán)重
vupdate = v - aph*verror
wupdate = w - aph*werror
return vupdate,wupdate,errorter
#主程序部分,設(shè)置了輸入值、初始值、輸出值的真實(shí)值、迭代次數(shù)
if __name__ =='__main__':
'''x = matrix([0.05,0.10]).T
y = matrix([0.01,0.99]).T
#給出初始權(quán)重
w = matrix([[0.15,0.20],[0.25,0.30]])
b1 = matrix([0.1,0.1]).T
v = matrix([[0.40,0.45],[0.50,0.55]])
b2 = matrix([0.2,0.2]).T
'''
#隨機(jī)參數(shù)生成
np.random.seed(0)
w = matrix(np.random.normal(0,1,[2,2]))
b1 = matrix(np.random.normal(0,1,[1,2]))
v = matrix(np.random.normal(0,1,[2,2]))
b2 = matrix(np.random.normal(0,1,[1,2]))
#學(xué)習(xí)率
aph=0.5
#迭代次數(shù)
'''n = 10
for i in range(n):
#激活前向算法
pred_y, h= forwordmd(x,w,v,b1,b2) #得到預(yù)測(cè)值和隱藏層的值
#更新權(quán)重
vupdate,wupdate,errorvalue = Bpaugorith(y,pred_y,h,v,aph,w) #得到更新權(quán)重
w,v = wupdate,vupdate
print('預(yù)測(cè)值:' )
print(pred_y)
print('更新的權(quán)重v:')
print(vupdate)
print('更新的權(quán)重w:')
print(wupdate)
print('損失值:')
print(errorvalue)
'''
#設(shè)置閾值E
e,m = 0.19,1
pred_y,h = forwordmd(x,w,v,b1,b2)
vupdate,wupdate,errorvalue = Bpaugorith(y,pred_y,h,v,aph,w)
w,v = wupdate,vupdate
while errorvalue>e:
pred_y,h = forwordmd(x,w,v,b1,b2)
vupdate,wupdate,errorvalue = Bpaugorith(y,pred_y,h,v,aph,w)
w,v = wupdate,vupdate
m = m+1
print('閾值e:%.2f'%e)
print('迭代次數(shù)m:%d次'%m)
print('預(yù)測(cè)值:' )
print(pred_y)
print('更新的權(quán)重v:')
print(vupdate)
print('更新的權(quán)重w:')
print(wupdate)
print('損失值:')
print(errorvalue)
代碼例子參考:https://gitee.com/someone317/backpropagation_algorithm_test/blob/master/BPtest1.py#