使用python實(shí)現(xiàn)ANN
本文實(shí)例為大家分享了python實(shí)現(xiàn)ANN的具體代碼,供大家參考,具體內(nèi)容如下
1.簡(jiǎn)要介紹神經(jīng)網(wǎng)絡(luò)
神經(jīng)網(wǎng)絡(luò)是具有適應(yīng)性的簡(jiǎn)單單元組成的廣泛并行互聯(lián)的網(wǎng)絡(luò)。它的組織能夠模擬生物神經(jīng)系統(tǒng)對(duì)真實(shí)世界物體做做出的反應(yīng)。神經(jīng)網(wǎng)絡(luò)的最基本的成分是神經(jīng)元模型,也就是最簡(jiǎn)單的神經(jīng)元模型。
“M-P模型”

如上圖所示,神經(jīng)元接收到來(lái)自n個(gè)其他神經(jīng)元傳遞過(guò)來(lái)的輸入信號(hào),這些信號(hào)通過(guò)帶權(quán)重的鏈接進(jìn)行傳遞。神經(jīng)元接收到的總輸入值將與神經(jīng)元的閾值進(jìn)行比較,然后通過(guò)“激活函數(shù)”處理以產(chǎn)生神經(jīng)元的輸出
激活函數(shù):
理想的激活函數(shù)應(yīng)該是階躍函數(shù),也就是它能夠?qū)⑤斎胫涤成涑蔀檩敵鲋?或1。其中“0”代表神經(jīng)元抑制,“1”代表神經(jīng)元興奮。但是由于階躍函數(shù)不連續(xù)且不可導(dǎo),因此實(shí)際上常常使用sigmoid函數(shù)當(dāng)做神經(jīng)元的激活函數(shù)。它能夠?qū)⒖赡茉谳^大范圍內(nèi)變化的輸出值擠壓到(0,1)之間這個(gè)范圍內(nèi)。因此有時(shí)也成為擠壓函數(shù)。常用的sigmoid函數(shù)是回歸函數(shù)
f(x) = 1/(1+e^(-x))
如下圖所示:

感知機(jī):
感知機(jī)是最簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò),它由兩層神經(jīng)元組成。輸入層接受外界信號(hào)后傳遞給輸出層。輸出層是M-P神經(jīng)元。感知機(jī)也成為閾值邏輯單元。感知機(jī)可以通過(guò)采用監(jiān)督學(xué)習(xí)來(lái)逐步增強(qiáng)模式劃分的能力,達(dá)到學(xué)習(xí)的目的。

感知機(jī)能夠?qū)崿F(xiàn)簡(jiǎn)單的邏輯運(yùn)算。
一般的,對(duì)于給定訓(xùn)練數(shù)據(jù)集,權(quán)重Wi以及閾值θ可以通過(guò)學(xué)習(xí)得到。其中閾值(bias)可以通過(guò)學(xué)習(xí)得到。在輸出神經(jīng)元中,閾值可以看做是一個(gè)固定輸入為-1,0的啞結(jié)點(diǎn),所對(duì)應(yīng)的連接權(quán)重為Wn+1,從而使得權(quán)重和閾值的學(xué)習(xí)統(tǒng)一為權(quán)重的學(xué)習(xí)。
感知機(jī)的學(xué)習(xí)規(guī)則非常簡(jiǎn)單,對(duì)于訓(xùn)練樣本(X,y),若當(dāng)前感知機(jī)輸出為y',則感知機(jī)做如下調(diào)整

