姓名:張博奇
學號:2014301020063
班級:物基一班
摘要:本文利用BP算法思想構建二層神經(jīng)網(wǎng)絡和更復雜的三層神經(jīng)網(wǎng)絡,訓練神經(jīng)網(wǎng)絡根據(jù)輸入數(shù)據(jù)集預測輸出數(shù)據(jù)泻拦,對神經(jīng)網(wǎng)絡的結構有了初步的認識堤如,闡述了權重矩陣(網(wǎng)絡參數(shù))在神經(jīng)網(wǎng)絡中的核心作用蒲列。并在此基礎上用三層神經(jīng)網(wǎng)絡訓練機器學習分類器窒朋,進而預測正確的分類,并討論隱藏層維度對分類結果的大致影響蝗岖。
關鍵詞:神經(jīng)網(wǎng)絡侥猩、預測、機器學習抵赢、權重矩陣
引言
機器學習欺劳,是如今最令人振奮的計算機領域之一。國際著名的互聯(lián)網(wǎng)公司铅鲤,諸如Google划提、Facebook、Apple彩匕、Amazon早已展開了一場關于機器學習的軍備競賽腔剂。從手機上的語音助手、垃圾郵件過濾到逛淘寶時的物品推薦驼仪,無一不用到機器學習技術。2016年在圍棋界大放異彩的AlphaGo也是機器學習的成功案例袜漩。
背景知識
在20世紀下半葉绪爸,機器學習作為人工智能的子領域誕生了,其目標是通過自學習算法從數(shù)據(jù)中獲取知識宙攻,然后對未來世界進行預測奠货。無需借助人力從數(shù)據(jù)中得到規(guī)則,機器學習能夠自動建立模型進行預測座掘。
機器學習是從對大腦的工作原理的研究逐步發(fā)展起來的递惋。Warren McCullock和Walter Pitts 在1943年首次提出了一個簡化版大腦細胞的概念,即McCullock-Pitts(MCP)神經(jīng)元(W.S.McCulloch and W.Pitts. A Logical Calculus of the IdeasImmanent in Nervous Activity.)溢陪。
神經(jīng)元是大腦中內部連接的神經(jīng)細胞萍虽,作用是處理和傳播化學和電信號。McCullock和Pitts描述了如下的神經(jīng)細胞:可以看做帶有兩個輸出的簡單邏輯門形真;即有多個輸入傳遞到樹突(Dentrity)杉编,然后在神經(jīng)元(Cell nucleus)內部進行輸入整合,如果累積的信號量超過某個閾值咆霜,會產(chǎn)生一個輸出信號并且通過軸突(Axon)進行傳遞邓馒。十幾年后,基于MCP神經(jīng)元模型蛾坯,F(xiàn)rank Rosenblatt發(fā)表了第一個感知機學習規(guī)則(F.Rosenblatt, The Perceptron, a Perceiving and Recognizing Automaton. Cornell Aeronautical Laboratory, 1957)光酣。基于此感知機規(guī)則脉课,Rosenblatt提出了能夠自動學習最優(yōu)權重參數(shù)的算法救军,權重即輸入特征的系數(shù)财异。后文中會有具體闡述。
構建二層神經(jīng)網(wǎng)絡
BP算法缤言,即誤差反向傳播(Error Back Propagation, BP)算法宝当。BP算法的基本思想是,學習過程由信號的正向傳播與誤差的反向傳播兩個過程組成胆萧。由于多層前饋網(wǎng)絡的訓練經(jīng)常采用誤差反向傳播算法庆揩,人們也常把將多層前饋網(wǎng)絡直接稱為BP網(wǎng)絡。
下面嘗試著用BP算法訓練的神經(jīng)網(wǎng)絡根據(jù)輸入數(shù)據(jù)預測輸出數(shù)據(jù)跌穗。從二層神經(jīng)開始入手订晌,輸入X和輸出Y數(shù)據(jù)集均以矩陣的形式給出。每一行代表一個訓練樣本(即相當于對大腦施加一次刺激)蚌吸,每一列代表一個輸入結點(即相當于接受刺激的部位)锈拨。l0和l1分別代表輸入網(wǎng)絡層和中間隱藏層,顯然有數(shù)據(jù)集X等于輸入網(wǎng)絡層l0羹唠。syn0表示連接l0和l1層的突觸奕枢,也即上文提到的權重。
取4次訓練樣本[0,0,1],[0,1,1],[1,0,1],[1,1,1]和擬定的輸出結果[0,0,1,1].T代碼如下:
import numpy as np
# sigmoid 函數(shù)
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
# 輸入數(shù)據(jù)集
X = np.array([ [0,0,1],
[0,1,1],
[1,0,1],
[1,1,1] ])
# 輸出數(shù)據(jù)集
y = np.array([[0,0,1,1]]).T
np.random.seed(1)
# 隨機初始化權重并使均值為零
syn0 = 2*np.random.random((3,1)) - 1
for i in range(10000):
l0 = X
l1 = nonlin(np.dot(l0,syn0))
#誤差
l1_error = y - l1
l1_delta = l1_error * nonlin(l1,True)
# 更新權重
syn0 += np.dot(l0.T,l1_delta)
print (l1)
點擊查看代碼
輸出結果為:
[[ 0.00966449]
[ 0.00786506]
[ 0.99358898]
[ 0.99211957]]
從輸出結果可以看出佩微,其值與每個訓練樣本第一個結點的值是相近的缝彬,但第二與第三個結點的作用使得輸出結果有偏差。我們成功地利用輸入的訓練樣本預測了輸出哺眯。
其中谷浅,Sigmoid 函數(shù)
可以將任何值都映射到一個位于 0 到 1 范圍內的值。通過它奶卓,我們可以將實數(shù)轉化為概率值一疯。通過 “nonlin” 函數(shù)體還能得到 sigmod 函數(shù)的導數(shù)(當形參 deriv 為 True 時)。由于Sigmoid函數(shù)是非線性的夺姑,允許我們擬合非線性假設墩邀,類似的函數(shù)還有tanh、ReLUs等瑟幕。
權重syn0是隨機生成的一個3行一列矩陣磕蒲,與輸入X相乘后得到一個數(shù)值,經(jīng)過nolin函數(shù)作用后得到對應的概率值只盹,也就是猜測結果辣往。l1_error則評估預測值l1與初始設定的Y值差值。nolin函數(shù)形參 deriv 為 True 時得到Sigmoid 函數(shù)導數(shù)殖卑。
由上圖可以看出導數(shù)值在X絕對值較大時很小站削,在X絕對值較小時很大,但可以計算其導數(shù)值始終小于1孵稽。這個特性導致l1絕對值很大時其nolin函數(shù)值很小许起,l1_error相乘是一個較小值十偶;l1絕對值很小時其nolin函數(shù)值很大,l1_error相乘是一個較大值园细。從統(tǒng)計學角度而言惦积,我們對較為確定的事件賦予小的權重,對不確定的事件賦予大的權重猛频。將nolin函數(shù)值乘上誤差時狮崩,實際上就在以高確信度減小預測誤差,更新權重后得到更進一步的準確的權重值鹿寻。從這里我們就可以看出睦柴,神經(jīng)網(wǎng)絡的訓練過程,實際上就是對一個隨機權重不斷訓練毡熏,最后使輸入數(shù)據(jù)集在權重的作用下越來越接近輸出值的過程坦敌。神經(jīng)網(wǎng)絡是基于輸入與輸出間的聯(lián)系進行學習的。
構建三層神經(jīng)網(wǎng)絡
在構建二層神經(jīng)網(wǎng)絡時痢法,我們將輸出數(shù)據(jù)集定為[0,0,1,1].T狱窘,但是如果我們將輸出數(shù)據(jù)集改為[0,1,1,0].T,重新執(zhí)行上述代碼财搁,可以發(fā)現(xiàn)輸出的l1為:
[[ 0.5]
[ 0.5]
[ 0.5]
[ 0.5]]
這和我們的擬定輸出數(shù)據(jù)集不一致训柴,神經(jīng)網(wǎng)絡并沒有按照輸入與輸出間的關系預測輸出值。這是因為不一定總是單個輸入與輸出間存在一對一的關系妇拯,也可能是兩個輸入對應一個輸出,甚至更復雜洗鸵。輸入與輸出不一定是呈線性相關越锈。或者說膘滨,輸入的組合與輸出間存在著一對一的關系甘凭。
為了解決這種更復雜的對應關系,需要額外增加一個網(wǎng)絡層火邓。第一層對輸入進行組合丹弱,然后以第一層的輸出作為輸入,通過第二層的映射得到最終的輸出結果铲咨。通過增加更多的中間層躲胳,以對更多關系的組合進行建模。這一策略正是人們所熟知的“深度學習”纤勒。
三層神經(jīng)網(wǎng)絡中坯苹,l0作為輸入層,l1作為中間隱藏層摇天,l2作為輸出層粹湃。增加l2層和連接l1與l2間的權重syn1恐仑,并使l1_error等于l2誤差更新值乘權重(這種做法也稱作“貢獻度加權誤差”),可以寫出三層神經(jīng)網(wǎng)絡的代碼:
import numpy as np
# sigmoid 函數(shù)
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
# 輸入數(shù)據(jù)集
X = np.array([[0,0,1],
[0,1,1],
[1,0,1],
[1,1,1]])
# 輸出數(shù)據(jù)集
y = np.array([[0],
[1],
[1],
[0]])
np.random.seed(1)
# 隨機初始化權重并使均值為零
syn0 = 2*np.random.random((3,5)) - 1
syn1 = 2*np.random.random((5,1)) - 1
for j in range(50000):
l0 = X
l1 = nonlin(np.dot(l0,syn0))
l2 = nonlin(np.dot(l1,syn1))
#l2層
l2_error = y - l2
l2_delta = l2_error*nonlin(l2,deriv=True)
#l1層
l1_error = l2_delta.dot(syn1.T)
l1_delta = l1_error * nonlin(l1,deriv=True)
# 更新權重
syn1 += l1.T.dot(l2_delta)
syn0 += l0.T.dot(l1_delta)
print(l2)
點擊查看代碼
輸出結果為:
[[ 0.00248611]
[ 0.99693818]
[ 0.99597714]
[ 0.00503275]]
可見已經(jīng)較好的得到了與擬定輸出結果相近的預測值为鳄。三層神經(jīng)網(wǎng)絡構建成功裳仆。
利用三層神經(jīng)網(wǎng)絡預測分類
-
產(chǎn)生數(shù)據(jù)集
利用scikit-learn可以產(chǎn)生很多有趣的數(shù)據(jù)集。
這里采用整體較好分辨又具有一定難度分辨全部數(shù)據(jù)集的半月形數(shù)據(jù)集孤钦。
- 構建三層神經(jīng)網(wǎng)絡并訓練機器學習分類器
由于圖形是彎曲的歧斟,我們無法直接畫一條直線以區(qū)分紅點與藍點這兩類數(shù)據(jù)。因此需要構建一個具有輸入層司训、隱藏層构捡、輸出層的三層神經(jīng)網(wǎng)絡來分辨。由于是二維圖像壳猜,輸入結點選擇為兩個勾徽,兩類需要分辨的數(shù)據(jù),輸出結點也選擇為兩個统扳。隱藏層的結點數(shù)不是固定的喘帚,比如在上文構建三層神經(jīng)網(wǎng)絡中選擇了(5×1)矩陣,也就是五結點數(shù)(五維)隱藏層咒钟。結點數(shù)對數(shù)據(jù)篩選的影響會在后面討論吹由。
zi是輸入層、ai是輸出層朱嘴。W1,b1,W2,b2是需要從訓練數(shù)據(jù)中學習的網(wǎng)絡參數(shù)倾鲫,也就是上文提到的權重(矩陣)。依然選擇sigmoid函數(shù)在z1與a1間進行映射萍嬉,z2與a2間則采用Softmax函數(shù)進行映射(Softmax函數(shù)也是轉化成概率的一種方法乌昔,關于Softmax函數(shù)可查看維基百科)。
向前傳播進行預測:
為了找到使誤差函數(shù)最小時權重W1,b1,W2,b2的值壤追,可以使用梯度下降方法磕道,這里采用有固定學習速率的批量梯度下降法。梯度下降需要一個與參數(shù)相關的損失函數(shù)的梯度行冰。先定義:
與參數(shù)相關的損失函數(shù)的梯度:
利用后向傳播導數(shù)實現(xiàn)批量梯度下降溺蕉,進而更新網(wǎng)絡參數(shù)W1,b1,W2,b2,減小誤差悼做。
-
對數(shù)據(jù)集進行分類
運行程序,最終實現(xiàn)了將半月形中藍色數(shù)據(jù)集與紅色數(shù)據(jù)集分離:
點擊查看源代碼
可以看出絕大多數(shù)紅色數(shù)據(jù)集與藍色數(shù)據(jù)集實現(xiàn)了分離贿堰,只有極少數(shù)數(shù)據(jù)集被分在了錯誤的位置辙芍,神經(jīng)網(wǎng)絡能夠找到成功區(qū)分不同數(shù)據(jù)集的決策邊界,數(shù)據(jù)集的分類獲得成功。下面改變隱藏層維度故硅,來評估不同隱藏層維度會對數(shù)據(jù)分離結果造成的影響:
可以看出隱藏層為一維時相當于線性分割兩種數(shù)據(jù)集庶灿,隨著維度增加分割效果得到提高,在隱藏層達到十維時只有一個本方數(shù)據(jù)集被排除在外吃衅,分割效果最好往踢,隱藏層增加到五十維時沒有明顯的變化,這就需要改進算法實現(xiàn)更優(yōu)的數(shù)據(jù)篩選效果徘层,包括采用其他的層間映射函數(shù)峻呕、更有效的梯度計算方法(顯然有固定學習速率的批量梯度下降法不是最高效的方法)、更多層次的神經(jīng)網(wǎng)絡等趣效。
結論
一個基本的三層神經(jīng)網(wǎng)絡由輸入層瘦癌、隱藏層、輸出層構成跷敬,相鄰兩層間由權重矩陣(網(wǎng)絡參數(shù))連接讯私。通過不斷提供訓練樣本,神經(jīng)網(wǎng)絡會學習最優(yōu)權重參數(shù)西傀,從而減小誤差斤寇,利用輸入數(shù)據(jù)建立模型并模擬輸出。輸入層與輸出層結點數(shù)拥褂、隱藏層維度娘锁、層間映射函數(shù)、梯度計算方法都會對神經(jīng)網(wǎng)絡的準確性造成影響饺鹃。本文僅對神經(jīng)網(wǎng)絡與機器學習做了基于個人能力的粗淺分析莫秆,更具有生產(chǎn)力的神經(jīng)網(wǎng)絡遠比本文所述復雜。相信隨著科技的發(fā)展悔详,未來人工智能會豐富每個人的生活馏锡!
致謝
Python機器學習
Implementing a Neural Network from Scratch in Python – An Introduction
Computational Physics, Nicholas J.Giordano, Hisao Nakanishi