使用python實現(xiàn)ANN
本文實例為大家分享了python實現(xiàn)ANN的具體代碼,供大家參考,具體內(nèi)容如下
1.簡要介紹神經(jīng)網(wǎng)絡
神經(jīng)網(wǎng)絡是具有適應性的簡單單元組成的廣泛并行互聯(lián)的網(wǎng)絡。它的組織能夠模擬生物神經(jīng)系統(tǒng)對真實世界物體做做出的反應。神經(jīng)網(wǎng)絡的最基本的成分是神經(jīng)元模型,也就是最簡單的神經(jīng)元模型。
“M-P模型”
如上圖所示,神經(jīng)元接收到來自n個其他神經(jīng)元傳遞過來的輸入信號,這些信號通過帶權重的鏈接進行傳遞。神經(jīng)元接收到的總輸入值將與神經(jīng)元的閾值進行比較,然后通過“激活函數(shù)”處理以產(chǎn)生神經(jīng)元的輸出
激活函數(shù):
理想的激活函數(shù)應該是階躍函數(shù),也就是它能夠?qū)⑤斎胫涤成涑蔀檩敵鲋?或1。其中“0”代表神經(jīng)元抑制,“1”代表神經(jīng)元興奮。但是由于階躍函數(shù)不連續(xù)且不可導,因此實際上常常使用sigmoid函數(shù)當做神經(jīng)元的激活函數(shù)。它能夠?qū)⒖赡茉谳^大范圍內(nèi)變化的輸出值擠壓到(0,1)之間這個范圍內(nèi)。因此有時也成為擠壓函數(shù)。常用的sigmoid函數(shù)是回歸函數(shù)
f(x) = 1/(1+e^(-x))
如下圖所示:
感知機:
感知機是最簡單的神經(jīng)網(wǎng)絡,它由兩層神經(jīng)元組成。輸入層接受外界信號后傳遞給輸出層。輸出層是M-P神經(jīng)元。感知機也成為閾值邏輯單元。感知機可以通過采用監(jiān)督學習來逐步增強模式劃分的能力,達到學習的目的。
感知機能夠?qū)崿F(xiàn)簡單的邏輯運算。
一般的,對于給定訓練數(shù)據(jù)集,權重Wi以及閾值θ可以通過學習得到。其中閾值(bias)可以通過學習得到。在輸出神經(jīng)元中,閾值可以看做是一個固定輸入為-1,0的啞結(jié)點,所對應的連接權重為Wn+1,從而使得權重和閾值的學習統(tǒng)一為權重的學習。
感知機的學習規(guī)則非常簡單,對于訓練樣本(X,y),若當前感知機輸出為y',則感知機做如下調(diào)整
其中,η屬于(0,1),稱為“學習率”
若感知機對訓練樣例預測正確,則感知機不發(fā)生變化,否則將根據(jù)錯誤的程度進行權重的調(diào)整。
需要注意的是,感知機只有輸出神經(jīng)元進行激活函數(shù)處理,因此它的學習能力非常有限,也就是因為它只有一層功能神經(jīng)元。
可以證明,若兩類模式實現(xiàn)性可分的,即存在一個超平面可以將他們分開,則利用感知機一定會收斂,可以求得一個權向量。否則,感知機的學習過程將會發(fā)生震蕩,導致參數(shù)難以穩(wěn)定下來,不等求得合適的解。例如,單層感知機不能解決抑或問題。
如果想要解決非線性可分問題,考慮使用多層功能神經(jīng)元。
前饋神經(jīng)網(wǎng)絡
每層神經(jīng)元與下一層神經(jīng)元全互聯(lián),神經(jīng)元之間不存在同層鏈接,也不存在跨曾鏈接。其中輸入層神經(jīng)元有由外界進行輸入,隱藏層與輸出層神經(jīng)元對信號進行加工,最終結(jié)果由輸出層神經(jīng)元進行輸出。輸入層神經(jīng)元僅僅起到接受輸入的功能,并不進行函數(shù)處理。
所謂的神經(jīng)網(wǎng)絡的學習過程,也就是根據(jù)訓練數(shù)據(jù)來調(diào)整神經(jīng)元之間的“連接權”以及每個功能神經(jīng)元的閾值,換句話說,神經(jīng)網(wǎng)絡能夠“學習”到的東西,全部都蘊含在“連接權”與“閾值”之中
BP算法(誤差逆?zhèn)鞑ニ惴ǎ?/p>
BP算法,也成為反向傳播算法
•在感知器算法中我們實際上是在利用理想輸出與實際輸出之間的誤差作為增量來修正權值,然而在多層感知器中,我們只能計算出輸出層的誤差,中間隱層由于不直接與外界連接,其誤差無法估計。
•反向傳播算法(BP算法)的思想:從后向前反向逐層傳播輸出層的誤差,以間接計算隱層的誤差。算法可以分為兩個階段:
–正向過程:從輸入層經(jīng)隱層逐層正向計算各單元的輸出;
–反向過程:由輸出誤差逐層反向計算隱層各單元的誤差,并用此誤差修正前層的權值。
B-P算法的學習過程如下:
(1)選擇一組訓練樣例,每一個樣例由輸入信息和期望的輸出結(jié)果兩部分組成。
(2)從訓練樣例集中取一樣例,把輸入信息輸入到網(wǎng)絡中。
(3)分別計算經(jīng)神經(jīng)元處理后的各層節(jié)點的輸出。
(4)計算網(wǎng)絡的實際輸出和期望輸出的誤差。
(5)從輸出層反向計算到第一個隱層,并按照某種能使誤差向減小方向發(fā)展的原則,調(diào)整網(wǎng)絡中各神經(jīng)元的連接權值。
(6)對訓練樣例集中的每一個樣例重復(3)-(5)的步驟,直到對整個訓練樣例集的誤差達到要求時為止。
•優(yōu)點:
–理論基礎牢固,推導過程嚴謹,物理概念清晰,通用性好等。所以,它是目前用來訓練前饋多層網(wǎng)絡較好的算法。
•缺點:
–BP算法的收斂速度一般來說比較慢;
–BP算法只能收斂于局部最優(yōu)解,不能保證收斂于全局最優(yōu)解;
–當隱層元的數(shù)量足夠多時,網(wǎng)絡對訓練樣本的識別率很高,但對測試樣本的識別率有可能很差,即網(wǎng)絡的推廣能力有可能較差。
具體的公式在這里不再給出,因為相關的資料也有很多,可以隨時查閱。
可以證明:
只需要一個包含足夠多的神經(jīng)元的因曾,多層前饋網(wǎng)絡能夠以任意精度逼近任意復雜度的連續(xù)函數(shù)。而主要的問題是:如何設置隱層神經(jīng)元的個數(shù)?
考慮采用”試錯法“
因為前饋網(wǎng)絡具有強大地表示能力,因此BP算法有時會出現(xiàn)過擬合的現(xiàn)象,對于過擬合,采用的主要策略是早停和正則化:
早停:將數(shù)據(jù)集分為訓練集和驗證集,訓練集用來計算梯度,更新連接權值和閾值,驗證集用來估計誤差,若訓練集誤差降低但驗證集誤差升高,則立即停止訓練。返回具有最小驗證集誤差的連接權和閾值。
正則化:在誤差目標函數(shù)中增加一個用來描述網(wǎng)絡復雜度的部分。例如連接權與閾值的平方和,仍令Ek為第k個訓練樣例上誤差,Wi表示鏈接權和閾值,則誤差目標函數(shù)定義為:
其中λ屬于(0,1),用對經(jīng)驗誤差與網(wǎng)絡復雜度這兩項進行這種,使用”交叉驗證“
2.使用python和機器學習庫sklearn庫編程實現(xiàn):
# coding=utf-8 # 使用Python構建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: # 構造函數(shù) layers指的是每層內(nèi)有多少個神經(jīng)元 layers內(nèi)的數(shù)量表示有幾層 # acvitation 為使用的激活函數(shù)名稱 有默認值 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的目的是 輸出層不需要賦予相應的權值 for i in range(1,len(layers) - 1): # 第一句是對當前層與前一層之間的連線進行權重賦值,范圍在 -0.25 ~ 0.25之間 self.weight.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25) # 第二句是對當前層與下一層之間的連線進行權重賦值,范圍在 -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是指引當前類的指針 X表示訓練集 通常模擬成一個二維矩陣,每一行代表一個樣本的不同特征 # 每一列代表不同的樣本 y指的是classLabel 表示的是輸出的分類標記 # learning_rate是學習率,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的形式 # 使用抽樣的算法 每次隨機選一個 x中的樣本 for k in range(epochs): # randint(X.shape[0])指的是從0~X.shape[0] 之間隨機生成一個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)積的運算 將內(nèi)積運算的結(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)積 # 預測過程 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
使用簡單的程序進行測試
# 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.
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Python推導式簡單示例【列表推導式、字典推導式與集合推導式】
這篇文章主要介紹了Python推導式,結(jié)合簡單實例形式分析了Python列表推導式、字典推導式與集合推導式基本使用方法,需要的朋友可以參考下2018-12-12pandas dataframe中雙中括號和單中括號的區(qū)別及說明
這篇文章主要介紹了pandas dataframe中雙中括號和單中括號的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08Python3.4 tkinter,PIL圖片轉(zhuǎn)換
我們給大家整理了關于Python3.4 tkinter,PIL圖片轉(zhuǎn)換的相關完整代碼,大家可以學習測試下。2018-06-06如何使用 Python和 FFmpeg 批量截圖視頻到各自文件夾中
wxPython 提供了一個簡單易用的界面,而 FFmpeg 則負責處理視頻幀的提取,這個工具不僅對視頻編輯工作有幫助,也為批量處理視頻文件提供了極大的便利,這篇文章主要介紹了使用 Python和 FFmpeg 批量截圖視頻到各自文件夾中,需要的朋友可以參考下2024-08-08sublime3之內(nèi)網(wǎng)安裝python插件Anaconda的流程
這篇文章主要介紹了sublime3之內(nèi)網(wǎng)安裝python插件Anaconda的流程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11