深度學習基石:一篇文章理解反向傳播

https://blog.csdn.net/goldfish288/article/details/79835550php

原文地址:https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/web

 

逐步反向傳播示例

背景

反向傳播是訓練神經網絡的經常使用方法,以前對此一直了解的不夠完全,這篇文章算是讓我完全搞懂了反向傳播的細節。算法

概觀

對於本教程,咱們將使用具備兩個輸入,兩個隱藏的神經元,兩個輸出神經元的神經網絡。此外,隱藏和輸出神經元將包括一個偏見。網絡

基本結構以下:併發

neural_network(7)

爲了使用一些數字,下面是最初的權重,偏見和培訓輸入/輸出:wordpress

neural_network(9)

反向傳播的目標是優化權重,以便神經網絡能夠學習如何正確映射任意輸入到輸出。函數

對於本教程的其他部分,咱們將使用單個訓練集:給定輸入0.05和0.10,咱們但願神經網絡輸出0.01和0.99。學習

前進通行證

首先,讓咱們看看神經網絡目前預測的是什麼,給定0.05和0.10的權重和誤差。爲此,咱們將經過網絡向前饋送這些輸入。優化

咱們計算出淨輸入總到每一個隱藏層神經元,壁球使用的總淨輸入激活功能(在這裏咱們使用的邏輯功能),而後重複上述過程與輸出層的神經元。.net

總淨輸入也被稱爲只是 淨輸入一些消息來源

如下是咱們計算總淨投入的方法H_1

net_ {h1} = w_1 * i_1 + w_2 * i_2 + b_1 * 1

net_ {h1} = 0.15 * 0.05 + 0.2 * 0.1 + 0.35 * 1 = 0.3775

而後咱們使用邏輯函數對其進行壓縮以得到如下輸出H_1

out_ {h1} = \ frac {1} {1 + e ^ { -  net_ {h1}}} = \ frac {1} {1 + e ^ { -  0.3775}} = 0.593269992

執行相同的過程,H_2咱們獲得:

out_ {h2} = 0.596884378

咱們重複這個過程爲輸出層神經元,使用隱藏層神經元的輸出做爲輸入。

如下是輸出O-1

net_ {o1} = w_5 * out_ {h1} + w_6 * out_ {h2} + b_2 * 1

net_ {o1} = 0.4 * 0.593269992 + 0.45 * 0.596884378 + 0.6 * 1 = 1.105905967

out_ {o1} = \ frac {1} {1 + e ^ { -  net_ {o1}}} = \ frac {1} {1 + e ^ { -  1.105905967}} = 0.75136507

並執行相同的過程,0-2咱們獲得:

out_ {o2} = 0.772928465

計算總偏差

如今咱們可使用平方偏差函數來計算每一個輸出神經元的偏差,並將它們相加獲得總偏差:

E_ {total} = \ sum \ frac {1} {2}(目標 - 輸出)^ {2}

有些來源將目標稱爲 理想,而輸出 則以實際爲目標。
\壓裂{1} {2}是包括的,以便指數在咱們稍後區分時被取消。不管如何,結果最終會乘以學習率,因此咱們在這裏引入一個常數並不重要[  1 ]。

例如,目標輸出爲O-10.01,但神經網絡輸出爲0.75136507,所以其偏差爲:

E_ {o1} = \ frac {1} {2}(target_ {o1} -out_ {o1})^ {2} = \ frac {1} {2}(0.01-0.75136507)^ {2} = 0.274811083

重複這個過程0-2(記住目標是0.99),咱們獲得:

E_ {o2} = 0.023560026

神經網絡的總偏差是這些偏差的總和:

E_ {total} = E_ {o1} + E_ {o2} = 0.274811083 + 0.023560026 = 0.298371109

向後傳遞

咱們使用反向傳播的目標是更新網絡中的每一個權重,使它們使實際輸出更接近目標輸出,從而最大限度地減小每一個輸出神經元和整個網絡的偏差。

輸出層

考慮一下的例句。咱們想知道變化的例句會影響總偏差,也就是說\ frac {\ partial E_ {total}} {\ partial w_ {5}}

\ frac {\ partial E_ {total}} {\ partial w_ {5}}讀做「部分的衍生物 E_ {}總相對於 W_ {5}」。你也能夠說「關於梯度 W_ {5}」。

經過應用鏈式規則,咱們知道:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = \ frac {\ partial E_ {total}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\部分net_ {o1}} * \ frac {\ partial net_ {o1}} {\ partial w_ {5}}

在視覺上,這是咱們正在作的事情:

output_1_backprop(4)

咱們須要找出這個方程中的每一部分。

