[翻譯] Deep Dive into Math Behind Deep Networks

Deep Dive into Math Behind Deep Networks

本文翻譯自 https://towardsdatascience.com/https-medium-com-piotr-skalski92-deep-dive-into-deep-networks-math-17660bc376ba

作者的GitHub: https://github.com/SkalskiP

這個年頭,有KerasTensorFlow 或 PyTorch 之類的高階函式庫跟框架,我們不需要去煩惱權重矩陣的大小或是去記那些觸發函數的導數公式什麼的。大部份的情況下,我們在建一個神經網路,即使是結構很複雜的,也只需要import一些東西跟幾行程式碼就搞定。這樣可以讓我們在找bug或是改善流程的時候,省下好幾個小時的時間。然而,對於發生在神經網路內部的事情,如果有足夠的知識,對我們在挑選結構、超參數跟最佳化的時候,是非常有幫助的。

Introduction 導論

為了多了解神經網路的原理,我決定在這暑假花一些時間看看隱藏在表面下的數學。我也決定寫一篇文章,一部份是為了我自己(組織新學到的東西),一部份是為了別人(幫他們了解困難的概念)。對那些不喜歡代數或微積分的人,我會試著盡可能溫和一點,但就像標題寫的,這是個很多數學的文章。

圖 1. Training set的視覺化

做為一個例子,我們來解這個圖1所示資料集的二分類問題。每個點都屬於兩個類別所形成的圓圈,這種排列對很多傳統的機器學習演算法來說,都很不方便,但是一個小小的神經網路可以跑的很好。要解這問題,我們會用一個長的如圖2的神經網路結構,5層的全連接層,每層的節點數不一。在隱藏層,我們用ReLU做為觸發函數,對輸出層則是使用Sigmoid。這是個簡單的結構,但足夠複雜到做為深入思考的例子。

圖2. 神經網路結構

KERAS solution 使用KERAS的方案

首先,我會展示用最受歡迎的機器學習函式庫之一的KERAS做的方案

就就就就這樣而己啊!如我在前面說的,一些imports跟幾行程式碼就足以建立跟訓練一個模型,而這模型能夠分類整個test set且達到幾乎100%的準確率。我們的工作濃縮成依據選定的結構提供超參數(hyperparameters)而已,超參數指的是像層的數量、每層的神經元數量、觸發函數或是epoch數量等等。讓我們來看看背後發生了什麼事。喔,在學習階段我做了一個很酷的視覺化,希望能讓你不要睡著。


圖3. 在訓練過程中,合格的區域的視覺化

What are neural networks? 什麼是神經網路

讓我們從這個關鍵問題開始:「什麼是神經網路?」其實就是個由生物學啟發的方法,用來建立具有學習能力、能夠獨立尋找資料間的關係的電腦程式。像圖2顯示出來的,網路就是軟體的「神經元」用層的形式組合來的,每一層用一種可以溝通的方式連結起來。

Single neuron 單一個神經元

每個神經元接收一堆 x 值的集合(1到n)做為輸入,然後計算預測的y-hat值。x向量其實包含的是特徵的值,特徵是從一個樣本而來,樣本是在包含m個樣本的訓練資料集裡面。每個單元都有自己的參數集合,用來改變學習過程,通常用w(權重的column vector)跟b(偏移量)來表示。在每次迭代,神經元會基於它目前的w,加上b,來計算x的值的加權平均。最後把計算結果傳給一個非線性觸發函數g,在這文章的後面我會稍微提一下最受歡迎的觸發函數。

圖 4. 單一神經元

Single layer 單一個層

現在讓我們離遠一點點,來看神經網路的一個層是怎麼執行計算的。要用我們對單一單元內部發生什麼事的知識,還有把層向量化之後,結合這些計算結果為一個矩陣等式。先把符號一致化,這些等式是寫給選定的層[l]。下標的i標記了這層的神經元的順序。

圖5. 單層

還有一件事:當我們對一個單元寫等式,我們用x跟y-hat,用以表示特徵的column vector跟預測值。當切換到層的表示時,我們用向量a,代表了那個層的觸發。而向量x則是第0層的觸發,也就是輸入層。每個層裡的神經元做的計算都跟這個式子差不多:

不夠清楚,我們把第2層的式子0寫下來:

