背景
反向傳播訓練(Backpropagation)一個神經網路是一種常見的方法。網上並不缺少介紹反向傳播是如何工作的論文。但很少包括一個用實際數字的例子。這篇文章是我試圖解釋它是如何工作的和一個具體的例子。
大家可以對比自己的計算,以確保他們正確理解反向傳播。
Python 實現反向傳播演算法
您可以到 Github 嘗試我寫的一個反向傳播演算法Python指令碼。
反向傳播演算法視覺化
一個互動式視覺化顯示神經網路學習過程, 可以看看我的神經網路視覺化網站。
額外的資源
果你發現本教程有用,想繼續學習神經網路及其應用,我強烈推薦看看Adrian Rosebrock的優秀教程Getting Started with Deep Learning and Python
概述
對於本教程,我們將使用一個有 2 個輸入神經元、2 個隱藏的神經元和 2 個輸出神經元的神經網路。此外,隱藏層和輸出層將包括一個 偏差神經元(Bias)。
這裡的基本結構:
為了一些數字,這是初始權重,偏差,和訓練輸入/輸出:
反向傳播的目標是優化神經網路的權重,這樣神經網路可以學習如何正確將任意輸入對映到輸出。
本教程的剩餘部分我們要處理一個訓練集:給定輸入0.05和0.10,我們希望神經網路輸出0.01和0.99。
前向傳播
讓我們看看目前神經網路給定的偏差、權重和輸入的0.05和0.10。為此我們要養活這些輸入提前雖然網路。
我們算出每個隱藏神經元的總輸入,再利用總輸入作為啟用函式(這裡我們使用 Sigmoid 函式)的變數,然後在輸出層神經元重複這一步驟。
這是我們如何計算h1
總輸入:
然後使用 Sigmoid 函式計算h1
輸出:
同理得h2
輸出:
我們對輸出層神經元重複這個過程,使用隱層神經元的輸出作為輸入。
這是o1
的輸出:
同理得o2
輸出:
計算總誤差
我們現在可以計算每個輸出神經元平方誤差和:
例如,o1
預期輸出為 0.01,但實際輸出為0.75136507,因此他的誤差是:
重複這個過程得到o2
(預期輸出是0.99)的誤差是
因此,神經網路的總誤差為
反向傳播過程
反向傳播的目標是更新連線的權重以使每個神經元的實際輸出更加接近預期輸出,從而減少每個神經元以及整個網路的誤差。
輸出層
考慮一下ω5
,我們希望知道ω5
的改變對誤差的影響有大多,稱為
(誤差對ω5
求偏導數)
根據我們所知道的鏈式法則得出:
視覺化我們所做的事情
我們需要弄清楚這個等式的每一部分。
首先,o1
的輸出變化對總誤差的影響有多大?
我們用總誤差對求偏導數時,的值變為 0 ,因為 不會影響
o2
的誤差。
下一步,o1
總輸入的變化對於o1
的輸出的影響有多大?
最後,計算 ω5
的變化對o1
總輸入的影響有多大?
將這三者放在一起:
Delta規則——權值的修正量等於誤差乘以輸入
我們也可以將這個計算過程組合成 δ規則 的形式:
(1)
令 (2)
因為
所以 (3)聯立(1)(2)(3)得
為了減少誤差,我們從當前權重減去這個值(學習率可自定義,這裡我們設定為0.5):
重複這個過程,我們可以得到權重 ω6
, ω7
, 和 ω8
:
我們在得到新的隱藏層神經元的輸入權重之後再更新 ω6
, ω7
, 和 ω8
(也就是說,在進行反向傳播的時候我們使用舊的權重值)
隱藏層
接下來,我們將繼續向後傳播,計算新值ω1
, ω2
, ω3
, 和 ω4
。
全域性來說,我們需要計算
視覺化:
我們要用類似計算輸出層那樣的過程,但略有不同的是:每個隱層神經元的輸出會對多個輸出神經元的輸出和誤差產生印象。我們知道out_h1
將同時影響out_o1
和out_o2
(為方便表示,這裡用下劃線表示下標,下同)。因此需要同時考慮out_h1
對每個輸出神經元的影響:
先從 開始:
我們之前計算過:
然後=ω5
,因為:
講兩者代入 得:
同理得:
因此,
現在我們計算好了。
然後我們計算:
接下來我們計算h1
的總輸入對ω1
求偏導數:
綜上所述,
你也可以這麼寫
現在我們可以更新ω1
了:
重複該過程計算 ω1
, ω2
, 和 ω3
:
最後,我們已經更新所有的權重! 我們最初提出 0.05 和 0.1 的輸入,網路上的誤差為 0.298371109 。第一輪反向傳播之後,現在總誤差降至 0.291027924 。它可能看起來沒有調整太多。但是在這個過程重複 10000 次之後,比如說,誤差降到0.000035085。在這一時刻,當我們輸入0.05和0.1時,兩個輸出神經元分別輸出0.015912196 ( vs 預期 0.01) and 0.984065734 (vs 預期 0.99) 。
如果你做到這一步,發現任何錯誤或者能想到更通俗易懂的說明方法,請加我公眾號 jinkey-love 交流。