其中,η屬于(0,1),稱為“學(xué)習(xí)率”
若感知機(jī)對(duì)訓(xùn)練樣例預(yù)測(cè)正確,則感知機(jī)不發(fā)生變化,否則將根據(jù)錯(cuò)誤的程度進(jìn)行權(quán)重的調(diào)整。
需要注意的是,感知機(jī)只有輸出神經(jīng)元進(jìn)行激活函數(shù)處理,因此它的學(xué)習(xí)能力非常有限,也就是因?yàn)樗挥幸粚庸δ苌窠?jīng)元。
可以證明,若兩類模式實(shí)現(xiàn)性可分的,即存在一個(gè)超平面可以將他們分開,則利用感知機(jī)一定會(huì)收斂,可以求得一個(gè)權(quán)向量。否則,感知機(jī)的學(xué)習(xí)過(guò)程將會(huì)發(fā)生震蕩,導(dǎo)致參數(shù)難以穩(wěn)定下來(lái),不等求得合適的解。例如,單層感知機(jī)不能解決抑或問(wèn)題。
如果想要解決非線性可分問(wèn)題,考慮使用多層功能神經(jīng)元。
前饋神經(jīng)網(wǎng)絡(luò)
每層神經(jīng)元與下一層神經(jīng)元全互聯(lián),神經(jīng)元之間不存在同層鏈接,也不存在跨曾鏈接。其中輸入層神經(jīng)元有由外界進(jìn)行輸入,隱藏層與輸出層神經(jīng)元對(duì)信號(hào)進(jìn)行加工,最終結(jié)果由輸出層神經(jīng)元進(jìn)行輸出。輸入層神經(jīng)元僅僅起到接受輸入的功能,并不進(jìn)行函數(shù)處理。
所謂的神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)過(guò)程,也就是根據(jù)訓(xùn)練數(shù)據(jù)來(lái)調(diào)整神經(jīng)元之間的“連接權(quán)”以及每個(gè)功能神經(jīng)元的閾值,換句話說(shuō),神經(jīng)網(wǎng)絡(luò)能夠“學(xué)習(xí)”到的東西,全部都蘊(yùn)含在“連接權(quán)”與“閾值”之中
BP算法(誤差逆?zhèn)鞑ニ惴ǎ?/p>
BP算法,也成為反向傳播算法
•在感知器算法中我們實(shí)際上是在利用理想輸出與實(shí)際輸出之間的誤差作為增量來(lái)修正權(quán)值,然而在多層感知器中,我們只能計(jì)算出輸出層的誤差,中間隱層由于不直接與外界連接,其誤差無(wú)法估計(jì)。
•反向傳播算法(BP算法)的思想:從后向前反向逐層傳播輸出層的誤差,以間接計(jì)算隱層的誤差。算法可以分為兩個(gè)階段:
–正向過(guò)程:從輸入層經(jīng)隱層逐層正向計(jì)算各單元的輸出;
–反向過(guò)程:由輸出誤差逐層反向計(jì)算隱層各單元的誤差,并用此誤差修正前層的權(quán)值。
B-P算法的學(xué)習(xí)過(guò)程如下:
(1)選擇一組訓(xùn)練樣例,每一個(gè)樣例由輸入信息和期望的輸出結(jié)果兩部分組成。
(2)從訓(xùn)練樣例集中取一樣例,把輸入信息輸入到網(wǎng)絡(luò)中。
(3)分別計(jì)算經(jīng)神經(jīng)元處理后的各層節(jié)點(diǎn)的輸出。
(4)計(jì)算網(wǎng)絡(luò)的實(shí)際輸出和期望輸出的誤差。
(5)從輸出層反向計(jì)算到第一個(gè)隱層,并按照某種能使誤差向減小方向發(fā)展的原則,調(diào)整網(wǎng)絡(luò)中各神經(jīng)元的連接權(quán)值。
(6)對(duì)訓(xùn)練樣例集中的每一個(gè)樣例重復(fù)(3)-(5)的步驟,直到對(duì)整個(gè)訓(xùn)練樣例集的誤差達(dá)到要求時(shí)為止。
•優(yōu)點(diǎn):
–理論基礎(chǔ)牢固,推導(dǎo)過(guò)程嚴(yán)謹(jǐn),物理概念清晰,通用性好等。所以,它是目前用來(lái)訓(xùn)練前饋多層網(wǎng)絡(luò)較好的算法。
•缺點(diǎn):
–BP算法的收斂速度一般來(lái)說(shuō)比較慢;
–BP算法只能收斂于局部最優(yōu)解,不能保證收斂于全局最優(yōu)解;
–當(dāng)隱層元的數(shù)量足夠多時(shí),網(wǎng)絡(luò)對(duì)訓(xùn)練樣本的識(shí)別率很高,但對(duì)測(cè)試樣本的識(shí)別率有可能很差,即網(wǎng)絡(luò)的推廣能力有可能較差。
具體的公式在這里不再給出,因?yàn)橄嚓P(guān)的資料也有很多,可以隨時(shí)查閱。
可以證明:
只需要一個(gè)包含足夠多的神經(jīng)元的因曾,多層前饋網(wǎng)絡(luò)能夠以任意精度逼近任意復(fù)雜度的連續(xù)函數(shù)。而主要的問(wèn)題是:如何設(shè)置隱層神經(jīng)元的個(gè)數(shù)?
考慮采用”試錯(cuò)法“
因?yàn)榍梆伨W(wǎng)絡(luò)具有強(qiáng)大地表示能力,因此BP算法有時(shí)會(huì)出現(xiàn)過(guò)擬合的現(xiàn)象,對(duì)于過(guò)擬合,采用的主要策略是早停和正則化:
早停:將數(shù)據(jù)集分為訓(xùn)練集和驗(yàn)證集,訓(xùn)練集用來(lái)計(jì)算梯度,更新連接權(quán)值和閾值,驗(yàn)證集用來(lái)估計(jì)誤差,若訓(xùn)練集誤差降低但驗(yàn)證集誤差升高,則立即停止訓(xùn)練。返回具有最小驗(yàn)證集誤差的連接權(quán)和閾值。
正則化:在誤差目標(biāo)函數(shù)中增加一個(gè)用來(lái)描述網(wǎng)絡(luò)復(fù)雜度的部分。例如連接權(quán)與閾值的平方和,仍令Ek為第k個(gè)訓(xùn)練樣例上誤差,Wi表示鏈接權(quán)和閾值,則誤差目標(biāo)函數(shù)定義為:

