一. 前言
最近開始搞自動駕駛感知部分,將之前的總結的資料和筆記調出來看看,順便總結一下,留下記錄。
二. 神經網絡介紹
這里我們采用優達學城[1]上提供的例子,如下圖所示。
圖 1-1 圖 1-2 圖 1-3
上圖是根據grades和test的成績來判斷是否被大學錄取,綠色的圓表示錄取,紅色的圓表示拒絕錄取。
從上圖1-1可以看出,如果采用線性的方法區分紅色和綠色,采用一條直線直線的效果不好(圖1-2),所以需要用兩條直線區分(圖1-3)。
例如,如果一個學成的test的成績為1,grade的成績為8,那么根據圖1-3,該學生拒絕錄取,即,該學生的成績在藍色線的上方,但卻在黃色線的左側,所以拒絕錄取,可以如圖2表示
圖 2
這里我們總結一下所有錄取和拒絕錄取的情況,根據圖1-3可以分為四種情況,如下表
表1
test在黃線右側 | grade在藍線上方 | 結果 |
真 | 真 | 錄取 |
真 | 假 | 拒絕 |
假 | 真 | 拒絕 |
假 | 假 | 拒絕 |
通過表1可以看出,圖2是“AND”(“與”)的關系。圖2就是一個簡單神經網絡。
根據不同的場景,最后的關系可以是“OR”,“XOR”,甚至可以自定義邏輯關系等等。
那么我們怎樣判斷test在黃線的右側,grade在藍線的上方呢?實際上就是我們接下來要聊的神經元(感知機)
三. 感知機
圖2中, 中間的兩個方框中的節點實際上就是感知機(神經元),他們構成了神經網絡的基本單元,每個感知機按照輸入決定數據的分類。
那么,感知機是如何決定test在黃線的右側,grade在藍線的上方呢?事實上初始神經網絡吧並不知道輸入的test,或者grade在什么位置,即並不清楚圖1-3的藍線與黃線的位置,需要我們根據數據做出調整,這個過程就是“訓練”。
訓練神經網絡的過程,實際上就是在確定藍線與黃線的位置。
直線的方程在二維坐標系下可以寫成:0 = w1 × x1 + w2 × x2 + b, 如果給出的x1與x2在直線的上方/右側(上方與右側等價),那么w1 × x1 + w2 × x2 + b > 0,否則<0。這里w1, w2, b就是神經網絡中常用的權重,x1與x2分別代表圖2中的test與grade數據。通過不停的帶入test與grade數據,調整w1, w2, b訓練整個神經網絡。
圖2的兩個感知機都包含了0 = w1 × x1 + w2 × x2 + b的一個線性方程。
圖2是針對二維坐標系的例子,如果是n維數據,那么可以寫成和函數(summing function):
最后感知機要把和函數轉換成輸出信號,這里即1與0(“真”與“假”)。通常通過激活函數(activation function)實現。常用到的激活函數
我們常用的激活函數有:
(1)單位階躍函數:和函數小於 0,函數返回 0,如果和函數等於或者大於 0,函數返回 1。
(2)sigmoid函數[2]
(3)tanh函數
(4)softmax函數[3]
我們常采用sigmoid函數作為激活函數。
這樣我們就得到了我們簡單的感知機模型,如下圖所示:
這里我們解決了神經網絡每個節點的構成,接下來我們着重介紹,神經網絡的訓練方法,也就是權重的學習。
四. 權重調整
因為神經網絡的初始隨機權重不能滿足我們的需求,所以我們需要通過正確的數據不斷調整我們網絡中的權重,這個過程就是訓練。
目前訓練采用的主流方法就是梯度下降,權重調整的目的是使目標函數的輸出,趨近於真值。
4.1 目標函數
訓練的目的就是通過帶入真實數據調整權重,使輸出趨近於真值。所以為了能夠衡量,我們需要有一個指標來了解預測與實際的差別,也就是誤差(真值與計算結果的差異)。一個普遍的指標是誤差平方和 sum of the squared errors (SSE)
舉例一個單個感知機來解釋(以下的推導過程都是基於單個感知機):
圖3
ŷ表示感知機輸出,y表示真值。
首先,我們想知道我們初始的感知機的輸出與真值之間的誤差,希望誤差全部為正,便於累加,誤差可以表示為
※※不采用絕對值的原因是,對於較大的誤差可以通過平方放大其誤差,從而帶來放大懲罰值,同時采用平方的形式有利於我們后面的數學運算(求導)。
上面的E僅僅代表了單個數據的誤差,如果我們想要得到整體數據的誤差,可以所有誤差進行累計,即
每一行的x和y的對應元素代表μ(x,y的上角標)。我們得到了整體數據的誤差E,即誤差平方和 (SSE)。ŷ是由激活函數得到,1/2方便計算導數,μ用於表示整體數據。比如
這樣針對權重wi 的優化目標函數E已經得到。從上式可以看出,E取決於權重wi 與輸入 xiμ。如果E的值比較大,那么預測的結果比較差,如果E較小,那么預測的結果會比較好。所以我們希望E越小越好。
這時我們要優化的所有函數可以表示為
其中
4.2 梯度下降[4]
針對4.1節中提到的優化函數方法有很多,我們這里着重講解梯度下降。實際上不需要了解梯度下降的數學細節,知道結果就好,因為好多工具幫大家實現了梯度下降,而且包含了很多方法[4]。
由於初始的E比較大,我們希望E變得越來越小,而且變小的速度還要夠快,所以我們利用導數,來計算梯度下降對快的方向,下降的方向與導數相反。我們只需每次累加梯度下降的方向。如圖4所示
圖4
梯度下降的方法有很多,這里選用隨機梯度下降SGD[4]。由於隨機梯度下降的核心:用樣本中的一個例子來近似我所有的樣本,調整權重,所以導數只需求解單個樣本即可,不需要包含∑符號。針對4.1的目標函數,采用鏈式求導法則有
α為學習速率(learning rate),包含了方向(正負號),用來控制下降的速度。鏈式求導在下面要說到的反向傳遞也要用到,正因為有鏈式求導,神經網絡的層數才可以增加,深度學習才可以方便調整參數。由於我們采用sigmoid函數作為激活函數f(h),sigmoid函數的導數為:f'(h) = f(h)(1 - f(h)) = ŷ(1 - ŷ)。
為了表達簡單,迭代過程化簡為:
δ實際上表示誤差項,即用於衡量輸出的誤差。
隨機梯度下降SGD的過程pipeline表示為:
- 權重步長設定為 0:Δwi = 0 對訓練數據中的每一個樣本:
- 通過網絡做正向傳播,計算輸出:ŷ = f(h)
- 計算輸出單元的誤差項:δ
- 更新權重步長:Δwi = Δwi + δxi更新輸入對應權重
- 更新權重:wi+1 = wi + αδxi
- 重復上面迭代,直至迭代步數結束。
上面的闡述僅僅圍繞着神經網絡中一個節點進行,單層多節點的神經網絡類似,但是多層神經網絡(深度學習)要復雜一些,涉及到神經網絡核心——反向傳播。
4.3 反向傳播
我們已了解了使用梯度下降來更新單個節點權重,反向傳播算法則是它的一個延伸。用以更新多層神經網絡的參數,反向傳播同樣基於鏈式求導法則,。
網絡上有個一很不錯的例子,我用這個例子[5]講解一下反向傳播。
這個神經網絡有兩個輸出,一層隱含層(兩個節點),兩個輸入。
第一層是輸入層,包含兩個神經元i1,i2,和截距項b1;第二層是隱含層,包含兩個神經元h1,h2和截距項b2,第三層是輸出o1,o2,每條線上標的wi是層與層之間連接的權重,激活函數同樣使用sigmoid函數。
初始值為:
輸入數據: i1=0.05, i2=0.10;
輸出數據: o1=0.01, o2=0.99;
初始權重: w1=0.15, w2=0.20, w3=0.25, w4=0.30; w5=0.40, w6=0.45, w7=0.50, w8=0.55;
目標:給出輸入數據i1, i2(0.05和0.10),使輸出盡可能與原始輸出o1, o2(0.01和0.99)接近
這里先列出了前向傳播及目標函數的所有公式
(上述公式建議從下往上看)其中,Etotal為總的誤差,Eo1與Eo2分別為兩個輸出的誤差SSE,yo1與yo2分別為兩個目標輸出,ŷo1與ŷo2分別為神經網絡輸出,ŷh1與ŷh2分別為兩個隱藏層輸出,w1~w8分別為要調整的權重,x1與x2分別為兩個輸入。
我們的目標通過通過輸入調整參數w1~w8使得輸出接近目標輸出。根據我們在4.2節中發現核心實際上是得到每次迭代后的Δwi 。
那么根據4.2節的內容,從隱藏層到輸出的參數Δw5~Δw8,采用鏈式求導可以計算為
δo實際上表示輸出層誤差項。
到輸出的權重更新完成后,接下來更新隱藏層權重,
隱含層的權重更新,需要知道各隱藏層節點的誤差對最終輸出的影響。每層的輸出是由兩層間的權重決定的,兩層之間產生的誤差,按權重縮放后在網絡中向前傳播。既然我們知道輸出誤差,便可以用權重來反向傳播到隱藏層的權重Δw1~Δw4。
δoh實際上表示輸出層誤差項。
講反向傳播采用類似隨機梯度下降的方式,則反向傳播的pipeline可以寫成:
- 隨機設置初始權重
- 對訓練數據當中的每一個樣本,
- 讓它正向傳播通過網絡,計算輸出:ŷ ;
- 計算輸出節點的誤差項:δo ;
- 誤差傳播到隱藏層的誤差項:δoh ;
- 更新權重步長:
- 輸出層節點權重更新:Δwo = Δwo + δŷh ;
- 隱藏層節點權重更新:Δwh = Δwh + δŷh ;
- 第一層節點權重更新:Δwi = Δwi + δxi ;
- 更新權重:
- wi+1 = wi + αΔw
- 重復這個過程,直至迭代步數結束 。
※※從這里可以看出,誤差項是從輸出層權重更新,逐層傳播到隱藏層權重更新。
※※從公式同樣可以看出,如果函數中的每個值都經過前向傳播計算得到,實際上反向傳播每個值的計算是相互獨立的,這就為並行計算(GPU)提供了條件,這也就是深度學習為什么可以采用GPU計算的原因。
※※我們采用的誤差項計算是通過sigmoid求導得到的,f'(h) = f(h)(1 - f(h)),從導數的公式可以看出,sigmoid的導數最大值為0.25,在求導過程中,數值會越來越小,對產生梯度消失。所以在深度學習采用如reLu等激活函數。
參考資料
[2] https://www.cnblogs.com/hgl0417/p/5902042.html
[3] https://www.cnblogs.com/hgl0417/p/6670913.html
[4] https://www.cnblogs.com/hgl0417/p/5893930.html
[5] https://blog.csdn.net/weixin_38347387/article/details/82936585