摘要:說到BP(Back Propagation)算法,人們通常強調的是反向傳播,其實它是一個雙向算法:正向傳播輸入信號,反向傳播誤差信息。接下來,你將看到的,可能是史上最為通俗易懂的BP圖文講解,不信?來瞅瞅并吐吐槽唄!
更多深度文章,請關注:https://yq.aliyun.com/cloud
系列文章:
人工“碳”索意猶盡,智能“硅”來未可知(深度學習入門系列之二)
“機器學習”三重門,“中庸之道”趨若人(深度學習入門系列之四)
Hello World感知機,懂你我心才安息 (深度學習入門系列之五)
8.1 BP神經網絡極簡史
在神經網絡(甚至深度學習)參數訓練中,BP(Back Propagation)算法非常重要,它都占據舉足輕重的地位。在提及BP算法時,我們常將它與杰弗里?辛頓(Geoffrey Hinton)的名字聯系在一起。但實際上,辛頓還真不是第一個提出BP算法的人,就像愛迪生不是第一個發明電燈的人一樣。但人們記住的,永遠都是那個讓電燈“飛入平常百姓家”的功勛人物愛迪生,而不是它的第一發明人美國人亨利·戈培爾(Henry Goebel)。
如果說辛頓就是BP算法的“愛迪生”,那誰是BP算法的“戈培爾”呢?他就是保羅·沃伯斯(Paul Werbos)。1974年,沃伯斯在哈佛大學博士畢業。在他的博士論文里,首次提出了通過誤差的反向傳播來訓練人工神經網絡[1]。事實上,這位沃伯斯不光是BP算法的開創者,他還是循環神經網絡(Recurrent Neural Network,RNN)的早期開拓者之一。在后期的系列入門文章中,我們還會詳細介紹RNN,這里暫且不表。
說到BP算法,我們通常強調的是反向傳播,但其實呢,它是一個典型的雙向算法。更確切來說,它的工作流程是分兩大步走:(1)正向傳播輸入信號,輸出分類信息(對于有監督學習而言,基本上都可歸屬于分類算法);(2)反向傳播誤差信息,調整全網權值(通過微調網絡參數,讓下一輪的輸出更加準確)。
下面我們分別舉例,說明這兩個流程。為了簡化問題描述,我們使用如圖8-1所示的最樸素三層神經網絡。在這個網絡中,假設輸入層的信號向量是[-1, 1],輸出層的目標向量為[1, 0],“學習率”η為0.1,權值是隨機給的,這里為了演示方便,分別給予或“1”或“-1”的值。下面我們就詳細看看BP算法是如何運作的?
圖8-1 簡易的三層神經網絡
8.2.1正向傳播信息
正向傳播信息,簡單說來,就是把信號通過激活函數的加工,一層一層的向前“蔓延”,直到抵達輸出層。在這里,假設神經元內部的激活函數為Sigmod(f(x)=11+e?xf(x)=11+e?x)。之所以選用這個激活函數,主要因為它的求導形式非常簡潔而優美:
f′(x)=f(x)(1?f(x))(8.1)(8.1)f′(x)=f(x)(1?f(x))
事實上,類似于感知機,每一個神經元的功能都可細分兩大部分:(1)匯集各路鏈接帶來的加權信息;(2)加權信息在激活函數的“加工”下,神經元給出相應的輸出,如圖8-2所示。
圖8-2 單個神經元的兩部分功能
于是,在正向傳播過程中,對于f1(e)f1(e)神經元的更新如圖8-3所示,其計算過程如下所示:
f1(e)=f1(w11x1+w21x2)=f1((?1)×1+1×(?1))=f1(?2)=11+e?(?2)=0.12f1(e)=f1(w11x1+w21x2)=f1((?1)×1+1×(?1))=f1(?2)=11+e?(?2)=0.12
圖8-3 神經元信息前向更新神經元1的f1(e)
接著,在同一層更新f2(e)f2(e)的值,過程和計算步驟類似于f1(e)f1(e),如圖8-4所示:
f2(e)=f2(w12x1+w22x2)=f2(1×1+1×(?1))=f2(0)=11+e0=0.5f2(e)=f2(w12x1+w22x2)=f2(1×1+1×(?1))=f2(0)=11+e0=0.5
圖8-4 神經元信息前向更新神經元2的f2(e)
接下來,信息正向傳播到下一層(即輸出層),更新神經元3的f3(e)f3(e)(即輸出y1y1的值),如圖8-5所示。
y1=f3(e)=f3(w13f1+w23f2)=f3(1×0.12+1×0.5)=f3(0.62)=11+e?0.62=0.65y1=f3(e)=f3(w13f1+w23f2)=f3(1×0.12+1×0.5)=f3(0.62)=11+e?0.62=0.65
圖8-5 神經元信息前向更新神經元3的f3(e)
然后,類似地,計算同在輸出層求神經元f4(e)f4(e)(即輸出y2y2)的值,如圖8-6所示。
y2=f4(e)=f4(w14f1+w24f2)=f4((?1)×0.12+1×0.5)=f4(0.38)=11+e?0.38=0.59y2=f4(e)=f4(w14f1+w24f2)=f4((?1)×0.12+1×0.5)=f4(0.38)=11+e?0.38=0.59
圖8-6神經元信息前向更新f4(e)
到此,在第一輪信號前向傳播中,實際輸出向量已計算得到y′=[0.65,0.59]Ty′=[0.65,0.59]T,但我們預期輸出的向量(即教師信號)是y=[1,0]Ty=[1,0]T,這二者之間是存在“誤差”的。于是,重點來了,下面我們就用“誤差”信息反向傳播,來逐層調整網絡參數。為了提高權值更新效率,這里就要用到下文即將提到的“反向模式微分法則(chain rule)”。
8.2.2 求導中的鏈式法則
(砰!砰!砰!敲黑板!請注意:如下部分是BP算法最為精妙之處,值得細細品味?。?/p>
在前面信號正向傳播的示例中,為了方便讀者理解,我們把所有的權值都暫時給予了確定之值。而實際上,這些值都是可以調整的,也就是說其實它們都是變量,除掉圖8-1中的所有確定的權值,把其視為變量,得就到更為一般化的神經網絡示意圖8-7。
圖8-7 帶權重變量的神經網絡
這里為了簡化理解,我們暫時假設神經元沒有激活函數(或稱激活函數為y=xy=x),于是對于隱含層神經元,它的輸出可分別表示為:
f1=x1w11+x2w21f2=x1w12+x2w22f1=x1w11+x2w21f2=x1w12+x2w22
然后,對于輸出層神經元有:
f3=f1w13+f2w23=(x1w11+x2w21)w13+(x1w12+x2w22)w23=x1w11w13+x2w21w13+x1w12w23+x2w22w23f3=f1w13+f2w23=(x1w11+x2w21)w13+(x1w12+x2w22)w23=x1w11w13+x2w21w13+x1w12w23+x2w22w23
f4=f1w14+f2w24=(x1w11+x2w21)w14+(x1w12+x2w22)w24=x1w11w14+x2w21w14+x1w12w24+x2w22w24f4=f1w14+f2w24=(x1w11+x2w21)w14+(x1w12+x2w22)w24=x1w11w14+x2w21w14+x1w12w24+x2w22w24
于是,損失函數LL可表示為公式(8.2):
L(w11,w12,...,wij,...,wmn)=12(yi?fi(w11,w12,...,wij,...,wmn))2(8.2)(8.2)L(w11,w12,...,wij,...,wmn)=12(yi?fi(w11,w12,...,wij,...,wmn))2
這里YY為預期輸出值向量,為實際輸出向量fi(w11,w12,...,wij,...,wmn)fi(w11,w12,...,wij,...,wmn)。對于有監督學習而言,在特定訓練集合下,輸入元素xixi和預期輸出yiyi都可視為常量。由此可以看到,損失函數LL,在本質上,就是一個單純與權值wijwij相關的函數(即使把原本的激活函數作用加上去,除了使得損失函數的形式表現得更加復雜外,并不影響這個結論)。
于是,損失函數LL梯度向量可表示為公式(8.3):
?L=(?L?w11,?L?w12,...,?L?wmn)=?L?w11e11+?L?w12e12+...+?L?wmnemn(8.3)(8.3)?L=(?L?w11,?L?w12,...,?L?wmn)=?L?w11e11+?L?w12e12+...+?L?wmnemn
其中,這里的eijeij是正交單位向量。為了求出這個梯度,需要求出損失函數LL對每一個權值wijwij的偏導數。
BP算法之所以經典,部分原因在于,它是求解這類“層層累進”的復合函數偏導數的利器。為啥這么說呢?下面,我們就列舉一個更為簡化但不失一般性的例子來說明這個觀點(以下案例參考了Chris Olah的博客文章[3])。
假設有如下一個三層但僅僅包括aa、bb、cc、dd和ee等5個神經元的網絡,在傳遞過程中,cc、dd和ee神經元對輸入信號做了簡單的加工,如圖8-8所示。
圖8-8 簡易的神經網絡
假設變量aa影響cc,此時我們想弄清楚aa是如何影響cc的。于是我們考慮這么一個問題,如果aa變化一點點,那么cc是如何變化的呢?我們把這種影響關系定義為變量cc相對于變量aa的偏導數,記做?c?a?c?a。
利用高等數學的知識,我們很容易求得,對于直接相連的神經元(如aa對cc,或bb對dd),可利用“加法規則”或“乘法規則”直接求出。例如,利用加法規則,?c?a?c?a可表示為:
?c?a=?(a+b)?a=?a?a+?b?a=1?c?a=?(a+b)?a=?a?a+?b?a=1
而對于表達式為乘法的求偏導規則為:
??uuv=u?v?u+v?u?u=v??uuv=u?v?u+v?u?u=v
那么,對于間接相連的神經元,比如aa對ee,如果我們也想知道aa變化一點點時ee變化多少,怎么辦呢?也就是說,偏導數?e?a?e?a該如何求呢?這時,我們就需要用到鏈式法則了。
這里假設a=2a=2,b=1b=1。如果aa的變化速率是1,那么cc的變化速率也是1(因為?c?a=1?c?a=1)。類似地,如果cc的變化速率為1,那么ee的變化速率為2(因為?e?c=d=2?e?c=d=2)。所以相對于aa變化1,ee的變化為1×2=21×2=2。這個過程就是我們常說的“鏈式法則”,其更為形式化的表達為(如圖8-9所示):
?e?a=?e?c??c?a=d×1=2×1=2?e?a=?e?c??c?a=d×1=2×1=2
圖8-9 鏈式法則示意圖
aa對ee的“影響”屬于單路徑的影響,還比較容易求得,但這并不是我們關注的重點。因為在神經網絡中,神經元對神經元的連接,阡陌縱橫,其影響也是通過多條路徑“交織”在一起的。在圖8-9中,我們研究一下bb對ee的影響,就能比較好理解這一工作機理。顯然,bb對ee的影響,也可表達為一個偏導關系:
?e?b=?cd?b=d?c?b+c?d?b=d×1+c×1=2×1+3×1=5?e?b=?cd?b=d?c?b+c?d?b=d×1+c×1=2×1+3×1=5
從圖8-9可以看出,bb對ee影響,其實是“兵分兩路”:(1)bb通過影響cc,然后通過cc影響ee;(2)bb通過影響dd,然后通過dd影響ee。這就是多維變量(這里“多”僅為2)鏈式法則的“路徑加和”原則。
這個原則,看起來簡單明了,但其實蘊藏著巨大代價。因為當網絡結構龐大時,這樣的“路徑加和”原則,很容易產生組合爆炸問題。例如,在如圖8-10所示的有向圖中,如果XX到YY有三條路徑(即XX分別以αα、ββ和χχ的比率影響YY),YY到ZZ也有三條路徑(YY分別以δδ、εε和ξξ的比率影響ZZ)。
圖8-10 路徑加和規則演示
于是,很容易根據路徑加和原則得到XX對ZZ的偏導數:
?Z?X=(αδ+αε+αξ)+(βδ+βε+βξ)+(χδ+χε+χξ)(8.4)(8.4)?Z?X=(αδ+αε+αξ)+(βδ+βε+βξ)+(χδ+χε+χξ)
上面用到的求偏導數方法,可稱之為“前向模式微分(forward-mode differentiation)”,如圖8-11-(a)所示。當網絡結構簡單時,即使XX到ZZ的每一個路徑都被“臨幸(遍歷)”一遍,總共才有3×3=93×3=9條路徑,但一旦網絡結構的復雜度上去了,這種“前向模式微分”,就會讓求偏導數的次數和神經元個數的平方成正比。這個計算量,就很可能是成為機器“難以承受的計算之重”。
有道是“東方不亮西方亮”。為了避免這種海量求導模式,數學家們另辟蹊徑,提出了一種稱之為“反向模式微分(reverse-mode differentiation)”。取代公式(8.4)的那種簡易的表達方式,我們用公式(8.5)的表達方式來求XX對ZZ的偏導:
?Z?X=(α+β+ξ)(δ+ε+ξ)(8.5)(8.5)?Z?X=(α+β+ξ)(δ+ε+ξ)
或許你會不屑一顧,這又是在搞什么鬼?把公式(8.4)恒等變換為公式(8.5)又有什么用呢?
圖8-11 前向與反向微分方法對比
你可別急,這背后大有玄機,且聽我慢慢道來。
前文提到的前向模式微分方法,其實就是我們在高數課堂上學習的求導方式。在這種求導模式中,強調的是某一個輸入(比如XX)對某一個節點(如神經元)的影響。因此,在求導過程中,偏導數的分子部分,總是根據不同的節點總是不斷變化,而分母則鎖定為偏導變量“?X?X”,保持定不變(見圖8-11-(a))。
相比而言,反向模式微分方法則有很大不同。首先在求導方向上,它是從輸出端(output)到輸入端進行逐層求導。其次,在求導方法上,它不再是對每一條“路徑”加權相乘然后求和,而是針對節點采納“合并同類路徑”和“分階段求解”的策略。
拿8-11-(b)的例子來說,先求YY節點對ZZ節點的"總影響"(反向第一層):
?Z?Y=δ+ε+ξ?Z?Y=δ+ε+ξ
然后,再求節點XX對節點YY的總影響(反向第二層):
?Z?Y=α+β+χ?Z?Y=α+β+χ
然后利用乘法規則求得XX對ZZ的整體影響(α+β+ξ)(δ+ε+ξ)(α+β+ξ)(δ+ε+ξ)。在求導形式上,偏導數的分子部分(節點)不變,而分母部分總是隨著節點不同而變化,即[?Z?][?Z?]。
這樣說來說去,好像還是不太明白!下面我們還是用圖8-9所示的原始例子,對比二者的求導過程,一遍走下來,你就能明白其中的差異。為了進一步方便讀者理解,我們將圖8-9重新繪制為圖8-12的樣子。
圖8-12 前向模式微分方法
以求變量bb偏導數的流程為例,我們先用前向模式微分法,來說明這種方法的求導過程。根據加法規則,對于求偏導值?e?b?e?b的步驟可以分兩步走:(1)求得所有輸入(包括aa和bb)到終點ee的每條路徑上的偏導值乘積;(2)對所有條路徑的導數值進行加和操作。
從8-12所示的圖中,對于兩個輸入aa和bb,它們共有3條路徑抵達終點ee(分別計為①、②和③)。
對于第①條路徑而言,輸入aa對ee的影響為:
?e?b=0×1×1×2=0?e?b=0×1×1×2=0
對于第②條路徑而言,輸入bb對ee的影響為:
?e?b=1×1×1×2=2?e?b=1×1×1×2=2
對于第③條路徑而言,輸入bb對ee的影響為:
?e?b=1×1×1×3=3?e?b=1×1×1×3=3
所以在整體上,輸入aa和bb從三條路徑上對e施加的“總影響”為:0+2+3=5.
或許讀者已經注意到了,有些路徑已經被冗余遍歷了,比如在圖8-12所示中,a→c→ea→c→e(第①條路)和b→c→eb→c→e(第②條路)就都走了路徑c→ec→e。
此外,對于求?e?a?e?a,上述三條路徑,它們同樣還是“一個都不能少”地走一遍,這到底得有多少冗余??!
可能你會疑問,對于?e?b?e?b(?e?a?e?a),第①(③)條路徑明明可以不走的嘛?這種明智,是對人的觀察而言的,且是對于簡單網絡而言的。因為,如果網絡及其復雜,人們可能就沒有這么“慧眼識珠”,識別其中的路徑冗余。
此外,對于計算機而言,有些時候,局部操作的“優化”,相對于整體操作的“規范化”,頂多算得上“奇淫巧技”,其優勢可謂是“蕩然無存”。如果有過大規模并行編程經驗的讀者,可能對這個觀點會有更深的認知。
然而,同樣是利用鏈式法則,反向模式微分方法就能非常機智地避開了這種冗余(下面即將講到的BP算法,正是由于這么干,才有其優勢的)。在這種方法中,它能做到對每一條路徑只“臨幸”一次,這是何等的節儉!下面我們來看看它是如何工作的。
圖8-13反向模式微分方法
相比于“前向模式微分法”是以輸入(如圖8-13-(a)所示的aa和bb)為錨點,正向遍歷每一條可能的路徑。反向模式微分法是以節點(或說神經元,如圖8-13-(a)所示的ee、cc和dd)為錨點,逐層分階段求導,然后匯集每一個節點的外部路徑(合并同類路徑)。
如圖8-13-(b)所示,在反向求導的第1層,對于節點cc有:
?e?c=?(c×d)?c=d=2?e?c=?(c×d)?c=d=2
類似的,對于節點dd有:
?e?d=?(c×d)?d=c=3?e?d=?(c×d)?d=c=3
在階段性的求解完畢第一層的導數之后,下面開始求解第二層神經元變量的偏導。如圖8-13-(c)所示,在反向第2層,對于節點aa有如圖8-14-(Ⅰ)所示的求導模式。
圖8-14反向模式微分方法的推演
特別需要注意的是,8-14-(Ⅰ)所示的表達式“?e?c?c?a?e?c?c?a”中左部“?e?c?e?c”,已經在第1層求解過了,并“存儲”在神經元cc中。此時,采用“拿來主義”,拿來就能用!這就是反向模式微分的精華所在!
類似地,在反向求導第2層,對于節點bb,由于它匯集“兩路兵馬”的影響,所以需要合并同類路徑,有如圖8-14-(Ⅱ)所示結果。
這樣一來,如圖8-13反向模式微分方法,每個路徑僅僅遍歷一次,就可以求得所有輸出(如ee節點)對輸入(如aa或bb節點)的偏導,干凈利落,沒有任何冗余!
在第七章,我們提到“BP算法把網絡權值糾錯的運算量,從原來的與神經元數目的平方成正比,下降到只和神經元數目本身成正比?!逼涔?,正是得益于這個反向模式微分方法節省的計算冗余!
8.2.3 誤差反向傳播
有了前面“鏈式求導”的知識鋪墊,下面我們就來細細講解誤差反向傳播的過程。鑒于我們的系列文章是寫給初學者(實踐者)看的,下面我們盡量省略了其中較為復雜的推導公式,對該部分感興趣的讀者可參閱卡內基梅隆大學Tom Mitchell教授的經典著作《機器學習》[3](對公式不感冒的讀者,第一遍閱讀可以直接跳過公式,直達圖文解釋部分)。
誤差反向傳播通過梯度下降算法,迭代處理訓練集合中的樣例,一次處理一個樣例。對于樣例dd,如果它的預期輸出(即教師信號)和實際輸出有“誤差”,BP算法抓住這個誤差信號LdLd,以“梯度遞減”的模式修改權值。也就是說,對于每個訓練樣例dd,權值wjiwji的校正幅度為ΔwjiΔwji(需要說明的是,wjiwji和wijwij其實都是同一個權值,wjiwji表示的是神經元jj的第ii個輸入相關的權值,這里之所以把下標“jj”置于“ii”之前,僅僅表示這是一個反向更新過程而已):
Δwji=?η?Ld?wji(8.6)(8.6)Δwji=?η?Ld?wji
在這里,LdLd表示的是訓練集合中樣例dd的誤差,分解到輸出層的所有輸出向量,LdLd可表示為:
Ld(w)=12∑j∈outputs(yj?y′j)2(8.7)(8.7)Ld(w)=12∑j∈outputs(yj?yj′)2
其中:
yjyj表示的是第jj個神經單元的預期輸出值。
y′jyj′表示的jj個神經單元的實際輸出值。
outputsoutputs的范圍是網絡最后一層的神經元集合。
下面我們推導出?Ld?wji?Ld?wji的一個表達式,以便在公式(8.7)中使用梯度下降規則。首先,我們注意到,權值wjiwji僅僅能通過netjnetj影響其他相連的神經元。因此利用鏈式法則有:
?Ld?wji=?Ld?netj?netj?wji=?Ld?netjxji(8.8)(8.8)?Ld?wji=?Ld?netj?netj?wji=?Ld?netjxji
在這里,netj=∑iwjixjinetj=∑iwjixji,也就是神經元jj輸入的加權和。xjixji表示的神經jj的第ii個輸入。需要注意的是,這里的xjixji是個統稱,實際上,在反向傳播過程中,在經歷輸出層、隱含層和輸入層時,它的標記可能有所不同。
由于在輸出層和隱含層的神經元對“糾偏”工作,承擔的“責任”是不同的,至少是形式不同,所以需要我們分別給出推導。
(1)在輸出層,對第ii個神經元而言,省略部分推導過程,公式(8.8)的左側第一項為:
?Ld?netj=(yj?y′j)y′j(1?y′j)(8.9)(8.9)?Ld?netj=(yj?yj′)yj′(1?yj′)
為了方便表達,我們用該神經元的糾偏“責任(responsibility)”δ(1)jδj(1)描述這個偏導,即:
δ(1)j=?Ld?netj(8.10)(8.10)δj(1)=?Ld?netj
這里δ(1)jδj(1)的上標“(1)”,表示的是第1類(即輸出層)神經元的責任。如果上標為“(2)”,這表示的是第2類(即隱含層)神經元的責任,見下面的描述。
(2)對隱含層神經元jj的梯度法則(省略了部分推導過程),有:
其中:
fjfj表示神經單元jj的計算輸出。
netjnetj表示的是神經單元jj的加權之和。
Downstream(j)Downstream(j)表示的是在網絡中神經單元jj的直接下游單元集合。
隱含層神經元的糾差職責,是通過計算前一步輸出神經元的“責任”來實現的。
這里說的每層神經元“責任”,或者更為確切來說是“糾偏責任”,其實就是在8.2.2節講到的“分階段求解”策略。
在明確了各個神經元“糾偏”的職責之后,下面就可以依據類似于感知機學習,通過如下加法法則更新權值:
對于輸出層神經元有:
w(1)ji=w(1)ji+ηΔw(1)ji=w(1)ji+ηδ(1)ihj(8.12)(8.12)wji(1)=wji(1)+ηΔwji(1)=wji(1)+ηδi(1)hj
對于隱含層神經元有:
在這里,η∈(0,1)η∈(0,1)表示學習率。在實際操作過程中,為了防止錯過極值,ηη通常取小于0.1的值。hjhj為神經元j的輸出。xjkxjk表示的是神經單元jj的第kk個輸入。
上面的公式依然比較抽象,難以理解。下面我們還是以前面的神經網絡拓撲結構為例,用實際運算過程給予詳細說明,以期望給與讀者感性認識。
從上面的描述可以得知,針對輸出層的神經元3,它的輸出值y′1y1′為0.65,而期望輸出值y1y1為1,二者存在“誤差”:e1=y1?y′1=1?0.65=0.35e1=y1?y1′=1?0.65=0.35。
在這里,我們把每個神經元根據誤差調參的“責任”記為δδ,那么,根據公式(8.9)和(8.10),神經元3的“責任”可表示為:
圖8-15 誤差反向傳播計算神經元3的“責任”
從上面分析可知,我們很容易計算出δ(1)3δ3(1)的值:
于是,可以反向更新w(1)31w31(1)的權值為:
在這里,(具體推導見公式8.8-8.10),ηη為學習率,此處取值為0.1。f1f1為神經元1的輸出(即y′1y1′)。
類似地,我們可以反向更新w(1)32w32(1))的權值:
w(1)32=w(1)32+ηΔw(1)32=w(1)32+ηδ(1)3f2=1+0.1×0.0796×0.5=1.00398w32(1)=w32(1)+ηΔw32(1)=w32(1)+ηδ3(1)f2=1+0.1×0.0796×0.5=1.00398
同樣的操作,我們可以計算出δ(1)4δ4(1)的值,如圖8-16所示。
圖8-16 誤差反向傳播計算神經元4的責任
從而可以反向更新w(1)41w41(1)的權值:
w(1)41=w(1)41+ηΔw(1)41=w(1)41+ηδ(1)4f1=?1+0.1×(?0.1427)×0.12=?1.0017w41(1)=w41(1)+ηΔw41(1)=w41(1)+ηδ4(1)f1=?1+0.1×(?0.1427)×0.12=?1.0017
類似地,我們可以反向更新w(1)42w42(1)的權值:
w(1)42=w(1)42+ηΔw(1)42=w(1)42+ηδ(1)4f2=1+0.1×(?0.1427)×0.5=0.9929w42(1)=w42(1)+ηΔw42(1)=w42(1)+ηδ4(1)f2=1+0.1×(?0.1427)×0.5=0.9929
在反向更新完畢輸出層的權值后,下面。我們開始反向更新隱含層的網絡權值,示意圖如圖8-17所示。
圖8-17 誤差反向傳播計算神經元1的責任
如果我們把反向傳播誤差的“職責(即δjδj)”,也看做一種特殊信息的話,那么在隱藏層的每個神經元都會有一個加權和影響,記為ΔjΔj,實際上,這里的ΔjΔj,就是公式(8.11)的加權求和Downstream(j)Downstream(j)(其實也就是8.2.2所提及的“合并同類路徑”)。
對于隱含層神經1,則有:
有了這個權值影響,我們就可以很容易計算出神經元1承擔的“責任”δ(2)1δ1(2):
δ(2)1=f1(1?f1)Δ1=0.12×(1?0.12)×0.2223=?0.0235δ1(2)=f1(1?f1)Δ1=0.12×(1?0.12)×0.2223=?0.0235
在計算出計算神經元1承擔的“責任”之后,我們就可以更新與神經元1相連的兩個輸入變量權值:
類似的流程(示意圖如圖8-18所示),可以求得神經元2的累計加權影響有:
圖8-18誤差反向傳播計算神經元2的責任
于是,計算神經元2承擔的“責任”δ(2)2δ2(2):
δ(2)2=f2(1?f2)Δ2=0.5×(1?0.5)×(?0.0631)=0.0158δ2(2)=f2(1?f2)Δ2=0.5×(1?0.5)×(?0.0631)=0.0158
同樣,計算出計算神經元2承擔的“責任”之后,我們就可以更新與神經元2相連的兩個輸入變量權值:
從上面的推導過程,我們可以看到,經過一輪的誤差逆傳播,神經網絡的權值前后確有不同。但由于學習率(即步長)較小(為0.1),所以前后的權值變化并不大(括號內的數值為原始權值),如圖8-19所示。
圖8-19 一輪BP算法之后前后的權值對比
如此一來,整個網絡的權值就全部得以更新。接下來,網絡就可接受下一個訓練樣例,接著往下訓練了,直到輸出層的誤差小于預設的容忍度。
BP算法,在很多場所的確非常有用。例如,1989年,Yann Lecun(又一位當下的深度學習大牛)等人就用BP算法,在手寫郵政編碼識別上有著非常成功的應用[5],訓練好的系統,手寫數字錯誤率只有5%。Lecun借此還申請了美國專利,開了公司,發了一筆小財。
在發表BP算法之后的30年,2006年,辛頓等人在發表的有關“深度信念網”的經典論文中指出[8],深度信念網(DBN)的組成元件就是受限玻爾茲曼機 (Restricted Boltzmann Machines, RBM)。而DBN的構建其實分兩步走的:(1)單獨“無監督”地訓練每一層RBM網絡,以確保特征向量在映射到不同特征空間時,能夠盡可能多地保留特征信息;(2)在DBN的最后一層,設置BP網絡,用以接收RBM的輸出特征向量作為它的輸入特征向量,然后“有監督”地訓練實體關系分類器,對網絡權值實施微調(Fine-Tune)。
現在你看到了,BP算法的影響力,一直滲透到“深度學習”骨子里!這就是為什么在講深度學習時,我們繞不過BP算法的原因。
8.4 小結
在本章中,我們詳細解釋了反向傳播(BP)算法,通過學習我們知道,BP算法其實并不僅僅是個反向算法,而是一個雙向算法。也就是說,它其實是分兩大步走:(1)正向傳播信號,輸出分類信息;(2)反向傳播誤差,調整網絡權值。如果沒有達到預期目的,重走回頭路(1)和(2)。
BP算法很成功。但我們也要看到BP算法的不足,比如說會存在“梯度擴散(Gradient Diffusion)”現象,其根源在于對于非凸函數,梯度一旦消失,就沒有指導意義,導致它可能限于局部最優。而且“梯度擴散”現象會隨著網絡層數增加而愈發嚴重,也就是說,隨著梯度的逐層消減,導致它對調整網絡權值的調整效益,作用越來越小,故此BP算法多用于淺層網絡結構(通常小于等于3),這就限制了BP算法的數據表征能力,從而也就限制了BP的性能上限。
再比如說,雖然相比于原生態的BP算法,雖然它降低了網絡參數的訓練量,但其網絡參數的訓練代價還是不小,耗時非?!翱捎^”。就拿LeCun的識別手寫郵編的案例說事,其訓練耗時就達3天之久。
再后來,與LeCun同在一個貝爾實驗室的同事Vladimir Vapnik(弗拉基米爾·萬普尼克),提出并發揚光大了支持向量機 (Support Vector Machine) 算法。
SVM作為一種分類算法,對于線性分類,自然不在話下。在數據樣本線性不可分時,它使用了所謂“核機制(kernel trick)”,將線性不可分的樣本,映射到高維特征空間 (high-dimensional feature space),從而使其線性可分。自上世紀九十年代初開始,SVM逐漸大顯神威,在圖像和語音識別等領域,獲得了廣泛而成功的應用。
在手寫郵政編碼的識別問題上,LeCun利用BP算法,把錯誤率整到5%左右,而SVM在1998年就把錯誤率降到低至0.8%。這遠超越同期的傳統神經網絡算法。
就這樣,萬普尼克又把神經網絡研究送到了一個新的低潮!
在下一章中,我們將來聊聊“卷積神經網絡”,這可是深度學習發展過程中的一個重要里程碑,希望你能關注。
8.5 請你思考
通過本章的學習,請你思考如下問題:
(1)正是由于神經網絡具有強大的表示能力,“成也蕭何,敗也蕭何”,BP算法常常遭遇“過擬合(overfitting)”,它可能會把噪音當做有效信號,你知道有什么策略來避免過擬合嗎?
(2)利用梯度遞減策略,BP算法常停止于局部最優解,而非全局最優解,這好比“只因身在此山中”,卻不知“人外有人,山外有山”,你知道有什么方法可以改善這一狀況嗎?
(3)在BP算法流程中,我們看到的是反反復復的權值調整,而杰弗里?辛頓在文獻[4]中提到的特征表示(representation),體現在什么地方?
【參考文獻】
[1] Paul J. Werbos. Beyond Regression: New Tools for Prediction and Analysis in the Behavioral Sciences. PhD thesis, Harvard University, 1974
[2] Christopher Olah. Calculus on Computational Graphs: Backpropagation
[3]Tom Mitchell著.曾華軍等譯. 機器學習. 機器工業出版社. 2007.4
[4] Williams D, Hinton G. Learning representations by back-propagating errors[J]. Nature, 1986, 323(6088): 533-538.
[5] LeCun Y, Boser B, Denker J S, et al. Backpropagation applied to handwritten zip code recognition[J]. Neural computation, 1989, 1(4): 541-551.
[6]周志華. 機器學習. 清華大學出版社. 2016.1
[7] Mirosav Kubat著. 王勇等譯. 機器學習導論. 機械工業出版社. 2016.11
[8] Hinton G E, Osindero S, Teh Y W. A fast learning algorithm for deep belief nets[J]. Neural computation, 2006, 18(7): 1527-1554.
文章作者:張玉宏,著有《品味大數據》一書。審校:我是主題曲哥哥。
(未完待續)