其中λ屬于(0,1),用對(duì)經(jīng)驗(yàn)誤差與網(wǎng)絡(luò)復(fù)雜度這兩項(xiàng)進(jìn)行這種,使用”交叉驗(yàn)證“
2.使用python和機(jī)器學(xué)習(xí)庫(kù)sklearn庫(kù)編程實(shí)現(xiàn):
# coding=utf-8
# 使用Python構(gòu)建ANN
import numpy as np
# 雙曲函數(shù)
def tanh(x):
return np.tanh(x)
# 雙曲函數(shù)的微分
def tanh_deriv(x):
return 1.0 - np.tanh(x) * np.tanh(x)
# 邏輯函數(shù)
def logistics(x):
return 1 / (1+np.exp(-x))
# 邏輯函數(shù)的微分
def logistics_derivative(x):
return logistics(x)*(1-logistics(x))
# 使用類 面向?qū)ο蟮募记?建立ANN
class NeuralNetwork:
# 構(gòu)造函數(shù) layers指的是每層內(nèi)有多少個(gè)神經(jīng)元 layers內(nèi)的數(shù)量表示有幾層
# acvitation 為使用的激活函數(shù)名稱 有默認(rèn)值 tanh 表示使用tanh(x)
def __init__(self,layers,activation='tanh'):
if activation == 'logistic':
self.activation = logistics
self.activation_deriv = logistics_derivative
elif activation == 'tanh':
self.activation = tanh
self.activation = tanh_deriv
self.weight =[]
# len(layers)-1的目的是 輸出層不需要賦予相應(yīng)的權(quán)值
for i in range(1,len(layers) - 1):
# 第一句是對(duì)當(dāng)前層與前一層之間的連線進(jìn)行權(quán)重賦值,范圍在 -0.25 ~ 0.25之間
self.weight.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25)
# 第二句是對(duì)當(dāng)前層與下一層之間的連線進(jìn)行權(quán)重賦值,范圍在 -0.25 ~ 0.25之間
self.weight.append((2*np.random.random((layers[i]+1,layers[i+1]))-1)*0.25)
def fit(self,X,y,learning_rate = 0.2,epochs = 10000):
# self是指引當(dāng)前類的指針 X表示訓(xùn)練集 通常模擬成一個(gè)二維矩陣,每一行代表一個(gè)樣本的不同特征
# 每一列代表不同的樣本 y指的是classLabel 表示的是輸出的分類標(biāo)記
# learning_rate是學(xué)習(xí)率,epochs表示循環(huán)的次數(shù)
X = np.atleast_2d(X)
# 將X轉(zhuǎn)換為numpy2維數(shù)組 至少是2維的
temp = np.ones([X.shape[0],X.shape[1]+1])
# X.shape[0]返回的是X的行數(shù) X.shape[1]返回的是X的列數(shù)
temp[:,0:-1] = X # :指的是所有的行 0:-1指的是從第一列到除了最后一列
X = temp # 偏向的賦值
y = np.array(y) # 將y轉(zhuǎn)換為numpy array的形式
# 使用抽樣的算法 每次隨機(jī)選一個(gè) x中的樣本
for k in range(epochs):
# randint(X.shape[0])指的是從0~X.shape[0] 之間隨機(jī)生成一個(gè)int型的數(shù)字
i = np.random.randint(X.shape[0])
a = [X[i]] # a是從x中任意抽取的一行數(shù)據(jù)
#正向更新
for l in range(len(self.weight)): # 循環(huán)遍歷每一層
# dot是求內(nèi)積的運(yùn)算 將內(nèi)積運(yùn)算的結(jié)果放在非線性轉(zhuǎn)換方程之中
a.append(self.activation(np.dot(a[l], self.weight[l])))
error = y[i] - a[-1] # 求誤差 a[-1]指的是最后一層的classLabel
deltas = [error * self.activation_deriv(a[-1])]
# 開始反向傳播 從最后一層開始,到第0層,每次回退1層
for l in range(len(a) - 2,0,-1):
deltas.append(deltas[-1].dot(self.weight[l].T)*self.activation_deriv(a[l]))
deltas.reverse()
for i in range(len(self.weight)):
layer = np.atleast_2d(a[i])
delta = np.atleast_2d(deltas[i]) # delta存的是誤差
self.weight[i] += learning_rate * layer.T.dot(delta) # 誤差與單元格的值的內(nèi)積
# 預(yù)測(cè)過(guò)程
def predict(self,x):
x=np.array(x)
temp = np.ones(x.shape[0]+1)
temp[0:-1] = x
a = temp
for l in range(0,len(self.weight)):
a = self.activation(np.dot(a,self.weight[l]))
return a
使用簡(jiǎn)單的程序進(jìn)行測(cè)試
# coding=utf-8 from ANN import NeuralNetwork import numpy as np nn = NeuralNetwork([2, 2, 1], 'tanh') X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) y = np.array([0, 1, 1, 0]) nn.fit(X, y) for i in [[0, 0], [0, 1], [1, 0], [1, 1]]: print(i, nn.predict(i))
執(zhí)行后,輸出的結(jié)果為:

