1. 程式人生 > >深度學習---反向傳播演算法BP

深度學習---反向傳播演算法BP

這個BP演算法可以多看幾遍,條理清晰

Stanford機器學習---第五講. 神經網路的學習 Neural Networks learning

推導過程:

重點參考必看:

https://blog.csdn.net/fendouaini/article/details/79789440

https://blog.csdn.net/zhongkejingwang/article/details/44514073

https://zhuanlan.zhihu.com/p/24801814

在學習深度學習相關知識,無疑都是從神經網路開始入手,在神經網路對引數的學習演算法bp演算法,接觸了很多次,每一次查詢資料學習,都有著似懂非懂的感覺,這次趁著思路比較清楚,也為了能夠讓一些像我一樣疲於各種查詢資料,卻依然懵懵懂懂的孩子們理解,參考了樑斌老師的部落格

BP演算法淺談(Error Back-propagation)(為了驗證樑老師的結果和自己是否正確,自己python實現的初始資料和樑老師定義為一樣!),進行了梳理和python程式碼實現,一步一步的幫助大家理解bp演算法!

為了方便起見,這裡我定義了三層網路,輸入層(第0層),隱藏層(第1層),輸出層(第二層)。並且每個結點沒有偏置(有偏置原理完全一樣),啟用函式為sigmod函式(不同的啟用函式,求導不同),符號說明如下:

對應網路如下:

其中對應的矩陣表示如下:
首先我們先走一遍正向傳播,公式與相應的資料對應如下:

那麼:

同理可以得到

那麼最終的損失為

我們當然是希望這個值越小越好。這也是我們為什麼要進行訓練,調節引數,使得最終的損失最小。這就用到了我們的反向傳播演算法,實際上反向傳播就是梯度下降法中(為什麼需要用到梯度下降法,也就是為什麼梯度的反方向一定是下降最快的方向,我會再寫一篇文章解釋,這裡假設是對的,關注bp演算法)鏈式法則的使用。

下面我們看如何反向傳播

根據公式,我們有:

這個時候我們需要求出C對w的偏導,則根據鏈式法則有

上面插入sigmod函式求導公式:

(在這裡我們可以看到不同啟用函式求導是不同的,所謂的梯度消失,梯度爆炸如果瞭解bp演算法的原理,也是非常容易理解的!)
同理有

到此我們已經算出了最後一層的引數偏導了.我們繼續往前面鏈式推導:

我們現在還需要求

下面給出其中的一個推到,其它完全類似同理可得到其它幾個式子:

則最終的結果為:

再按照這個權重引數進行一遍正向傳播得出來的Error為0.165

而這個值比原來的0.19要小,則繼續迭代,不斷修正權值,使得代價函式越來越小,預測值不斷逼近0.5.我迭代了100次的結果,Error為5.92944818e-07(已經很小了,說明預測值與真實值非常接近了

),最後的權值為:

好了,bp過程可能差不多就是這樣了,可能此文需要你以前接觸過bp演算法,只是還有疑惑,一步步推導後,會有較深的理解。

下面給出我學習bp時候的好的部落格

Backpropagation (裡面的插圖非常棒,不過好像有點錯誤,歡迎討論~)

上面實現的python程式碼如下:

import numpy as np

def nonlin(x, deriv=False):
	if (deriv == True):
	return x * (1 - x) #如果deriv為true,求導數
	return 1 / (1 + np.exp(-x))

X = np.array([[0.35],[0.9]]) #輸入層
y = np.array([[0.5]]) #輸出值

np.random.seed(1)

W0 = np.array([[0.1,0.8],[0.4,0.6]])
W1 = np.array([[0.3,0.9]])
print 'original ',W0,'\n',W1
for j in xrange(100):
	l0 = X #相當於文章中x0
	l1 = nonlin(np.dot(W0,l0)) #相當於文章中y1
	l2 = nonlin(np.dot(W1,l1)) #相當於文章中y2
	l2_error = y - l2
	Error = 1/2.0*(y-l2)**2
	print "Error:",Error
	l2_delta = l2_error * nonlin(l2, deriv=True) #this will backpack
	#print 'l2_delta=',l2_delta
	l1_error = l2_delta*W1; #反向傳播
	l1_delta = l1_error * nonlin(l1, deriv=True)

	W1 += l2_delta*l1.T; #修改權值
	W0 += l0.T.dot(l1_delta)
	print W0,'\n',W1

推導過程2:

反向傳播演算法(Backpropagation Algorithm,簡稱BP演算法)是深度學習的重要思想基礎,對於初學者來說也是必須要掌握的基礎知識!本文希望以一個清晰的脈絡和詳細的說明,來讓讀者徹底明白BP演算法的原理和計算過程。

全文分為上下兩篇,上篇主要介紹BP演算法的原理(即公式的推導),介紹完原理之後,我們會將一些具體的資料帶入一個簡單的三層神經網路中,去完整的體驗一遍BP演算法的計算過程;下篇是一個專案實戰,我們將帶著讀者一起親手實現一個BP神經網路(不適用任何第三方的深度學習框架)來解決一個具體的問題。

讀者在學習的過程中,有任何的疑問,歡迎加入我們的交流群(掃描文章最後的二維碼即可加入),和大家一起討論!

1.BP演算法的推導


圖1 一個簡單的三層神經網路

圖1所示是一個簡單的三層(兩個隱藏層,一個輸出層)神經網路結構,假設我們使用這個神經網路來解決二分類問題,我們給這個網路一個輸入樣本 ,通過前向運算得到輸出 。輸出值 的值域為 ,例如 的值越接近0,代表該樣本是“0”類的可能性越大,反之是“1”類的可能性大。

1.1前向傳播的計算

為了便於理解後續的內容,我們需要先搞清楚前向傳播的計算過程,以圖1所示的內容為例:

輸入的樣本為:

第一層網路的引數為:

第二層網路的引數為:

第三層網路的引數為:

1.1.1第一層隱藏層的計算


圖2 計算第一層隱藏層

1.1.2第二層隱藏層的計算


圖3 計算第二層隱藏層

1.1.3輸出層的計算


圖4 計算輸出層

即:

單純的公式推導看起來有些枯燥,下面我們將實際的資料帶入圖1所示的神經網路中,完整的計算一遍。

2.圖解BP演算法


圖5 圖解BP演算法

我們依然使用如圖5所示的簡單的神經網路,其中所有引數的初始值如下:

輸入的樣本為(假設其真實類標為“1”):

第一層網路的引數為:

第二層網路的引數為:

第三層網路的引數為:

2.1前向傳播

我們首先初始化神經網路的引數,計算第一層神經元:

2.2誤差反向傳播

接著計算第二層隱藏層的誤差項,根據誤差項的計算公式有:

最後是計算第一層隱藏層的誤差項:

2.3更新引數

上一小節中我們已經計算出了每一層的誤差項,現在我們要利用每一層的誤差項和梯度來更新每一層的引數,權重W和偏置b的更新公式如下:

通常權重W的更新會加上一個正則化項來避免過擬合,這裡為了簡化計算,我們省去了正則化項。上式中的 是學習率,我們設其值為0.1。引數更新的計算相對簡單,每一層的計算方式都相同,因此本文僅演示第一層隱藏層的引數更新:

3.小結

至此,我們已經完整介紹了BP演算法的原理,並使用具體的數值做了計算。在下篇中,我們將帶著讀者一起親手實現一個BP神經網路(不適用任何第三方的深度學習框架),敬請期待!有任何疑問,歡迎加入我們一起交流!