07.25 基於矩陣的反向傳播

反向傳播是神經網絡訓練中常用的一種方法,它是通過對每一層的權值進行調優來實現輸出誤差的反向傳播,從而使損失函數最小化。

在本文中,我將用小批量表示反向傳播的矩陣方法,以及它如何加強神經網絡的學習;我還將把這種方法與在小批上循環進行比較,然後解釋小批處理大小如何影響學習速度和準確性。

簡介:

實際上,小批量梯度下降是梯度下降的一種變體,它在處理(feed-forwarding/back- propagation)一系列訓練數據後更新權重。所處理的示例數量稱為“mini-batch size”,是需要優化的神經網絡的超參數之一,因為我們將看到,這個大小的值會影響學習的速度和準確性。

給定一個具有多個示例(n)的mini-batch,循環方法包括循環該小批量,通過feed-forwarding然後一次back propagating 一個示例。因此,我們需要(n)次迭代來處理mini-batch的所有示例。

對於矩陣方法,我們將同時對所有示例進行 feed-forward/back-propagate。因此,只有一次迭代就足以處理所有的小批處理示例。

基於矩陣的反向傳播

符號:

在進一步討論之前,我們將指定一個符號來幫助我們引用神經網絡的組件。我們以這個包含4個神經元的隱藏層、3個神經元的輸入層和2個神經元的輸出層的網絡為例:

基於矩陣的反向傳播

我們通過以下方式表示權重,偏差和激活:

基於矩陣的反向傳播

因此,屬於層(1)的神經元(j)的激活可以用以下方式寫入(其中σ是激活函數):

基於矩陣的反向傳播

方程-1

基於矩陣的Feed-Forwarding:

如果我們指定每層的權重矩陣(W l ),則等式-1可以以矩陣形式重寫,其中(w jk )是矩陣的行號(j)和列號(k)上的元素。給定層(l)的權重矩陣乘以前一層(l-1)的激活的向量(A),乘法的結果被加到屬於該層的偏差(B)的向量中。(l)最後,激活函數應用於結果向量的每個元素。通過在我們的神經網絡上應用這個等式(1)等於3的等式,我們得到:

基於矩陣的反向傳播

方程-2

為了簡化方程式,我將插入向量(B)作為權重矩陣的第一列,並將(1)作為向量(A)的第一個元素插入,就像偏差正在扮演權重的角色一樣相應的激活總是等於1:

基於矩陣的反向傳播

方程-3

實際上,我所展示的是前饋傳播,但一次只有一個例子。我們想要做的是同時提供大量的例子,以加快學習速度。為此,不是將權重矩陣乘以一個激活矢量,而是將其乘以矩陣(X),其中每列表示對應於一個示例的激活矢量。後一個矩陣的列數是我們想要一次輸入的示例數,換句話說,就是mini-batch size。如果我們選擇一個等於4的小批量大小作為示例,該方程-3成為:

基於矩陣的反向傳播

基於矩陣的反向傳播:

現在我們已經瞭解矩陣方法如何用於前饋傳播,我們可以以相同的方式攻擊反向傳播:我們通過乘以權重矩陣一次前饋多個示例,然後返回 - 傳播誤差,始終遵循矩陣方法。為此,我們必須以矩陣形式重寫反向傳播的四個基本方程(見下圖):

基於矩陣的反向傳播

對於所表示的輸出層(L) ,我們寫出方程BP1中,如下圖,其中該矩陣的每個元素(G)是成本函數的導數(C)相對於所述激活(a)中,在這裡我們正利用二次代價函數,因此導數等於(aji-yji),其中(yji)是對應於輸出神經元(j)和示例(i)的標籤。

對於矩陣(S),每個元素是相對於(Zij)的激活函數的導數。

得到的矩陣(D)的每個元素對應於 輸出神經元(j)和示例(i)的Δ 。

基於矩陣的反向傳播

BP1:矩陣形式

現在,對於表示為(l)的隱藏層,我們將來自於層(l + 1)的加權矩陣的轉數乘以來自相同層的矩陣(D),得到的結果是使用Hadamard乘積乘以層(l)的矩陣(S)。BP2的方程是

基於矩陣的反向傳播

BP2

考慮到所有這些,方程式BP3和BP4很容易導出

