R語言自學日記(22)-深度學習(一):神經網絡

Edward Tung
R 語言自學系列
11 min readSep 14, 2018

Introduction of Neural Networks in Deep Learning

前言:深度學習的概念

深度學習是機器學習的一個分支,某種程度上是一種透過多層結構化與感知器建立來達成特徵抽取的技術。這麼說很抽象,簡單來說,我們在機器學習中了解到要建立一個好的模型,我們必須要輸入正確的特徵,但是生活中有很多問題是我們難以確認或是建構特徵的。

舉例來說,我們都知道要判斷一張照片是狗還是貓有很多方式,比方你看他的體型、耳朵或尾巴的形狀等等,但是,你要怎麼告訴電腦這件事?當每一張圖片的耳朵都出現在不同位置,尾巴彎曲的方向都不一樣,要怎麼樣才能讓機器自動去了解到每張圖片的特徵應該要怎麼抓取呢?

Source:NCIA Lab

可能很多人看過類似的示意圖,這是深度學習技術應用在圖像辨識的範例,概念上是讓電腦分區塊處理圖片,透過一系列的感知器傳導以後輸出結果,這樣的好處在於,電腦本身可以自動去抓取到特徵出現的位置,並根據後續的演算法去辨識出圖片該歸屬於哪個分類。

以上的演算法實際展開會變得比較複雜,但有幾個共同的基礎是固定的,這是一個建立在神經網絡之上的算法,因此,我們就要先介紹這些在深度學習中非常重要的元素:

感知器(Perceptron)

甚麼是感知器?簡單來說就是接收訊號和流出訊號的地方,我們可以把他想像成神經元,通過接收訊號,處理訊號以後將訊號傳遞出去:

Source:CodeProject.com

建構感知器的過程中,處理訊號的神經本體(就是程式裡頭的Function)會有所謂的權重(weight)與偏權值(bias),舉例來說我建立一個節點,會根據輸入資料大小去調配權重,資料值越大我們就認為他越重要,這個權重就是他數字本身,比方說5就會變成5*5,以此類推,則:

這就是一個簡單的感知器,但這樣的感知器為甚麼重要呢?實際上是因為一個概念叫做閘(Gate),它的設計使我們可以讓整個感知器根據情況流出不同的結果,舉例來說,我們可以創建一個OR Gate:

如果輸入的兩個值經過權重運算超過0,我們就輸出1,否則就輸出0,換言之,如果x1或x2其中一個為1,我們就輸出1,而這樣的組合有很多種,比方說AND Gate,NAND Gate等等,然而有一個例外,我們沒有辦法輸出一個排他邏輯的感知器,也就是XOR Gate,我們只有在其中一個為1的時候才輸出1,如果兩個都是1的話,就一樣輸出0。

因此,我們就需要建立多層感知器(Multiple Layer Perceptron),也就是我們說的MLP演算法,這時候就可以讓機器回答複雜的問題了,也就是根據情況,感知器會有不同的輸出輸入,而這個就變成我們接下來要談到的神經網絡的原型。

神經網絡(Neural Networks)與活化函數(Activation Function)

建立在多層感知器之上,我們就可以建構出一個神經網絡,神經網絡可以有很多層(layers),有一些是我們看不見的隱藏層(Hidden Layer),是電腦根據某種模式生成的,因此最後就會長得像這樣:

Source:http://cs231n.github.io

其中我們要介紹一個概念叫做激活函數/活化函數(Activation Function),這個函數的作用決定了節點的Output應該如何被輸出,舉例來說我們今天有非常多節點,但是為了要統一這些訊號總和進入下一層的Layer,避免這些輸出值最後變成輸入值的線性組合,我們會加上一個Activation Function來整流這些訊號,否則我們也不需要繼續了,因為不管多少層資料的變化都是均勻的,因此整體來說會圖示如下:

上面的x1~xn的輸入資料在經過權重運算之後(Net Function),會在輸入到一個Activation Function中去做訊號的篩選。這樣的活化函數有很多種,這邊我們介紹兩個函數分別是ReLU與Softmax:

ReLU函數全名叫做線性整流函數,在輸入資料小於0的時候我們就回傳0,當資料大於0的時候就輸出那筆資料,這個函數的起源是神經科學家在模擬腦神經元接受訊號時,發現輸出的訊號具有稀疏性(Sparse,可以想像成資料中有非常多0)。

Source:Wikipedia

稀疏性之所以重要,原因在於他暫時性抑制了某一部分不重要的資料,以便於我們可以從被Activated的資料中挖掘出特徵,ReLU函數是一個平滑變化的函數,因此現在被廣泛用於解決如迴歸問題等連續型數值預測與擬合。簡單來說,我們抑制住不重要的資料,只針對有用的資料去挖掘。

SoftMax函數則是進行多分類問題是非常有用的函數,原因是他對於離散機率分布的函數進行整合,一個SoftMax函數會像這樣:

Source : Wikipedia
模擬出來的SoftMax函數圖

這個函數通常被放在最後一層,比如我自己的習慣是會把非最後一層的資料放入ReLU,而最後一層放入Softmax以作為多分類器的活化函數,如果大家對Logistic函數有了解過,就會很容易發現兩者之間的關聯。總而言之,SoftMax是強制將一個K維度的資料以指數的方式去壓縮在(0,1)之間,而全部的總和為1,我們就會得到選到第X種分類的機率結果。但是這有一個問題,隨著神經元輸出越來越接近極值(該函數值域下),學習速度會越慢,關於這個原因可以看以下的延伸閱讀:

我們必須引入一個概念叫做交叉熵(Cross-Entropy)來作為深度學習上應用的損失函數,跟物理學到熵的概念比較不同,物理上說具有高熵的物體是比較不規則、雜亂的,而資訊上則稱具有高信息熵才可以涵蓋更多的資訊輛,具體怎麼計算交叉熵,一個交叉熵的計算方式為:

Source:Wikipedia,分別是離散分配與連續分配

我們可以考慮x1, x2, x3三種可能出現的情況,機率分別是1/4, 1/2, 1/4,則,x1與x3的交叉熵為-1/4*log(3/4) = 0.031,x2交叉熵為-1/2*log(1/2)=0.151,這時候我們說x2的不確定性比較高,也就是你很難確定他會不會出現(因為機率各1/2),但x1, x3的不確定性比較低,因為它們四次中有三次是不會出現的,你比較好預測這個結果。

而透過對於這些標籤(也就是預測出來的分類),我們會得到他們的預測機率,根據這些機率去建構損失函數,我們就可以完整的透過這個神經網絡來做分類預測了!

反向傳播(Backpropagation)

我們還有一個沒有解決的問題是,程序如何去針對網絡中每一層的權重做出最優化?我們知道一開始在沒有了解所有資料以前,程序只能夠一次針對一部分的資料去做學習並作權重優化,這個行為我們叫做小批次學習(Small-batch learning),並且透過梯度法更新出參數。(有人說為甚麼不要一次扔全部的數據集是因為,電腦通常不會有這麼高的內存,而且非常沒有效率)

另外一個想法是反向傳播法(Backward Pass/ Backpropagation),這個概念是在得到算法結果以後,透過鏈鎖律(Chain Rule)迭代的方式,我們圖示如下,假設有一個客戶A,他有許多的特徵(比如當期保費金額、儲蓄相對資產比率、簽約種類等),想要預測他下一期可能會繳多少保費:

「backpropagation」的圖片搜尋結果
Source: Mayank Agarwal, Medium

這是一種監督式學習的方法,舉例來說,我們知道一個客戶A他的下期保險簽約金是10000元,我們可以猜測說WX+b = 10000,但我們要怎麼調整權重W好讓這個WX+b可以最好的擬合我們的結果呢?(注意這邊的資料通常是很多筆,數學上是一個矩陣)

我們需要將回傳的訊號分別乘上對輸入特徵x1, x2的微分值,根據上圖,我們知道可以根據鏈鎖律去得到結果,我將詳細的步驟當成延伸閱讀放在下方,這邊就不一步步推導了:

總而言之,反向傳播提供了另外一種方法來優化我們的權重,通常這個方法的計算要比數值微分能夠更快找到梯度最小值,也就是更快速確認模型權重,我們當然也可以進一步去比較兩個方法估計出來的參數差異,去確認兩者之間有沒有差異,稱之為數值檢查。

建立深度學習迴歸模型(Keras Regressor)

說了這麼多,我們先把上面的步驟執行一遍看看,在這邊先介紹一下我們要使用的套件,深度學習框架中最著名的就是由Google推出的開源機器系統Tensorflow以及建立在之上,用Python撰寫的Keras Package。

在這邊我們要使用Keras來建立我們的模型,原因是雖然兩者都可以做到一樣的事情,Keras被編寫得比較User-friendly,比較簡短的代碼方便使用者建構模型,雖然某種程度上它的速度還是遜色於更底層的Tensorflow。

一樣,我們用落後一期的台積電股價來判斷,首先下載Keras,並且建立一個兩層的Network,隱藏層的節點數為5,活化函數使用ReLU。

Two-layer Keras Sequential Model

接著我們將這個空的神經網絡加入優化器、損失函數等,我在這邊先不提及優化器(Optimizer),實際上就是一種更新參數的方式而已,比方我們早先提過的梯度下降等,有興趣的朋友可以自行搜索,這邊我們設定為adam。最後,我們來擬合這個模型,迭代次數epoch設定為100,也就是迭代100次,並且設定批次學習數量為100,也就是一次學習100筆資料,代碼如下:

我們可以看到損失函數下降的過程,大概在10次以內就收斂得差不多,最後,我們再針對lag1資料進行預測,並跟實際資料作圖看看。

結尾

下一篇我們要進一步拓展到RNN(Recurrent Neural Network)模型,並且提及長短期記憶模型(LSTM),這是一個不僅僅在時間序列,也在目前火熱的翻譯系統上廣泛應用的深度學習模型。如果你喜歡我的文章,還請下方按Clap喔!預計下一篇是最後一篇了,之後還會有兩篇自學心得。

推薦閱讀書目:

Deep Learning:用Python進行深度學習的基礎理論實作 斎藤康毅

--

--

R 語言自學系列
R 語言自學系列

Published in R 語言自學系列

About a self-taught diary on R Language programming and practical Time Series Analysis, made by a python user and BBA student. Hope you like it:)

Edward Tung
Edward Tung

Written by Edward Tung

Columbia Student || 2 yrs of data scientist and 1 yr of business consultant experience