End.
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python基礎(chǔ)之類型轉(zhuǎn)換函數(shù)
這篇文章主要介紹了python類型轉(zhuǎn)換函數(shù),實(shí)例分析了Python中返回一個(gè)返回值與多個(gè)返回值的方法,需要的朋友可以參考下2021-10-10
Django項(xiàng)目之Elasticsearch搜索引擎的實(shí)例
今天小編就為大家分享一篇Django項(xiàng)目之Elasticsearch搜索引擎的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08
Python自定義主從分布式架構(gòu)實(shí)例分析
這篇文章主要介紹了Python自定義主從分布式架構(gòu),結(jié)合實(shí)例形式分析了主從分布式架構(gòu)的結(jié)構(gòu)、原理與具體的代碼實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-09-09
如何一分鐘內(nèi)找出pandas DataFrame某列中的nan值
這篇文章主要介紹了如何一分鐘內(nèi)找出pandas DataFrame某列中的nan值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Python 比較兩個(gè)數(shù)組的元素的異同方法
下面小編就為大家?guī)?lái)一篇Python 比較兩個(gè)數(shù)組的元素的異同方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
python sklearn庫(kù)實(shí)現(xiàn)簡(jiǎn)單邏輯回歸的實(shí)例代碼
Scikit-learn(sklearn)是機(jī)器學(xué)習(xí)中常用的第三方模塊,對(duì)常用的機(jī)器學(xué)習(xí)方法進(jìn)行了封裝,這篇文章主要介紹了python sklearn庫(kù)實(shí)現(xiàn)簡(jiǎn)單邏輯回歸的實(shí)例代碼,需要的朋友可以參考下2019-07-07
pyqt5 鍵盤監(jiān)聽按下enter 就登陸的實(shí)例
今天小編就為大家分享一篇pyqt5 鍵盤監(jiān)聽按下enter 就登陸的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
Python實(shí)現(xiàn)桶排序與快速排序算法結(jié)合應(yīng)用示例
這篇文章主要介紹了Python實(shí)現(xiàn)桶排序與快速排序算法結(jié)合應(yīng)用,結(jié)合實(shí)例形式分析了Python快速排序及桶排序結(jié)合應(yīng)用的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-11-11

