高 云,彭 煒
(山西大同大學(xué)計(jì)算機(jī)與網(wǎng)絡(luò)工程學(xué)院,山西大同037009)
人工神經(jīng)網(wǎng)絡(luò)(Artificial Neural Networks,ANN),是模擬生物神經(jīng)網(wǎng)絡(luò)進(jìn)行信息處理的一種數(shù)學(xué)模型。它從信息處理的角度出發(fā),以對大腦的生理研究成果為基礎(chǔ),建立一種簡單模型,按不同的連接方式組成不同的網(wǎng)絡(luò),其作用在于模擬大腦的思考機(jī)制,從而實(shí)現(xiàn)特定的功能[1-2]。
自從1943年, 美國心理學(xué)家McCulloch 和數(shù)學(xué)家Pitts 聯(lián)合提出了形式神經(jīng)元的數(shù)學(xué)模型MP模型, 神經(jīng)網(wǎng)絡(luò)就逐漸成為了一種運(yùn)算模型。它由大量的節(jié)點(diǎn)(或稱神經(jīng)元)之間相互聯(lián)接構(gòu)成, 每個(gè)節(jié)點(diǎn)代表一種特定的稱為激勵(lì)函數(shù)的輸出函數(shù)。每兩個(gè)節(jié)點(diǎn)間的權(quán)重就相當(dāng)于人工神經(jīng)網(wǎng)絡(luò)的記憶, 其輸出則依據(jù)網(wǎng)絡(luò)特征的不同而不同。而網(wǎng)絡(luò)自身通常都是對自然界某種算法或者函數(shù)的逼近, 也可能是對一種邏輯策略的表達(dá)[3]。
經(jīng)過十多年的發(fā)展, 人工神經(jīng)網(wǎng)絡(luò)已經(jīng)取得了很大的進(jìn)展, 其在自動控制、預(yù)測估計(jì)、生物、醫(yī)學(xué)、經(jīng)濟(jì)等各個(gè)領(lǐng)域已成功地解決了許多現(xiàn)代計(jì)算機(jī)難以解決的實(shí)際問題, 表現(xiàn)出了良好的智能特性。
人工神經(jīng)元是人工神經(jīng)網(wǎng)絡(luò)操作的基本信息處理單位,它是人工神經(jīng)網(wǎng)絡(luò)的設(shè)計(jì)基礎(chǔ)[1]。其模型如圖1所示。
圖1 人工神元模型
一個(gè)人工神經(jīng)元對輸入信號X=[x1,x2,…,xm]T的輸出y為y=f(μ+b),其中激活函數(shù)目前使用最廣泛的為Rule函數(shù),Rule函數(shù)表達(dá)形式為:
由于其計(jì)算簡單, 效果更佳, 目前已取代其他激活函數(shù)成為應(yīng)用最廣泛的激活函數(shù)。
隨著人工神經(jīng)網(wǎng)絡(luò)的發(fā)展,也提出了多種不同的學(xué)習(xí)規(guī)則,針對不同結(jié)構(gòu)的網(wǎng)絡(luò),可以選取不同的學(xué)習(xí)算法。而用于解決分類和預(yù)測問題的網(wǎng)絡(luò)中, 通常會選用δ學(xué)習(xí)規(guī)則(誤差校正學(xué)習(xí)算法)。δ學(xué)習(xí)規(guī)則是根據(jù)神經(jīng)網(wǎng)絡(luò)的輸出誤差再去對神經(jīng)元的連接強(qiáng)度(權(quán)值)進(jìn)行修正,是有指導(dǎo)的學(xué)習(xí)[4]。
對權(quán)值的修正為Δwij=ηδjYi,其中η為學(xué)習(xí)率,δj=Tj-Yj為j的偏差,即j的實(shí)際輸出值和期望值之差,是否完成神經(jīng)網(wǎng)絡(luò)的訓(xùn)練常使用誤差函數(shù)E是否小于某一個(gè)設(shè)定的值來衡量。E為衡量實(shí)際輸出向量Yk與期望值向量Tk誤差大小的函數(shù),常采用二乘誤差函數(shù)來定義為:
N為訓(xùn)練樣本個(gè)數(shù)。
BP 神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)算法可以說是目前最成功的也是應(yīng)用最廣泛的神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)算法。BP 神經(jīng)網(wǎng)絡(luò)就是一個(gè)“萬能的模型+誤差修正函數(shù)”,是一種按誤差逆向傳播算法進(jìn)行訓(xùn)練的多層前饋網(wǎng)絡(luò)。每次根據(jù)訓(xùn)練得到的結(jié)果與預(yù)想結(jié)果進(jìn)行誤差分析,進(jìn)而修改權(quán)值和閾值,一步一步得到能輸出和預(yù)想結(jié)果一致的模型。BP 神經(jīng)網(wǎng)絡(luò)模型拓?fù)浣Y(jié)構(gòu)包括輸入層(input),隱層(hide layer)和輸出層(output layer)。
如圖2所示的即為3個(gè)輸入節(jié)點(diǎn),4個(gè)隱層節(jié)點(diǎn),1個(gè)輸出節(jié)點(diǎn)的一個(gè)三層BP神經(jīng)網(wǎng)絡(luò)。
圖2 三層BP神經(jīng)網(wǎng)絡(luò)
BP 算法的學(xué)習(xí)過程由信號的正向傳播與誤差的逆向傳播兩個(gè)過程組成。
如圖3所示的為第j個(gè)基本BP神經(jīng)元,它只具有三個(gè)最基本也是最重要的功能:加權(quán)、求和與轉(zhuǎn)移。
圖3 BP神經(jīng)元
第j個(gè)神經(jīng)元的凈輸入值Sj為:
其中x1,x2,…,xn分別代表來自神經(jīng)元1,2,…,n的輸入;wj1,wj2,…,wjn分別表示神經(jīng)元1,2,…,n與第j個(gè)神經(jīng)元的權(quán)值;bj為閾值;f(.)為傳遞函數(shù);yj為第j個(gè)神經(jīng)元的輸出。X=[x1,x2,…,xn]T,Wj=[wj,wj2,…,wjn], 如果讓x0=1,wj0=bj, 則X=[x0,x1,…,xn]T,Wj=[wj,wj1,…wjn],此時(shí)節(jié)點(diǎn)j的凈輸入值Sj可表示為:
凈輸入值Sj通過f(.)轉(zhuǎn)換后, 得到第j個(gè)神經(jīng)元的輸出yj:
上式中的f(.)不僅是單調(diào)上升函數(shù),而且也一定是有界函數(shù),因?yàn)樯窠?jīng)細(xì)胞傳遞的信號不可能無限增加,一定會有一個(gè)最大值。
設(shè)BP 網(wǎng)絡(luò)的輸入層有n個(gè)節(jié)點(diǎn),隱層有q個(gè)節(jié)點(diǎn), 輸出層有m個(gè)節(jié)點(diǎn), 輸入層與隱層之間的權(quán)值為vki, 隱層與輸出層之間的權(quán)值為wjk[5]。隱層的傳遞函數(shù)為f1(.),輸出層的傳遞函數(shù)為f2(.),則隱層節(jié)點(diǎn)的輸出為(將閾值寫入求和項(xiàng)中):
輸出層節(jié)點(diǎn)的輸出為:
至此BP 網(wǎng)絡(luò)就完成了n維空間向量對m維空間的近似映射[6]。
2.3.1 誤差函數(shù)
用x1,x2,...,xP來表示輸入的P個(gè)學(xué)習(xí)樣本,則第p個(gè)樣本輸入到網(wǎng)絡(luò)后會得到輸出使用平方誤差函數(shù),對于全部的P個(gè)樣本,全局誤差函數(shù)表示為:
2.3.2 輸出層權(quán)值的變化
采用累計(jì)誤差BP 算法調(diào)整權(quán)值wjk, 使全局誤差E變小,即:
式中:η-學(xué)習(xí)率。
定義誤差信號為:
其中第一項(xiàng):
第二項(xiàng):
是輸出層的偏微分。
于是:
由鏈定理得:
于是輸出層各神經(jīng)元的權(quán)值調(diào)整公式為:
2.3.3 隱層權(quán)值的變化
定義誤差信號為:
其中第一項(xiàng):
依鏈定理有:
第二項(xiàng):
是隱層傳遞函數(shù)的偏微分。
于是:
由鏈定理得:
從而得到隱層各神經(jīng)元的權(quán)值調(diào)整公式為:
Scikit-Learn中并沒有神經(jīng)網(wǎng)絡(luò)模型,我們認(rèn)為Python中比較好的神經(jīng)網(wǎng)絡(luò)算法庫是Keras,這是一個(gè)強(qiáng)大而易用的深度學(xué)習(xí)算法庫。
選用了兩組某餐飲業(yè)的部分營業(yè)情況數(shù)據(jù),目的是觀察數(shù)據(jù)量的多少對分類預(yù)測結(jié)果正確性的影響。根據(jù)餐飲銷售量的情況和當(dāng)天對應(yīng)的各項(xiàng)指標(biāo)使用Keras 算法庫建立神經(jīng)網(wǎng)絡(luò)模型, 選取激活函數(shù), 編譯模型, 訓(xùn)練模型, 進(jìn)行分類預(yù)測, 即對應(yīng)天氣情況,周末和促銷情況不同時(shí),銷量會出現(xiàn)“高”、“中”、“低”的變化,最后將模型以混淆矩陣的可視化形式展示出來。
在建立模型之前需要進(jìn)行數(shù)據(jù)導(dǎo)入,但是導(dǎo)入的數(shù)據(jù)格式有時(shí)并不能滿足要進(jìn)行分類預(yù)測數(shù)據(jù)的格式要求, 所以還需將導(dǎo)入數(shù)據(jù)進(jìn)行格式轉(zhuǎn)換,之后才能建立模型,這一過程即為數(shù)據(jù)準(zhǔn)備過程。這里的數(shù)據(jù)準(zhǔn)備不同于數(shù)據(jù)清洗、數(shù)據(jù)規(guī)約等數(shù)據(jù)預(yù)處理工作。
算法中也需要導(dǎo)入pandas 庫, pandas 是基于NumPy 的一種工具,該工具是為了解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。pandas提供了大量能使我們快速便捷地處理數(shù)據(jù)的函數(shù)和方法。它是使Python 成為強(qiáng)大而高效的數(shù)據(jù)分析環(huán)境的重要因素之一。
數(shù)據(jù)存放文件為csv 文件,CSV 是純文本文件,不包含很多格式信息在里面。CSV文件的體積會更小,創(chuàng)建分發(fā)讀取更加方便,適合存放結(jié)構(gòu)化信息,比如記錄的導(dǎo)出,流量統(tǒng)計(jì)等等。
利用pd.read_csv()方法讀取filename 所指定的文件,并重新設(shè)置“序號”列成為index 值,由于需要處理漢字,將編碼設(shè)為“gbk”。
導(dǎo)入數(shù)據(jù)時(shí)由于數(shù)據(jù)是類別標(biāo)簽,要將它轉(zhuǎn)換為數(shù)據(jù), 為了便于理解,這里對于每個(gè)類別標(biāo)簽只考慮兩種分類情況。用 1 來表示“good”,“yes”、“hign”這3個(gè)屬性,用0來表示“bad”,“no”,“l(fā)ow”。
原始數(shù)據(jù)格式如圖4所示。
圖4 原始數(shù)據(jù)模式圖
將導(dǎo)入的數(shù)據(jù)切片處理, 取3 列即“天氣”列,“是否周末”列和“是否有促銷”列中所有的行數(shù)據(jù)為自變量,第4 列(“銷量”)中所有行數(shù)據(jù)為因變量,按照整型識別進(jìn)行數(shù)據(jù)轉(zhuǎn)換。轉(zhuǎn)換后的數(shù)據(jù)格式如圖5所示。
圖5 轉(zhuǎn)換后的數(shù)據(jù)模式圖
建立并訓(xùn)練模型需要keras.models 和keras.layers 庫, 將其導(dǎo)入采用的是Kera 中的序貫?zāi)P?Sequential)。
序貫?zāi)P褪嵌鄠€(gè)網(wǎng)絡(luò)層的線性堆疊, 也就是“一條路走到黑”,通過.add()方法一個(gè)個(gè)的將layer加入模型中。應(yīng)用神經(jīng)網(wǎng)絡(luò)算法進(jìn)行建模,輸入節(jié)點(diǎn)與隱藏節(jié)點(diǎn)的數(shù)目應(yīng)該根據(jù)實(shí)際需要而建立,并不是越多越好。隱層節(jié)點(diǎn)太少會導(dǎo)致模型訓(xùn)練不夠完善,太多又會導(dǎo)致網(wǎng)絡(luò)出現(xiàn)過擬合現(xiàn)象。
因此神經(jīng)網(wǎng)絡(luò)采用了3 個(gè)輸入節(jié)點(diǎn),10 個(gè)隱藏節(jié)點(diǎn)和1個(gè)輸出節(jié)點(diǎn)。激活函數(shù)也是必須考慮的問題之一,激活函數(shù)有很多種,選取時(shí)需要考慮函數(shù)兩側(cè)數(shù)據(jù)層數(shù)據(jù)的特點(diǎn),即一個(gè)模型可以選取不同的激活函數(shù)。在建立輸入層和隱藏層時(shí)使用relu函數(shù)作為激活函數(shù),能夠大幅度提供準(zhǔn)確度。建立隱藏層與輸出層時(shí), 由于是0-1 輸出, 所以使用sigmoid函數(shù)作為激活函數(shù)。
編譯模型時(shí),常見的損失函數(shù)有mean_squared_error、categorical_crossentropy 等。由于我們做的是二元分類, 所以指定損失函數(shù)為binary_crossentropy,模式為binary。另外, 求解方法指定用adam,還有sgd、rmsprop等。
訓(xùn)練模型,學(xué)習(xí)1000次之后進(jìn)行分類預(yù)測。雖然神經(jīng)網(wǎng)絡(luò)的模型實(shí)現(xiàn)方式不同,但是其使用方式大同小異,都是構(gòu)建模型,然后調(diào)用fit 方法來訓(xùn)練模型,調(diào)用predict方法進(jìn)行預(yù)測。
通過對兩組不同的數(shù)據(jù)進(jìn)行分類預(yù)測,發(fā)現(xiàn)在數(shù)據(jù)基本正確的情況下,數(shù)據(jù)量多的一組會表現(xiàn)出更優(yōu)的正確性。
由上可知,Keras實(shí)現(xiàn)分類預(yù)測算法過程如下:
1) 參數(shù)初始化, 導(dǎo)入數(shù)據(jù)并將其轉(zhuǎn)換為所需格式;
2)正確的選取自變量和因變量所在的數(shù)據(jù)區(qū)域,并將其切片;
3)建立模型,根據(jù)實(shí)際問題的規(guī)模選取合適的輸入節(jié)點(diǎn),隱層節(jié)點(diǎn)及輸出節(jié)點(diǎn)的數(shù)目;
4) 根據(jù)實(shí)際問題選取適合的輸入層與輸出層的激活函數(shù);
5)選取合適的損失函數(shù)并編譯模型;
6)訓(xùn)練模型后進(jìn)行分類預(yù)測,得出結(jié)果并對結(jié)果進(jìn)行分析。
模型建立訓(xùn)練后的分類預(yù)測結(jié)果需要通過可視化方式最終呈現(xiàn)給用戶,選取了混淆矩陣圖作為數(shù)據(jù)可視化方式。
由于Python 自身并沒有混淆矩陣可視化函數(shù)能夠直接調(diào)用,所以編寫了cm_plot.py 文件來實(shí)現(xiàn)數(shù)據(jù)的可視化。該文件包括的混淆矩陣可視化函數(shù)具有兩個(gè)參數(shù),分別為分類項(xiàng)與分類預(yù)測結(jié)果,將其放置在python所在位置的site-packages目錄,用戶可以像調(diào)用庫函數(shù)那樣方便的調(diào)用該函數(shù)。
混淆矩陣函數(shù)confusion_matrix 位于sklearn.metrics庫中,將其導(dǎo)入并建立混淆矩陣。
導(dǎo)入作圖庫matplotlib.pyplot,繪制混淆矩陣圖,配色風(fēng)格使用cm.Greens,在官網(wǎng)中有更多的風(fēng)格可以滿足使用者的不同愛好。
繪制混淆矩陣時(shí)需設(shè)置混淆矩陣圖的顏色標(biāo)簽、數(shù)據(jù)標(biāo)簽、坐標(biāo)軸(x、y) 標(biāo)簽等一些可視化屬性,最后將生成的混淆矩陣對象plt返回。
自定義函數(shù)cm_plot.py 編寫完成后, 即可將其使用類庫相同方式進(jìn)行導(dǎo)入,并調(diào)用show()方法顯示混淆矩陣可視化結(jié)果。
兩組數(shù)據(jù)生成的混淆矩陣圖分別如圖6 和圖7所示。
圖6 34數(shù)據(jù)量混淆矩陣圖
圖7 102數(shù)據(jù)量混淆矩陣圖
在數(shù)據(jù)大多正確情況下,根據(jù)所得的混淆矩陣圖看出,檢測樣本34個(gè)時(shí),預(yù)測正確的個(gè)數(shù)為26個(gè),預(yù)測準(zhǔn)確率為76.4%, 較低, 是由于神經(jīng)網(wǎng)絡(luò)訓(xùn)練時(shí)需要較多樣本,而這里是由于訓(xùn)練數(shù)據(jù)較少造成的。當(dāng)檢測樣本增加為102 個(gè)時(shí),預(yù)測正確的個(gè)數(shù)為80 個(gè), 預(yù)測準(zhǔn)確率為78.4%, 也驗(yàn)證了數(shù)據(jù)量的增加會使預(yù)測正確率有一定的上升。
文中數(shù)據(jù)由于比較簡單,并沒有考慮擬合的問題。實(shí)際上,神經(jīng)網(wǎng)絡(luò)的擬合能力很強(qiáng)并容易出現(xiàn)過擬合現(xiàn)象。與傳統(tǒng)的“懲罰項(xiàng)”做法不同,目前神經(jīng)網(wǎng)絡(luò)(尤其是深度神經(jīng)網(wǎng)絡(luò))中流行的防止過擬合的方法是隨機(jī)地讓部分神經(jīng)網(wǎng)絡(luò)節(jié)點(diǎn)休眠。