生活随笔
收集整理的這篇文章主要介紹了
机器学习-预测之BP神经网络模型原理及实战
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
BP神經網絡模型
簡介
BP網絡(Back-Propagation Network)是1986年被提出的,是一種按誤差逆向傳播算法訓練的多層前饋網絡,是目前應用最廣泛的神經網絡模型之一,用于函數逼近、模型識別分類、數據壓縮和時間序列預測等。
BP網絡又稱為反向傳播神經網絡,它是一種有監督的學習算法,具有很強的自適應、自學習、非線性映射能力,能較好地解決數據少、信息貧、不確定性問題,且不受非線性模型的限制。一個典型的BP網絡應該包括三層:輸入層、隱含層和輸出層。(關于神經網絡的基礎術語等知識可以查看我之前的博客)各層之間全連接,同層之間無連接。隱含層可以有很多層,對于一般的神經網絡而言,單層的隱含層已經足夠了。上圖是一個典型的BP神經網絡結構圖。
學習過程
正向傳播
輸入信號從輸入層經過各個隱含層向輸出層傳播從,在輸出層得到實際的響應值,若實際值與期望值誤差較大,就會轉入誤差反向傳播階段。
反向傳播
按照梯度下降的方法從輸出層經過各個隱含層并逐層不斷地調整各神經元的連接權值和閾值,反復迭代,直到網絡輸出的誤差減少到可以接受的程度,或者進行到預先設定的學習次數。
BP神經網絡通過有指導的學習方式進行訓練和學習。標準的BP算法采用誤差函數按梯度下降的方法學習,使網絡的設計輸出值和期望輸出值之間的均方誤差最小。BP神經網絡的傳輸函數通常采用sigmoid函數,而輸出層則采用線性傳輸函數。
原理
輸入輸出層的設計
- 輸入層
- 輸入層各神經元負責接收來自外界的輸入信息,并傳遞給中間層各神經元,它的節點數為輸入變量的個數。
- 輸出層
- 輸出層向外界輸出信息處理結果。它的節點個數為輸出變量的個數。
隱含層設計
- 內部信息處理層,負責信息變換,根據信息變換能力的需求,中間層可以設計為單隱層或多隱層結構;最后一個隱含層傳遞信息到輸出層各神經元,經過進一步處理后,完成一次學習的正向傳播處理過程。
- 有關研究表明,一個隱含層的神經網絡,只要隱節點足夠多,就可以以任意精度逼近一個非線性函數。因此,通常采用含有一個隱層的三層多輸入單輸出的BP神經網絡建立預測模型。
- 在網絡設計過程中,隱層神經元數的確定十分重要。隱層神經元數目過多,會加大網絡計算量并容易產生過度擬合問題;神經元數目過少,則會影響網絡性能,達不到預期效果。網絡中隱層神經元的數目與實際問題的復雜程度、輸入和輸出層的神經元數及對期望誤差的設定有著直接的關系。目前,對于隱層的神經元數目的確定沒有明確的公式,只有一些基于經驗的公式,神經元的個數最終需要根據經驗和多次試驗確定。
L=n+m+aL= \sqrt {n+m} + aL=n+m?+a
其中,n為輸入層神經元個數,m為輸出層神經元個數,a為1到10之間的常數。
BP算法改進
雖然BP神經網絡具有高度非線性和較強的泛化能力,但也存在收斂速度慢、迭代步數多、易陷入局部極小和全局搜索能力差等缺點。可以采用增加動量項、自適應調節學習率、引入陡度因子等方法進行改進。
- 增加動量項
- 加速算法收斂
- wij=wij?η1×δij×xi+α?wijw_{ij} = w_{ij} - \eta_1 \times \delta_{ij}\times x_i + \alpha ?w_{ij}wij?=wij??η1?×δij?×xi?+α?wij?
- 其中,動量因子α\alphaα一般為0.1~0.8。
- 自適應調節率
- 引入陡度因子
實戰
案例使用神經網絡預測公路運量。
過程
- 劃分訓練集和驗證集
- 建立模型,設定模型參數
- 對模型進行訓練并可視化損失函數變化
- 模型驗證并使用(觀察預測值和真實值對比)
可以看到,效果還是很顯著的。
import numpy
as np
import matplotlib
.pyplot
as plt
def logsig(x
):"""定義激活函數:param x::return:"""return 1/(1+np
.exp
(-x
))def get_Data():"""讀入數據,轉為歸一化矩陣:return:"""population
= [20.55, 22.44, 25.37, 27.13, 29.45, 30.10, 30.96, 34.06, 36.42, 38.09, 39.13, 39.99, 41.93, 44.59,47.30, 52.89, 55.73, 56.76, 59.17, 60.63]vehicle
= [0.6, 0.75, 0.85, 0.9, 1.05, 1.35, 1.45, 1.6, 1.7, 1.85, 2.15, 2.2, 2.25, 2.35, 2.5, 2.6, 2.7, 2.85, 2.95,3.1]roadarea
= [0.09, 0.11, 0.11, 0.14, 0.20, 0.23, 0.23, 0.32, 0.32, 0.34, 0.36, 0.36, 0.38, 0.49, 0.56, 0.59, 0.59,0.67, 0.69, 0.79]passengertraffic
= [5126, 6217, 7730, 9145, 10460, 11387, 12353, 15750, 18304, 19836, 21024, 19490, 20433, 22598,25107, 33442, 36836, 40548, 42927, 43462]freighttraffic
= [1237, 1379, 1385, 1399, 1663, 1714, 1834, 4322, 8132, 8936, 11099, 11203, 10524, 11115, 13320,16762, 18673, 20724, 20803, 21804]samplein
= np
.mat
([population
, vehicle
, roadarea
]) sampleinminmax
= np
.array
([samplein
.min(axis
=1).T
.tolist
()[0], samplein
.max(axis
=1).T
.tolist
()[0]]).transpose
()sampleout
= np
.mat
([passengertraffic
, freighttraffic
]) sampleoutminmax
= np
.array
([sampleout
.min(axis
=1).T
.tolist
()[0], sampleout
.max(axis
=1).T
.tolist
()[0]]).transpose
()sampleinnorm
= (2 * (np
.array
(samplein
.T
) - sampleinminmax
.transpose
()[0]) / (sampleinminmax
.transpose
()[1] - sampleinminmax
.transpose
()[0]) - 1).transpose
()sampleoutnorm
= (2 * (np
.array
(sampleout
.T
).astype
(float) - sampleoutminmax
.transpose
()[0]) / (sampleoutminmax
.transpose
()[1] - sampleoutminmax
.transpose
()[0]) - 1).transpose
()noise
= 0.03 * np
.random
.rand
(sampleoutnorm
.shape
[0], sampleoutnorm
.shape
[1])sampleoutnorm
+= noise
return samplein
, sampleout
, sampleinminmax
, sampleoutminmax
, sampleinnorm
, sampleoutnorm
def model_create():"""建立模型并訓練:return:"""maxepochs
= 60000learnrate
= 0.035errorfinal
= 0.65 * 10 ** (-3)samnum
= 20indim
= 3outdim
= 2hiddenunitnum
= 8w1
= 0.5 * np
.random
.rand
(hiddenunitnum
, indim
) - 0.1b1
= 0.5 * np
.random
.rand
(hiddenunitnum
, 1) - 0.1w2
= 0.5 * np
.random
.rand
(outdim
, hiddenunitnum
) - 0.1b2
= 0.5 * np
.random
.rand
(outdim
, 1) - 0.1errhistory
= []samplein
, sampleout
, sampleinminmax
, sampleoutminmax
, sampleinnorm
, sampleoutnorm
= get_Data
()for i
in range(maxepochs
):hiddenout
= logsig
((np
.dot
(w1
, sampleinnorm
).transpose
() + b1
.transpose
())).transpose
()networkout
= (np
.dot
(w2
, hiddenout
).transpose
() + b2
.transpose
()).transpose
()err
= sampleoutnorm
- networkoutsse
= sum(sum(err
** 2))errhistory
.append
(sse
)if sse
< errorfinal
:breakdelta2
= errdelta1
= np
.dot
(w2
.transpose
(), delta2
) * hiddenout
* (1 - hiddenout
)dw2
= np
.dot
(delta2
, hiddenout
.transpose
())db2
= np
.dot
(delta2
, np
.ones
((samnum
, 1)))dw1
= np
.dot
(delta1
, sampleinnorm
.transpose
())db1
= np
.dot
(delta1
, np
.ones
((samnum
, 1)))w2
+= learnrate
* dw2b2
+= learnrate
* db2w1
+= learnrate
* dw1b1
+= learnrate
* db1errhistory10
= np
.log10
(errhistory
)minerr
= min(errhistory10
)plt
.plot
(errhistory10
)plt
.plot
(range(0, i
+ 1000, 1000), [minerr
] * len(range(0, i
+ 1000, 1000)))ax
= plt
.gca
()ax
.set_yticks
([-2, -1, 0, 1, 2, minerr
])ax
.set_yticklabels
([u
'$10^{-2}$', u
'$10^{-1}$', u
'$10^{1}$', u
'$10^{2}$', str(('%.4f' % np
.power
(10, minerr
)))])ax
.set_xlabel
('iteration')ax
.set_ylabel
('error')ax
.set_title
('Error Histroy')plt
.savefig
('errorhistory.png', dpi
=700)plt
.close
()hiddenout
= logsig
((np
.dot
(w1
, sampleinnorm
).transpose
() + b1
.transpose
())).transpose
()networkout
= (np
.dot
(w2
, hiddenout
).transpose
() + b2
.transpose
()).transpose
()diff
= sampleoutminmax
[:, 1] - sampleoutminmax
[:, 0]networkout2
= (networkout
+ 1) / 2networkout2
[0] = networkout2
[0] * diff
[0] + sampleoutminmax
[0][0]networkout2
[1] = networkout2
[1] * diff
[1] + sampleoutminmax
[1][0]sampleout
= np
.array
(sampleout
)fig
, axes
= plt
.subplots
(nrows
=2, ncols
=1, figsize
=(12, 10))line1
, = axes
[0].plot
(networkout2
[0], 'k', marker
=u
'$\circ$')line2
, = axes
[0].plot
(sampleout
[0], 'r', markeredgecolor
='b', marker
=u
'$\star$', markersize
=9)axes
[0].legend
((line1
, line2
), ('simulation output', 'real output'), loc
='upper left')yticks
= [0, 20000, 40000, 60000]ytickslabel
= [u
'$0$', u
'$2$', u
'$4$', u
'$6$']axes
[0].set_yticks
(yticks
)axes
[0].set_yticklabels
(ytickslabel
)axes
[0].set_ylabel
(u
'passenger traffic$(10^4)$')xticks
= range(0, 20, 2)xtickslabel
= range(1990, 2010, 2)axes
[0].set_xticks
(xticks
)axes
[0].set_xticklabels
(xtickslabel
)axes
[0].set_xlabel
(u
'year')axes
[0].set_title
('Passenger Traffic Simulation')line3
, = axes
[1].plot
(networkout2
[1], 'k', marker
=u
'$\circ$')line4
, = axes
[1].plot
(sampleout
[1], 'r', markeredgecolor
='b', marker
=u
'$\star$', markersize
=9)axes
[1].legend
((line3
, line4
), ('simulation output', 'real output'), loc
='upper left')yticks
= [0, 10000, 20000, 30000]ytickslabel
= [u
'$0$', u
'$1$', u
'$2$', u
'$3$']axes
[1].set_yticks
(yticks
)axes
[1].set_yticklabels
(ytickslabel
)axes
[1].set_ylabel
(u
'freight traffic$(10^4)$')xticks
= range(0, 20, 2)xtickslabel
= range(1990, 2010, 2)axes
[1].set_xticks
(xticks
)axes
[1].set_xticklabels
(xtickslabel
)axes
[1].set_xlabel
(u
'year')axes
[1].set_title
('Freight Traffic Simulation')fig
.savefig
('simulation.png', dpi
=500, bbox_inches
='tight')plt
.show
()if __name__
== '__main__':model_create
()
補充說明
參考書《Python3數據分析與機器學習實戰》,具體數據集和代碼可以查看我的GitHub,歡迎star或者fork。
總結
以上是生活随笔為你收集整理的机器学习-预测之BP神经网络模型原理及实战的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。