關(guān)鍵字
神經(jīng)元模型:神經(jīng)網(wǎng)絡(luò)中簡(jiǎn)單單元就可以稱為神經(jīng)元谨履。
一直沿用至今的“M-P神經(jīng)元模型”正是對(duì)這一結(jié)構(gòu)進(jìn)行了抽象,也稱“閾值邏輯單元“熬丧,其中樹突對(duì)應(yīng)于輸入部分笋粟,每個(gè)神經(jīng)元收到n個(gè)其他神經(jīng)元傳遞過來的輸入信號(hào),這些信號(hào)通過帶權(quán)重的連接傳遞給細(xì)胞體,這些權(quán)重又稱為連接權(quán)(connection weight)害捕。細(xì)胞體分為兩部分绿淋,前一部分計(jì)算總輸入值(即輸入信號(hào)的加權(quán)和,或者說累積電平)尝盼,后一部分先計(jì)算總輸入值與該神經(jīng)元閾值的差值吞滞,然后通過激活函數(shù)(activation function)的處理,產(chǎn)生輸出從軸突傳送給其它神經(jīng)元盾沫。
全局最小與局部極胁迷:模型學(xué)習(xí)的過程實(shí)質(zhì)上就是一個(gè)尋找最優(yōu)參數(shù)的過程,例如BP算法試圖通過最速下降來尋找使得累積經(jīng)驗(yàn)誤差最小的權(quán)值與閾值赴精,在談到最優(yōu)時(shí)组贺,一般會(huì)提到局部極小(local minimum)和全局最凶婺铩(global minimum)。
- 局部極小解:參數(shù)空間中的某個(gè)點(diǎn)啊奄,其鄰域點(diǎn)的誤差函數(shù)值均不小于該點(diǎn)的誤差函數(shù)值渐苏。
- 全局最小解:參數(shù)空間中的某個(gè)點(diǎn),所有其他點(diǎn)的誤差函數(shù)值均不小于該點(diǎn)的誤差函數(shù)值菇夸。
1琼富、神經(jīng)網(wǎng)絡(luò)和神經(jīng)元模型
神經(jīng)網(wǎng)絡(luò)是由具有適應(yīng)性的簡(jiǎn)單單元組成的廣泛并行互連的網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)中最基本的成分是神經(jīng)元模型庄新,即“簡(jiǎn)單單元”鞠眉。
M-P神經(jīng)元模型:神經(jīng)元接收來自n個(gè)其他神經(jīng)元傳遞過來的輸入信號(hào),輸入信號(hào)通過帶權(quán)重的連接進(jìn)行傳遞择诈,神經(jīng)元收到的總輸入值與閾值比較械蹋,然后通過“激活函數(shù)”產(chǎn)生神經(jīng)元的輸出。
理想的激活函數(shù)是圖5.2(a)所示的階躍函數(shù)羞芍,輸出值1對(duì)應(yīng)神經(jīng)元興奮哗戈,0對(duì)應(yīng)神經(jīng)元抑制,缺點(diǎn)是不連續(xù)荷科,不光滑唯咬。常用的激活函數(shù)是Sigmoid函數(shù),輸出值擠壓在(0,1)內(nèi)畏浆,又稱擠壓函數(shù)胆胰,如圖5.2(b)所示
把許多個(gè)這樣的神經(jīng)元按一定的層次結(jié)構(gòu)連接起來,就得到了神經(jīng)網(wǎng)絡(luò)刻获。
2蜀涨、多層前饋神經(jīng)網(wǎng)絡(luò)
每層神經(jīng)元與下一層神經(jīng)元全互連,神經(jīng)元之間不存在同層連接和跨層連接。其中輸入層神經(jīng)元接收外界輸入勉盅,隱層與輸出層神經(jīng)元對(duì)信號(hào)加工佑颇,由輸出神經(jīng)元輸出結(jié)果。
感知機(jī)和多層網(wǎng)絡(luò):感知機(jī)就是指由兩層神經(jīng)元組成,輸入層接收外界輸入信號(hào)后傳遞給輸出層减宣,輸出層是M-P神經(jīng)元揽思,也稱“閾值邏輯單元”。給定訓(xùn)練集茬贵,則感知機(jī)的n+1個(gè)參數(shù)(n個(gè)權(quán)重+1個(gè)閾值)都可以通過學(xué)習(xí)得到。閾值Θ可以看作一個(gè)輸入值固定為-1的啞結(jié)點(diǎn)的權(quán)重ωn+1移袍,即假設(shè)有一個(gè)固定輸入xn+1=-1的輸入層神經(jīng)元解藻,其對(duì)應(yīng)的權(quán)重為ωn+1,這樣就把權(quán)重和閾值統(tǒng)一為權(quán)重的學(xué)習(xí)了葡盗。簡(jiǎn)單感知機(jī)的結(jié)構(gòu)如下圖所示:
可以看出感知機(jī)是只有一層功能神經(jīng)元螟左,因此學(xué)習(xí)能力非常有限。在解決一些復(fù)雜問題時(shí)觅够,我們就需要提供多層的功能神經(jīng)元去處理胶背,也就是說在輸入層和輸出層之間加入一層功能神經(jīng)元,因此要解決非線性可分問題喘先,需要考慮使用多層功能神經(jīng)元钳吟,即神經(jīng)網(wǎng)絡(luò)。這一層常常稱為隱層窘拯。這樣隱層和輸出層都有了激活函數(shù)的功能神經(jīng)元红且。
多層前饋神經(jīng)網(wǎng)絡(luò):每層神經(jīng)元與下層神經(jīng)元全互連,神經(jīng)元之間不存在同層連接涤姊,也不存在跨層連接暇番,稱為“多層前饋神經(jīng)網(wǎng)絡(luò)”。這種網(wǎng)絡(luò)中的輸入層神經(jīng)元只接受輸入思喊,不進(jìn)行函數(shù)處理奔誓,隱層和輸出層包含功能神經(jīng)元。
3搔涝、誤差逆?zhèn)鞑ニ惴?/h1>
由上面可以得知:神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)主要蘊(yùn)含在權(quán)重和閾值中厨喂,多層網(wǎng)絡(luò)使用上面簡(jiǎn)單感知機(jī)的權(quán)重調(diào)整規(guī)則顯然不夠用了,BP神經(jīng)網(wǎng)絡(luò)算法即誤差逆?zhèn)鞑ニ惴ǎ╡rror BackPropagation庄呈,BP)正是為學(xué)習(xí)多層前饋神經(jīng)網(wǎng)絡(luò)而設(shè)計(jì)蜕煌,BP神經(jīng)網(wǎng)絡(luò)算法是迄今為止最成功的的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)算法。
先將輸入層輸入的數(shù)據(jù)提供給輸入層神經(jīng)元诬留,然后逐層將信號(hào)前傳斜纪,直到產(chǎn)生輸出層的結(jié)構(gòu)贫母;然后計(jì)算輸出層的誤差,再將誤差逆向傳播至隱層神經(jīng)元盒刚,最后根據(jù)隱層神經(jīng)元的誤差來對(duì)連接權(quán)和閾值進(jìn)行調(diào)整腺劣,如此循環(huán)迭代,直到達(dá)到某些條件為止因块。
上圖為一個(gè)單隱層前饋神經(jīng)網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)橘原,BP神經(jīng)網(wǎng)絡(luò)算法也使用梯度下降法(gradient descent),以單個(gè)樣本的均方誤差的負(fù)梯度方向?qū)?quán)重進(jìn)行調(diào)節(jié)涡上≈憾希可以看出:BP算法首先將誤差反向傳播給隱層神經(jīng)元,調(diào)節(jié)隱層到輸出層的連接權(quán)重與輸出層神經(jīng)元的閾值吩愧;接著根據(jù)隱含層神經(jīng)元的均方誤差芋酌,來調(diào)節(jié)輸入層到隱含層的連接權(quán)值與隱含層神經(jīng)元的閾值。注:BP算法的目標(biāo)是要最小化訓(xùn)練集D上的誤差積累雁佳,因此正因?yàn)閺?qiáng)大的表示能力脐帝,BP神經(jīng)網(wǎng)絡(luò)經(jīng)常出現(xiàn)過擬合,因此訓(xùn)練誤差持續(xù)降低糖权,而測(cè)試誤差逐漸升高堵腹。那么常用“早停”和“正則化”兩種測(cè)量來解決過擬合問題温兼。
所以BP算法,是迄今最成功的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)算法∥淦酰現(xiàn)實(shí)任務(wù)中使用神經(jīng)網(wǎng)絡(luò)時(shí)募判,大多是在使用BP算法進(jìn)行訓(xùn)練。通常說“BP網(wǎng)絡(luò)”時(shí)咒唆,一般是指用BP算法訓(xùn)練的多層前饋神經(jīng)網(wǎng)絡(luò)届垫。
上圖是一個(gè)由d個(gè)屬性、l個(gè)輸出神經(jīng)元全释、q個(gè)隱層神經(jīng)元的多層前饋網(wǎng)絡(luò)結(jié)構(gòu)装处。所示的網(wǎng)絡(luò)有幾個(gè)參數(shù)要確定:輸入層到隱層的d*q個(gè)權(quán)值、隱層到輸出層的q*l個(gè)權(quán)值浸船,q個(gè)隱層神經(jīng)元的閾值妄迁、l個(gè)輸出層神經(jīng)元的閾值。
4李命、BP算法的工作過程
參數(shù)說明:
下圖給出了BP算法的工作流程登淘。對(duì)每個(gè)訓(xùn)練樣例,BP算法執(zhí)行以下操作:先將輸入示例提供給輸入層神經(jīng)元封字,然后逐層將信號(hào)前傳黔州,直到產(chǎn)生輸出層的結(jié)果耍鬓;然后計(jì)算輸出層的誤差(第4-5行),再將誤差逆?zhèn)鞑ブ岭[層神經(jīng)元(第6行)流妻,最后根據(jù)隱層神經(jīng)元的誤差來對(duì)連接權(quán)和閾值進(jìn)行調(diào)整(第7行)牲蜀。該迭代過程循環(huán)進(jìn)行,直到達(dá)到某些停止條件為止绅这,例如訓(xùn)練誤差已達(dá)到一個(gè)很小的值涣达。
需注意的是,BP算法的目標(biāo)是要最小化訓(xùn)練集D上的累積誤差
但上圖的更新規(guī)則是基于單個(gè)的Ek推導(dǎo)而得君躺。如果是推導(dǎo)基于累積誤差最小化的更新規(guī)則峭判,就得到了累積誤差逆?zhèn)鞑ニ惴ā@鄯eBP算法和標(biāo)準(zhǔn)BP算法都很常用棕叫。一般來說林螃,標(biāo)準(zhǔn)BP算法每次更新只針對(duì)單個(gè)樣例,參數(shù)更新的非常頻繁俺泣,而且對(duì)不同樣例更新的效果可能出現(xiàn)“抵消”現(xiàn)象疗认。因此,為了達(dá)到同樣的累積誤差極小點(diǎn)伏钠,標(biāo)準(zhǔn)BP算法往往需進(jìn)行更多次迭代横漏。累積BP算法直接針對(duì)累積誤差最小化,它在讀取整個(gè)訓(xùn)練集D一遍后才對(duì)參數(shù)進(jìn)行更新熟掂,其參數(shù)更新的頻率低得多缎浇。但在很多任務(wù)中,累積誤差下降到一定程度之后赴肚,進(jìn)一步下降會(huì)非常緩慢素跺,這時(shí)標(biāo)準(zhǔn)BP往往會(huì)更快獲得較好的解,尤其是在訓(xùn)練集D非常大時(shí)更明顯誉券。
由于其強(qiáng)大的表示能力指厌,BP神經(jīng)網(wǎng)絡(luò)經(jīng)常遭遇過擬合,其訓(xùn)練誤差持續(xù)降低踊跟,但測(cè)試誤差卻可能上升踩验。有兩種策略常用來緩解BP網(wǎng)絡(luò)的過擬合。第一種策略是“早蜕堂担”:將數(shù)據(jù)集分成訓(xùn)練集和測(cè)試集箕憾,訓(xùn)練集用來計(jì)算梯度、更新連接權(quán)和閾值拳昌,驗(yàn)證集用來估計(jì)誤差厕九,若訓(xùn)練集誤差降低但驗(yàn)證集誤差升高,則停止訓(xùn)練地回,同時(shí)返回具有最小驗(yàn)證集誤差的連接權(quán)和閾值扁远。第二種策略是“正則化”俊鱼,其基本思想是在誤差目標(biāo)函數(shù)中增加一個(gè)用于描述網(wǎng)絡(luò)復(fù)雜度的部分,例如連接權(quán)與閾值的平方和畅买。
5并闲、代碼
數(shù)據(jù)來自西瓜書P84
import numpy as np
dataset = pd.read_csv('watermelon_3.csv', delimiter=",")
數(shù)據(jù)預(yù)處理
# 處理數(shù)據(jù)集
attributeMap = {}
attributeMap['淺白'] = 0
attributeMap['青綠'] = 0.5
attributeMap['烏黑'] = 1
attributeMap['蜷縮'] = 0
attributeMap['稍蜷'] = 0.5
attributeMap['硬挺'] = 1
attributeMap['沉悶'] = 0
attributeMap['濁響'] = 0.5
attributeMap['清脆'] = 1
attributeMap['模糊'] = 0
attributeMap['稍糊'] = 0.5
attributeMap['清晰'] = 1
attributeMap['凹陷'] = 0
attributeMap['稍凹'] = 0.5
attributeMap['平坦'] = 1
attributeMap['硬滑'] = 0
attributeMap['軟粘'] = 1
attributeMap['否'] = 0
attributeMap['是'] = 1
del dataset['編號(hào)']
dataset = np.array(dataset)
m, n = np.shape(dataset)
for i in range(m):
for j in range(n):
if dataset[i, j] in attributeMap:
dataset[i, j] = attributeMap[dataset[i, j]]
dataset[i, j] = round(dataset[i, j], 3)
trueY = dataset[:, n-1]
X = dataset[:, :n-1]
m, n = np.shape(X)
初始化參數(shù)
# P101,初始化參數(shù)
import random
d = n # 輸入向量的維數(shù)
l = 1 # 輸出向量的維數(shù)
q = d+1 # 隱層節(jié)點(diǎn)的數(shù)量
theta = [random.random() for i in range(l)] # 輸出神經(jīng)元的閾值
gamma = [random.random() for i in range(q)] # 隱層神經(jīng)元的閾值
# v size= d*q .輸入和隱層神經(jīng)元之間的連接權(quán)重
v = [[random.random() for i in range(q)] for j in range(d)]
# w size= q*l .隱藏和輸出神經(jīng)元之間的連接權(quán)重
w = [[random.random() for i in range(l)] for j in range(q)]
eta = 0.2 # 學(xué)習(xí)率,控制每一輪迭代的步長(zhǎng)
maxIter = 5000 # 最大訓(xùn)練次數(shù)
sigmoid函數(shù)
import math
def sigmoid(iX,dimension): # iX is a matrix with a dimension
if dimension == 1:
for i in range(len(iX)):
iX[i] = 1 / (1 + math.exp(-iX[i]))
else:
for i in range(len(iX)):
iX[i] = sigmoid(iX[i], dimension-1)
return iX
標(biāo)準(zhǔn)的誤差逆?zhèn)鞑?/p>
# 標(biāo)準(zhǔn)BP
while(maxIter > 0):
maxIter -= 1
sumE = 0
for i in range(m):
alpha = np.dot(X[i], v) # p101 line 2 from bottom, shape=1*q
b = sigmoid(alpha-gamma, 1) # b=f(alpha-gamma), shape=1*q
beta = np.dot(b, w) # shape=(1*q)*(q*l)=1*l
predictY = sigmoid(beta-theta, 1) # shape=1*l ,p102--5.3
E = sum((predictY-trueY[i])*(predictY-trueY[i]))/2 # 5.4
sumE += E # 5.16
# p104
g = predictY*(1-predictY)*(trueY[i]-predictY) # shape=1*l p103--5.10
e = b*(1-b)*((np.dot(w, g.T)).T) # shape=1*q , p104--5.15
w += eta*np.dot(b.reshape((q, 1)), g.reshape((1, l))) # 5.11
theta -= eta*g # 5.12
v += eta*np.dot(X[i].reshape((d, 1)), e.reshape((1, q))) # 5.13
gamma -= eta*e # 5.14
# print(sumE)
累積的誤差逆?zhèn)鞑?/p>
# #累積 BP
# trueY=trueY.reshape((m,l))
# while(maxIter>0):
# maxIter-=1
# sumE=0
# alpha = np.dot(X, v)#p101 line 2 from bottom, shape=m*q
# b = sigmoid(alpha - gamma,2) # b=f(alpha-gamma), shape=m*q
# beta = np.dot(b, w) # shape=(m*q)*(q*l)=m*l
# predictY = sigmoid(beta - theta,2) # shape=m*l ,p102--5.3
#
# E = sum(sum((predictY - trueY) * (predictY - trueY))) / 2 # 5.4
# # print(round(E,5))
# g = predictY * (1 - predictY) * (trueY - predictY) # shape=m*l p103--5.10
# e = b * (1 - b) * ((np.dot(w, g.T)).T) # shape=m*q , p104--5.15
# w += eta * np.dot(b.T, g) # 5.11 shape (q*l)=(q*m) * (m*l)
# theta -= eta * g # 5.12
# v += eta * np.dot(X.T, e) # 5.13 (d,q)=(d,m)*(m,q)
# gamma -= eta * e # 5.14
預(yù)測(cè)
def predict(iX):
alpha = np.dot(iX, v) # p101 line 2 from bottom, shape=m*q
b = sigmoid(alpha-gamma, 2) # b=f(alpha-gamma), shape=m*q
beta = np.dot(b, w) # shape=(m*q)*(q*l)=m*l
predictY = sigmoid(beta - theta, 2) # shape=m*l ,p102--5.3
return predictY
print(predict(X))
輸出結(jié)果
整理的課后答案 http://blog.csdn.net/icefire_tyh/article/details/52106899
整個(gè)答案:http://blog.csdn.net/icefire_tyh/article/details/52064910
完整代碼參考碼云