首先,總偏差相對於輸出的變化有多大?

E_ {total} = \ frac {1} {2}(target_ {o1} -out_ {o1})^ {2} + \ frac {1} {2}(target_ {o2}  -  out_ {o2})^ { 2}

\ frac {\ partial E_ {total}} {\ partial out_ {o1}} = 2 * \ frac {1} {2}(target_ {o1}  -  out_ {o1})^ {2-1} * -1 + 0

\ frac {\ partial E_ {total}} {\ partial out_ {o1}} =  - (target_ {o1}  -  out_ {o1})=  - (0.01  -  0.75136507)= 0.74136507

- (目標出) 有時表達爲  超出目標
當咱們取總誤差的偏導數時 OUT_ {} O1,數量 \ frac {1} {2}(target_ {o2}  -  out_ {o2})^ {2}變爲零,由於 OUT_ {} O1它不影響它,這意味着咱們正在取一個常數爲零的導數。

接下來,O-1相對於其總淨投入的變化輸出多少?

邏輯函數的偏導數是輸出乘以1減去輸出:

out_ {o1} = \ frac {1} {1 + e ^ { -  net_ {o1}}}

(1-out_ {o1})= 0.75136507(1-0.75136507)= 0.186815602

最後,關於O1變化的總淨投入是的例句多少?

net_ {o1} = w_5 * out_ {h1} + w_6 * out_ {h2} + b_2 * 1

\ frac {\ partial net_ {o1}} {\ partial w_ {5}} = 1 * out_ {h1} * w_5 ^ {(1-1)} + 0 + 0 = out_ {h1} = 0.593269992

把它放在一塊兒:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = \ frac {\ partial E_ {total}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\部分net_ {o1}} * \ frac {\ partial net_ {o1}} {\ partial w_ {5}}

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = 0.74136507 * 0.186815602 * 0.593269992 = 0.082167041

您常常會看到以delta規則的形式組合這個計算:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} =  - (target_ {o1}  -  out_ {o1})* out_ {o1}(1  -  out_ {o1})* out_ {h1}

或者,咱們有\ frac {\ partial E_ {total}} {\ partial out_ {o1}}\ frac {\ partial out_ {o1}} {\ partial net_ {o1}}能夠寫成\ frac {\ partial E_ {total}} {\ partial net_ {o1}},又名\ delta_ {O1}(希臘字母三角洲)aka 節點三角洲。咱們能夠用它來重寫上面的計算:

\ delta_ {o1} = \ frac {\ partial E_ {total}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\ partial net_ {o1}} = \ frac {\ partial E_ {total}} {\ partial net_ {o1}}

\ delta_ {o1} =  - (target_ {o1}  -  out_ {o1})* out_ {o1}(1  -  out_ {o1})

所以:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = \ delta_ {o1} out_ {h1}

有些來源提取負號,\三角洲因此它會寫成:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} =  -  \ delta_ {o1} out_ {h1}

爲了減小偏差,咱們從當前權重中減去這個值(可選地乘以一些學習率eta,咱們將其設置爲0.5):

w_5 ^ {e} * \ frac {\ partial E_ {total}} {\ partial w_ {5}} = 0.4  -  0.5 * 0.082167041 = 0.35891648

有些  來源使用 \α(alpha)來表示學習率, 其餘來源使用  \ ETA(eta), 其餘使用 \小量(epsilon)。

咱們能夠重複這個過程當中得到新的權重w_6w_7以及w_8

w_6 ^ {+} = 0.408666186

w_7 ^ {+} = 0.511301270

w_8 ^ {+} = 0.561370121

咱們將新權重引入隱含層神經元以後,咱們執行神經網絡中的實際更新(即,當咱們繼續下面的反向傳播算法時,咱們使用原始權重,而不是更新的權重)。

隱藏層

接下來,咱們將繼續爲新的計算值,向後傳遞W_1W_2w_3,和W_4

大圖片,這是咱們須要弄清楚的:

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = \ frac {\ partial E_ {total}} {\ partial out_ {h1}} * \ frac {\ partial out_ {h1}} {\ partial net_ {h1}} * \ frac {\ partial net_ {h1}} {\ partial w_ {1}}

視覺:

NN-計算

咱們將使用與輸出層相似的過程,但略有不一樣,以說明每一個隱藏層神經元的輸出對多個輸出神經元的輸出(並所以產生偏差)的貢獻。咱們知道這OUT_ {} H1影響到二者OUT_ {} O1OUT_ {} O2所以\ frac {\ partial E_ {total}} {\ partial out_ {h1}}須要考慮它對兩個輸出神經元的影響:

\ frac {\ partial E_ {total}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial out_ {h1}} + \ frac {\ partial E_ {o2}} {\部分out_ {h1}}

從如下開始\ frac {\ partial E_ {o1}} {\ partial out_ {h1}}

\ frac {\ partial E_ {o1}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial net_ {o1}} * \ frac {\ partial net_ {o1}} {\部分out_ {h1}}

咱們能夠\ frac {\ partial E_ {o1}} {\ partial net_ {o1}}使用咱們以前計算的值來計算:

\ frac {\ partial E_ {o1}} {\ partial net_ {o1}} = \ frac {\ partial E_ {o1}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\部分net_ {o1}} = 0.74136507 * 0.186815602 = 0.138498562

而且\ frac {\ partial net_ {o1}} {\ partial out_ {h1}}等於的例句

net_ {o1} = w_5 * out_ {h1} + w_6 * out_ {h2} + b_2 * 1

\ frac {\ partial net_ {o1}} {\ partial out_ {h1}} = w_5 = 0.40

將它們插入:

\ frac {\ partial E_ {o1}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial net_ {o1}} * \ frac {\ partial net_ {o1}} {\部分out_ {h1}} = 0.138498562 * 0.40 = 0.055399425

按照相同的過程\ frac {\ partial E_ {o2}} {\ partial out_ {h1}},咱們獲得:

\ frac {\ partial E_ {o2}} {\ partial out_ {h1}} = -0.019049119

所以:

\ frac {\ partial E_ {total}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial out_ {h1}} + \ frac {\ partial E_ {o2}} {\部分out_ {h1}} = 0.055399425 + -0.019049119 = 0.036350306

如今,咱們有\ frac {\ partial E_ {total}} {\ partial out_ {h1}},咱們須要弄清楚\ frac {\ partial out_ {h1}} {\ partial net_ {h1}},而後\ frac {\ partial net_ {h1}} {\ partial w}每個權重:

out_ {h1} = \ frac {1} {1 + e ^ { -  net_ {h1}}}

(1  -  0.59326999)= 0.241300709(1  -  out_ {h1})= 0.59326999

咱們計算總淨投入的偏導數,H_1W_1咱們對輸出神經元所作的相同:

net_ {h1} = w_1 * i_1 + w_3 * i_2 + b_1 * 1

\ frac {\ partial net_ {h1}} {\ partial w_1} = i_1 = 0.05

把它放在一塊兒:

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = \ frac {\ partial E_ {total}} {\ partial out_ {h1}} * \ frac {\ partial out_ {h1}} {\ partial net_ {h1}} * \ frac {\ partial net_ {h1}} {\ partial w_ {1}}

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = 0.036350306 * 0.241300709 * 0.05 = 0.000438568

你也能夠看到這寫成:

\ frac {\ partial E_ {total}} {\ partial w_ {1}} =(\ sum \ limits_ {o} {\ frac {\ partial E_ {total}} {\ partial out_ {o}} * \ frac { \ partial {{}} {\ partial net_ {o}} \ \ frac {\ partial net_ {o}} {\ partial out_ {h1}}})* \ frac {\ partial out_ {h1}} {\ partial net_ {h1}} * \ frac {\ partial net_ {h1}} {\ partial w_ {1}}

\ frac {\ partial E_ {total}} {\ partial w_ {1}} =(\ sum \ limits_ {o} {\ delta_ {o} * w_ {ho}})* out_ {h1}(1  -  out_ { h1})* i_ {1}

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = \ delta_ {h1} i_ {1}

咱們如今能夠更新W_1

w1 ^ {+} = w_1  -  \ eta * \ frac {\ partial E_ {total}} {\ partial w_ {1}} = 0.15  -  0.5 * 0.000438568 = 0.149780716

重複這些W_2w_3W_4

w_2 ^ {+} = 0.19956143

w_3 ^ {+} = 0.24975114

w_4 ^ {+} = 0.29950229

最後,咱們已經更新了全部的重量!當咱們最初輸入0.05和0.1的輸入時,網絡上的偏差爲0.298371109。在第一輪反向傳播以後,總偏差如今降至0.291027924。它可能看起來並很少,可是在重複這個過程10,000次後,錯誤會直線降低到0.0000351085。此時,當咱們提早0.05和0.1時,兩個輸出神經元產生0.015912196(vs 0.01目標)和0.984065734(vs 0.99目標)。

若是你已經作到了這一點,並發現上述任何錯誤,或者能夠想出任何方法使將來的讀者更清楚,不要猶豫,給我一個筆記。謝謝!

相關文章
相關標籤/搜索