反向傳播算法的工作原理(1)


圖書推薦:《數據準備和特徵工程》


反向傳播算法是神經網絡中的重要算法,通過它能夠快速計算梯度,進而通過梯度下降實現權重和偏置參數的更新

反向傳播算法最初是在20世紀70年代被引入的,但直到1986年大衛·魯梅爾哈特、傑弗裏·辛頓和羅納德·威廉姆斯合作的一篇著名論文問世後,人們才充分認識到它的重要性。這篇論文描述了幾種神經網絡,其中反向傳播比以前的方法快得多,使人們有可能利用神經網絡來解決以前無法解決的問題。如今,反向傳播算法是神經網絡中所要學習的主要內容。

本文的內容中涉及到更多的數學問題。如果你對數學不感興趣,可以把反向傳播當作一個黑匣子,忽略其中的細節。但是,如果想深入理解神經網絡,還是有必要花時間研究這些細節的。

反向傳播的核心思想是代價函數 相對於網絡中任何權重 (或偏置 )的偏導數 ,此式說明,更新權重和偏差時,代價函數的變化程度。雖然表達式有點複雜,但它的每一個元素都有一個自然的、直觀的解釋。所以反向傳播不僅僅是一種可供學習的快速算法,它也爲我們詳細解釋了權重和偏置的改變,從而提升網絡的整體預測能力。這很值得詳細研究。

基於矩陣的計算

在討論反向傳播之前,讓我們先用一個基於矩陣的快速算法來計算神經網絡的輸出。

首先要明確一些符號的意義,文中會用 表示從   層的第 個神經元到 層的第 個神經元的連接權重參數。下圖顯示的是從網絡第二層的第四個神經元到第三層的第二個神經元的連接的權重:

這種記法一開始很麻煩,要掌握它確實需要費些功夫。但只要稍加努力,你就會發現這種記法變得簡單而自然。它的一個奇怪之處是 的順序。你可能認爲更合理的操作是:使用 表示輸入神經元、 表示輸出神經元,反之就不成立了,是這樣。下面將解釋這個奇怪現象的原因。

我們使用類似的符號來表示網絡的偏置和激活結果。 表示 層中的 神經元的偏差;用 來表示激活 層中的 神經元。下面的圖表展示了這些符號的應用:

有了這些符號, 層中的 神經元的激活 層中的激活產生了關聯,公式如下:

其中,求和表示的是 層中所有神經元共計 個。爲了以矩陣形式重寫這個表達式,我們爲每個層 定義一個權重矩陣 ,權重矩陣 的各項是連接到神經元的 層的權重,也就是說, 行和 列中的項是 。類似地,對於每個層 ,我們定義一個偏差向量, 。你也許可以猜出這樣操作的原理 —— 偏差向量的元素 ,是 層中每個神經元的一個分量。最後,我們定義了一個激活函數的輸出向量 ,它的分量是

將(23)式用矩陣形式重寫,不過,這裏還需要將激活函數( )向量化。基本想法是函數( )應用於向量 中的每個元素,於是用符號 來表示函數的這種應用,也就是說, 的分量只是 。舉個例子,對於函數 矢量化形式的效果如下:

也就是說,矢量化的 只是對矢量的每個元素求平方。

有了這些符號,我們就可以把式(23)改寫成漂亮而緊湊的矢量化形式:

這個表達式使我們可以從全局的角度來思考問題:一個層裏的激活函數是如何與前一層裏的激活輸出相關聯的。我們只需將權重矩陣應用於激活函數,然後添加偏置向量,最後應用 函數(順便說一下,正是這個表達式激活了前面提到的 符號中的怪現象。如果我們用 來表示輸入的神經元,用 來表示輸出的神經元,那麼,我們需要用權重矩陣的轉置來代替方程(25)中的權重矩陣。這是一個很小的改變,但是很煩人,我們將失去簡單易懂的說法(和想法):“將權重矩陣應用於激活函數”。與我們現在所採用的逐神經元觀點相比,這種全局觀點通常更簡單、更簡潔(涉及的指數更少!)。這種方法可以使我們逃離“角標地獄”,同時仍然精確地表述所發生的情況。該表達式在實踐中也很有用,因爲大多數矩陣庫提供了實現矩陣乘法、矢量加法和矢量化的快速方法。

當使用方程(25)計算 時,我們計算中間量 。把 稱爲層 中的神經元的加權輸入。我們將在後半部分大量使用加權輸入 。方程(25) 有時用加權輸入來表示,如: 。同樣值得注意的是, 包含 ,也就是說, 只是層 中神經元 的激活函數的加權輸入。

代價函數的兩個假設

反向傳播的目標是計算代價函數 相對於網絡中任何權重 或偏置 的偏導數 。爲了使反向傳播有效,我們需要對代價函數的形式做兩個主要的假設。不過,在陳述這些假設之前,先考慮以示例說明代價函數。

以下是二次代價函數的形式:

其中, 是訓練示例的總數; 是對所有單個訓練示例求和; 是相應的真實輸出; 表示網絡中的層數; 是輸入 時從網絡輸出的激活向量(即網絡的預測值)。

那麼,爲了應用反向傳播,我們需要對代價函數 做什麼樣的假設呢?

第一個假設是,對於單個訓練示例 ,可以把代價函數寫成一個平均值 ,而不是 。對於二次代價函數來說,情況就是如此。其中單個訓練示例的代價爲 。這個假設也適用於所有其他的代價函數。

之所以需要這個假設,是因爲反向傳播實際上允許我們計算一個訓練集的偏導數 。然後,我們通過對訓練模型求平均值來恢復 。事實上,基於這個假設,我們認爲訓練示例 已修復,並刪除 下標,將代價 寫成 。我們最終會讓 回到原處,但目前它是一個令人討厭的符號,最好還是隱式的。

我們對代價的第二個假設是,它可以寫成神經網絡輸出的函數:

例如,二次代價函數滿足這一要求,因爲單個訓練示例 的二次代價可以寫成:

代價函數也取決於真實值 。你可能感到疑惑:爲什麼我們不把代價也看作是 的函數?不過,請記住,輸入訓練示例 是固定的,因此輸出 也是一個固定參數。特別是, 不是我們可以通過改變權重和偏差來修改的。也就是說,它不是神經網絡學習的東西。因此,將 看作是 的函數,而 只是一個幫助定義該函數的參數。

矩陣的Hadamard積

反向傳播算法基於常見的線性代數運算,如矢量加法、矢量乘矩陣等。但其中一種運算不太常用。

假設 是同一維的兩個矢量。然後我們使用 來表示這兩個矢量的對應元素的積。因此, 的分量僅爲 。例如,

這種矩陣的對應元素相乘被稱爲矩陣的Hadamard積。很多支持矩陣計算的庫通常提供了Hadamard積的函數或算式,這在實現反向傳播時非常有用。

反向傳播幕後的四個基本方程

反向傳播能夠讓網絡中的權重和偏置參數更新,從而最小化代價函數,這意味着計算偏導數 。但是爲了便於計算,我們首先引入一箇中間量 ,它表示 層的 神經元誤差。反向傳播將爲我們提供一個計算誤差 的過程,然後將 關聯起來。

爲了理解這個誤差是如何定義的,我們想象在神經網絡中有一個精靈:

精靈坐在 層的 神經元上。當輸入結果傳給神經元時,精靈就會擾亂神經元的運作。它在神經元的加權輸入中增加了一點變化 ,因此神經元輸出的不是 ,而是輸出 。這種變化會在網絡中的後續層傳播,最終導致總代價發生變化,變化的幅度爲:

現在,這個精靈表現很好,它試圖幫助你減少代價。也就是說,他試圖找到一個使代價更小的 。假設 有一個很大的值(正或負),精靈可以選擇 ,獲取與 相反的符號,從而實現梯度下降。相比之下,如果 接近於零,那麼精靈無法通過擾動加權輸入 來減少代價。這是精靈會認爲,神經元已經接近最佳狀態(當然,這種情況只適合於小的改變 。我們假設精靈會被迫做出這麼小的改變)。所以, 是對神經元誤差的度量。

受此啓發,我們在 層中定義神經元 的誤差 ,其表達式爲:

按照通常的約定,使用 來表示與層 相關的誤差向量。反向傳播將爲我們提供一種計算每層的 的方法,然後將這些誤差與實際感興趣的量 相關聯。

你可能感到疑惑:爲什麼精靈要更改加權輸入 ?或許,想象它更改輸出激活 會更自然,因爲這樣的更改使我們能夠利用 作爲誤差的度量標準。事實上,如果你這樣做,結果會和下面的討論非常相似。但這種做法使反向傳播在代數表達上更爲複雜。因此,我們將堅持使用 作爲誤差度量標準。

制勝計劃:反向傳播基於四個基本方程。這些方程爲我們提供了一種計算誤差 和代價函數梯度的方法。我講到的是以下四個方程式。不過,需要注意的是:你不應該期望在瞬間就掌握這些方程式,期望越高失望越大。事實上,要理解反向傳播,需要相當多的時間和耐心,需要逐漸深入研究這些方程。

輸出層 中的誤差方程式:

(BP1)給出了 的分量。

這是一個非常自然的表達。右邊的第一項 是對 輸出激活的函數,代價的變化。例如,如果 不太依賴於某個特定的輸出神經元 ,那麼 的值將很小,這是我們所期望的。右邊的第二項 是激活函數 的導數。

注意,(BP1)中的所有內容都很容易計算。特別是,我們計算 ,計算 只是簡單的求導。當然, 的確切形式取決於代價函數的形式。但是,如果代價函數已知,則計算 應該不會有什麼問題。例如,如果我們使用二次代價函數 ,容易得出 ,這顯然是很容易計算的。

式(BP1)是 的分量式表達式。這是一個非常好的表達式,但不是反向傳播所需要的基於矩陣的形式。然而,我們很容易將這個方程改寫爲基於矩陣的形式,如:

在這裏, 是一個矢量,其分量是偏導數 。你可以將 看作是 相對於輸出激活的變化率。顯然(BP1a)和(BP1)是等價的,因此從現在起,我們將交替使用(BP1)。例如,在二次代價的情況下,得到 。因此,完全基於矩陣的(BP1)就變成這種形式:

如你所見,此表達式中的所有內容都有一個很好的矢量形式,並且可以使用諸如Numpy之類的庫輕鬆地進行計算。

關於下一層 的誤差 的方程是

其中, 層的權重矩陣 的轉置。這個方程看起來很複雜,但每個元素都很好解釋。假設我們知道 層的誤差 。當我們應用轉置權重矩陣 時,可以直觀地認爲:這是在網絡中反向移動誤差,使我們可以對第 層輸出處的誤差進行某種衡量。然後,我們取Hadamard積   。這就通過層 中的激活函數反向移動誤差,從而使我們得出層 的加權輸入中的誤差

將(BP2)與(BP1)相結合,我們可以計算網絡中任何層的誤差 。首先使用(BP1)來計算 ,再應用方程(BP2)來計算 ,然後再次使用方程(BP2)來計算 ,在網絡中依此類推。

與網絡中任何偏置相關的、代價變化率的方程是:

也就是說,誤差 正好等於變化率 。這是一個好消息,因爲(BP1)和(BP2)已經告訴我們如何計算 。我們可以將(BP3)簡寫爲:

我們知道 和偏差 是在同一個神經元上評估的。

與網絡中任何權重相關的、代價變化率的方程是:

這告訴我們如何計算與 相關的偏導數 ,而我們已經知道如何計算 了。可以用角標較少的符號改寫方程,如下所示:

其中, 是對權重 的神經元輸入的激活, 是權重 的神經元輸出的誤差。放大查看權重 ,以及由該權重連接的兩個神經元,我們可以將其描述爲:

方程(32)的一個很好的結果是:當激活 很小的時候,也就是 ,梯度項 也將趨於很小。在這種情況下,權重學習緩慢,這意味着它在梯度下降過程中變化不大。換句話說,(BP4)的一個結果是低激活神經元輸出的權重學習緩慢。

從(BP1)到(BP4)中可以得到其他關於這些方面的理解。我們首先着眼於輸出層。考慮一下(BP1)中的 ,可以使用S型函數。當 大約爲0或1時, 函數變得非常平坦。當這種情況發生時,我們就得到 。因此,要吸取的教訓是:如果輸出神經元是低激活度( )或高激活度( ),最後一層中的權重將緩慢學習。在這種情況下,通常會說:輸出神經元已經飽和,因此權重停止學習(或學習緩慢)。類似的情況也適用於輸出神經元的偏置。

我們可以對早期的層獲得類似的結果。特別要注意(BP2)中的 項。這意味着:如果神經元接近飽和, 可能會變小。這也意味着:輸入到飽和神經元的任何權重都將學習緩慢(如果 有足夠大的項來補償 的小值,這個推理就不成立了。但我說的是總體趨勢)。

綜上所述,我們已經瞭解到:如果輸入神經元的激活度很低,或者輸出神經元已經飽和,也就是說,無論是高激活還是低激活,權重學習都會很慢。

這些觀察結果都不太令人驚訝。儘管如此,它們仍有助於改進我們的心理模型。這些模型反應了神經網絡學習過程中所發生的情況。此外,我們可以優化這種推理方式。這四個基本方程對任何激活函數都適用,而不僅僅是標準的S型函數。記住這四個方程(BP1)-(BP4) 可以幫助解釋:爲什麼要嘗試這樣的修改?以及,它們會產生什麼樣的影響?

參考鏈接:http://www.math.hkbu.edu.hk/~mhyipa/nndl/chap2.pdf


關注微信公衆號:老齊教室

閱讀更多精彩文章


本文分享自微信公衆號 - 飛槳PPDB(Tsing_Liu)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章