一如你所看到的,每一層跑的運算都差不多。在這裡用for迴圈並不是很有效率,所以我們在這裡用向量化來做加速。首先,把轉置後的權重w的水平向量疊起來,我們可以建一個矩陣W。同樣的,我們可以把個神經元的偏移值疊起來,建一個垂直向量b。現在沒有什麼能阻止我們建一個矩陣等式來讓我們一次為所有層的全部神經元執行計算。讓我們把會用到的矩陣跟向量的維度寫下來。

Vectorizing across multiple examples 對多樣本向量化

目前我們看到的等式,只牽涉到一個樣本。在神經網路的學習過程中,通常會用到百萬個樣本。接下來的步驟會做多個樣本的向量化。假設我們的資料集合有m個樣本,每個樣本有nx個特徵。首先,我們把每一層的垂直向量x, a, z放在一起,弄成X, A, Z矩陣。然後我們把前面的算式拿來應用剛建好的矩陣。

What is activation function and why do we need it? 什麼是觸發函數,為什麼我們需要這東西?

觸發函數是神經網路的關鍵元素之一。如果沒有觸發函數,神經網路就只是線性函數的組合,線性函數的組合是什麼?還是個線性函數。模型的擴展性變得很有限,不會比邏輯迴歸好。這種非線性的元素不只提供了很大的彈性,也在學習過程中提供了建立複雜函數的可能。觸發函數同時也是學習速度的關鍵影響,在選用的時候要特別注意。圖6顯示了一些常用的觸發函數。目前,ReLU可能是最常用的。我們仍然會用sigmoid,尤其是當我們要處理二分類問題,同時希望輸出值介於0到1之間時,在輸出層會使用sigmoid。

圖 6. 最常用的觸發函數跟它們的導數

Loss function 損失函數

學習的基本資訊是來自於Loss function。一般而言,loss function用來衡量我們跟理想答案的差距有多遠。我們這裡用的是binary cross entropy,依不同的問題,可以應用不同的函數。我們使用的函數說明如下,在學習過程中的變化顯示在圖7。可以看到隨著迭代,loss function的值降低而準確率變高。

圖7. 在學習過程中,準確率與loss function值的變化

How do neural networks learn? 神經網路怎麼學習的?

所謂學習就是去改變Wb的值,讓loss function最小化。為了達成這個目的,我們需要微積分跟梯度下降法來找到最小值。每次迭代,我們要去計算loss function對神經網路參數的偏微分。對於不熟悉這些計算的人,我只提一下這個偏微分有個神奇的能力,可以描述函數的坡度。感謝有這些技術,我們知道如何去調整參數來移動到圖的山谷區。為了在直覺上建構出梯度下降法怎麼做(同時也避免你們又睡著),我準備了一個小小的視覺化。你可以看到,隨著epoch一直走,我們如何朝向最小值前進。在我們的神經網路,它做的事情也是一樣,每次迭代時的梯度計算,告訴了我們該往哪裡移動。差別只是在我們實驗的神經網路中,我們有更多參數要調整。重點是,怎麼計算這麼複雜的導數?

Figure 8. Gradient descent in action

Backpropagation 後向傳播

Backpropagation是我們需要用來計算複雜梯度的演算法。神經網路的參數是依照下面的方程式來調整。

在上面的等式中,α 是學習率,用來控制調整量的一個超參數。選擇學習率是很麻煩的,設太小,神經網路學得很慢,設太大,可能會找不到最小值。計算dWdb是loss function對Wb的偏微分,用連鎖規則來計算。dWdb的大小,跟Wb是一樣的。圖9顯示了神經網路的一連串操作。我們可以明顯看到前向傳播跟後向傳播協同工作來最佳化loss function值。

圖9. 前向與後向傳播

Conclusion 結論

希望我已經很好的解釋了神經網路裡的數學。了解這程序的最基本部份,在使用神經網路時是很很有幫助的。我覺得我提到的東西是最重要的部份,然而也只是冰山一角。我強烈建議你們去實作一個小網路,不要用框架,頂多只用Numpy。

如果你看到這裡,就恭喜啦,這不是個很好讀的東西。如果喜歡這文章,請在 Twitter 跟 Medium 上面追蹤我,也歡迎到 GitHub 跟 Kaggle 看看我正在做的專案。保持好奇心!

 

 

Leave a Reply

你的電子郵件位址並不會被公開。 必要欄位標記為 *