Matrix VS Loop方法:

為了測試循環方法,我將運行數字識別程序,並 計算程序完成每個epoch所經過的秒數,以及測試的準確性數據。至於矩陣方法,我將運行相同代碼的修改版本,其中我已經實現了矩陣形式(https://github.com/hindkls/Matrix-Based-Backpropagation/blob/master/Network1.py)。

神經網絡從MNIST的訓練數據中學習,它有784個輸入神經元,10個輸出神經元和30個神經元的隱藏層。通過將我們的程序設置為運行超過30個epochs,學習率為η= 3.0且小批量大小為10,我們得到以下結果:

循環方法:

Looping over a mini-batch of size 10

--- 34.2879998684 seconds elapsed ---

Epoch 0: 9114 / 10000

--- 27.7209999561 seconds elapsed ---

Epoch 1: 9192 / 10000

--- 33.2569999695 seconds elapsed ---

Epoch 2: 9289 / 10000

...

--- 36.6579999924 seconds elapsed ---

Epoch 28: 9496 / 10000

--- 34.5559999943 seconds elapsed ---

Epoch 29: 9486 / 10000

矩陣方法:

Matrix approach with a mini-batch of size 10

--- 11.6560001373 seconds elapsed---

Epoch 0: 9090 / 10000

--- 11.375 seconds elapsed---

Epoch 1: 9273 / 10000

--- 11.4839999676 seconds elapsed---

Epoch 2: 9322 / 10000

...

--- 12.0789999962 seconds elapsed---

Epoch 28: 9486 / 10000

--- 11.3129999638 seconds elapsed---

Epoch 29: 9503 / 10000

通過比較結果,我們可以看到,使用矩陣方法處理每個epoch所經過的平均秒數遠小於使用循環方法所花費的時間。這是因為矩陣方法利用CPU和GPU中的並行性來加速計算。實現神經網絡的庫使用相同的方法,因為線性代數庫現在針對快速硬件進行了優化。

Mini-batch size

在本節中,我們將使用不同的Mini-batch size的值來看一下,看看它如何影響學習。為此,我們運行我們的程序(具有矩陣形式的程序)進行兩次試驗,第一次使用Mini-batch size等於1,第二次使用Mini-batch size等於600。

第一次:

Mini-Batch size = 1

--- 78.3759999275 seconds elapsed---

Epoch 0: 7669 / 10000

--- 81.4859998226 seconds elapsed---

Epoch 1: 8382 / 10000

--- 85.0969998837 seconds elapsed---

Epoch 2: 8311 / 10000

...

第二次:

Mini-Batch size = 600

--- 63.4069998264 seconds elapsed---

Epoch 0: 4206 / 10000

--- 67.6930000782 seconds elapsed---

Epoch 1: 5712 / 10000

--- 68.2200000286 seconds elapsed---

Epoch 2: 6570 / 10000

...

正如我們在這裡看到的,當我們運行一個小批量大小為600的程序時,學習速度要比當大小為1時快一些,但是準確度較低。這種行為背後的原因是,在第一次試驗中,權重的更新比第二次試驗要頻繁得多,因為它們是在處理完每個例子之後更新的,而在第二個試驗中,直到所有600個例子都被處理後,權重才會更新。那麼我們該怎麼做呢?我們是否應該選擇一個小的小批量尺寸並贏得準確性?還是用一個大的小批量生產,贏得速度卻失去精度?

我們需要做的,是找到一個速度和精度之間的折中的mini-batch size值,太小,我們不利用快速矩陣乘法,太大,我們不經常更新我們的權重。

現在,您可能認為學習速度與準確性並不重要,因為最終我們將達到良好的準確度,但請看一下我們運行的程序的結果是mini-batch size為10,你可以看到只要在第一個epoch,精度達到了90%,即權重沒有比大小等於1時更新很多。這與我們早先得出的結論並不矛盾。原因在於,當我們選擇一個小型批次大小等於1時,由於它對每個示例的影響都作出了響應,因此這種學習是最不明顯的。這就是為什麼選擇一個優化良好的mini-batch size,一方面可以幫助我們快速地收斂到一個好的最小值,因為我們確信權重是經常更新的,但是是以一種合理的方式更新的,另一方面可以利用快速矩陣庫。


分享到:


相關文章: