課程五 神經網絡(一)

@(斯坦福李飛飛深度學習上課筆記)

課程五 神經網絡(一)

內容列表:

1.不用大腦做類比的快速簡介
2.單個神經元建模
    2.1生物動機和連接
    2.2作爲線性分類器的單個神經元
    2.3常用的激活函數 
3.神經網絡結構
    3.1層組織
    3.2前向傳播計算例子
    3.3表達能力
    3.4設置層的數量和尺寸
4.小節

1. 快速簡介

在不訴諸大腦的類比的情況下,依然是可以對神經網絡算法進行介紹的。在線性分類一節中,在給出圖像的情況下,是使用s=Wx 來計算不同視覺類別的評分,其中W 是一個矩陣,x 是一個輸入列向量,它包含了圖像的全部像素數據。在使用數據庫CIFAR-10的案例中,x是一個[3072x1]的列向量,W 是一個[10x3072]的矩陣,所以輸出的評分是一個包含10個分類評分的向量。

神經網絡算法則不同,它的計算公式是s=W2max(0,W1x) 。其中W1 的含義是這樣的:舉個例子來說,它可以是一個[100x3072]的矩陣,其作用是將圖像轉化爲一個100維的過渡向量。函數max(0,) 是非線性的,它會作用到每個元素。這個非線性函數有多種選擇,後續將會學到。但這個形式是一個最常用的選擇,它就是簡單地設置閾值,將所有小於0的值變成0。最終,矩陣W2 的尺寸是[10x100],因此將得到10個數字,這10個數字可以解釋爲是分類的評分。注意非線性函數在計算上是至關重要的,如果略去這一步,那麼兩個矩陣將會合二爲一,對於分類的評分計算將重新變成關於輸入的線性函數。這個非線性函數就是改變的關鍵點。參數W_1,W_2將通過隨機梯度下降來學習到,他們的梯度在反向傳播過程中,通過鏈式法則來求導計算得出。

一個三層的神經網絡可以類比地看做s=W3max(0,W2max(0,W1x)) ,其中W1 ,W2 ,W3 是需要進行學習的參數。中間隱層的尺寸是網絡的超參數,後續將學習如何設置它們。現在讓我們先從神經元或者網絡的角度理解上述計算。

2. 單個神經元建模

神經網絡算法領域最初是被對生物神經系統建模這一目標啓發,但隨後與其分道揚鑣,成爲一個工程問題,並在機器學習領域取得良好效果。然而,討論將還是從對生物系統的一個高層次的簡略描述開始,因爲神經網絡畢竟是從這裏得到了啓發。

2.1 生物動機與連接

大腦的基本計算單位是神經元(neuron)。人類的神經系統中大約有860億個神經元,它們被大約10^14-10^15個突觸(synapses)連接起來。下面圖表的左邊展示了一個生物學的神經元,右邊展示了一個常用的數學模型。每個神經元都從它的樹突獲得輸入信號,然後沿着它唯一的軸突(axon)產生輸出信號。軸突在末端會逐漸分枝,通過突觸和其他神經元的樹突相連。

在神經元的計算模型中,沿着軸突傳播的信號(比如x_0)將基於突觸的突觸強度(比如w_0),與其他神經元的樹突進行乘法交互(比如w_0x_0)。其觀點是,突觸的強度(也就是權重w),是可學習的且可以控制一個神經元對於另一個神經元的影響強度(還可以控制影響方向:使其興奮(正權重)或使其抑制(負權重))。在基本模型中,樹突將信號傳遞到細胞體,信號在細胞體中相加。如果最終之和高於某個閾值,那麼神經元將會激活,向其軸突輸出一個峯值信號。在計算模型中,我們假設峯值信號的準確時間點不重要,是激活信號的頻率在交流信息。基於這個速率編碼的觀點,將神經元的激活率建模爲激活函數(activation function)f,它表達了軸突上激活信號的頻率。由於歷史原因,激活函數常常選擇使用sigmoid函數σ ,該函數輸入實數值(求和後的信號強度),然後將輸入值壓縮到0-1之間。在本節後面部分會看到這些激活函數的各種細節。

————————————————————————————————————————

Alt text
左邊是生物神經元,右邊是數學模型。
————————————————————————————————————————
一個神經元前向傳播的實例代碼如下:

class Neuron(object):
  # ... 
  def forward(inputs):
    """ 假設輸入和權重是1-D的numpy數組,偏差是一個數字 """
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid激活函數
    return firing_rate

換句話說,每個神經元都對它的輸入和權重進行點積,然後加上偏差,最後使用非線性函數(或稱爲激活函數)。本例中使用的是sigmoid函數σ(x)=1/(1+ex) 。在本節的末尾部分將介紹不同激活函數的細節。

粗糙模型:要注意這個對於生物神經元的建模是非常粗糙的:在實際中,有很多不同類型的神經元,每種都有不同的屬性。生物神經元的樹突可以進行復雜的非線性計算。突觸並不就是一個簡單的權重,它們是複雜的非線性動態系統。很多系統中,輸出的峯值信號的精確時間點非常重要,說明速率編碼的近似是不夠全面的。鑑於所有這些已經介紹和更多未介紹的簡化,如果你畫出人類大腦和神經網絡之間的類比,有神經科學背景的人對你的板書起鬨也是非常自然的。如果你對此感興趣,可以看看這份評論或者最新的另一份

2.2 作爲線性分類器的單個神經元

神經元模型的前向計算數學公式看起來可能比較眼熟。就像在線性分類器中看到的那樣,神經元有能力“喜歡”(激活函數值接近1),或者不喜歡(激活函數值接近0)輸入空間中的某些線性區域。因此,只要在神經元的輸出端有一個合適的損失函數,就能讓單個神經元變成一個線性分類器。

二分類Softmax分類器。舉例來說,可以把σ(Σiwixi+b) 看做其中一個分類的概率P(yi=1|xi;w) ,其他分類的概率爲P(yi=0|xi;w)=1P(yi=1|xi;w) ,因爲它們加起來必須爲1。根據這種理解,可以得到交叉熵損失,這個在線性分一節中已經介紹。然後將它最優化爲二分類的Softmax分類器(也就是邏輯迴歸)。因爲sigmoid函數輸出限定在0-1之間,所以分類器做出預測的基準是神經元的輸出是否大於0.5。

二分類SVM分類器。或者可以在神經元的輸出外增加一個最大邊界折葉損失(max-margin hinge loss)函數,將其訓練成一個二分類的支持向量機。

理解正則化。在SVM/Softmax的例子中,正則化損失從生物學角度可以看做逐漸遺忘,因爲它的效果是讓所有突觸權重w在參數更新過程中逐漸向着0變化。

一個單獨的神經元可以用來實現一個二分類分類器,比如二分類的Softmax或者SVM分類器。

常用激活函數

每個激活函數(或非線性函數)的輸入都是一個數字,然後對其進行某種固定的數學操作。下面是在實踐中可能遇到的幾種激活函數:
Alt text
左邊是Sigmoid非線性函數,將實數壓縮到[0,1]之間。右邊是tanh函數,將實數壓縮到[-1,1]。
————————————————————————————————————————
Sigmoid。sigmoid非線性函數的數學公式是σ(x)=1/(1+ex) ,函數圖像如上圖的左邊所示。在前一節中已經提到過,它輸入實數值並將其“擠壓”到0到1範圍內。更具體地說,很大的負數變成0,很大的正數變成1。在歷史上,sigmoid函數非常常用,這是因爲它對於神經元的激活頻率有良好的解釋:從完全不激活(0)到在求和後的最大頻率處的完全飽和(saturated)的激活(1)。然而現在sigmoid函數已經不太受歡迎,實際很少使用了,這是因爲它有兩個主要缺點:

Sigmoid函數飽和使梯度消失。sigmoid神經元有一個不好的特性,就是當神經元的激活在接近0或1處時會飽和:在這些區域,梯度幾乎爲0。回憶一下,在反向傳播的時候,這個(局部)梯度將會與整個損失函數關於該門單元輸出的梯度相乘。因此,如果局部梯度非常小,那麼相乘的結果也會接近零,這會有效地“殺死”梯度,幾乎就有沒有信號通過神經元傳到權重再到數據了。還有,爲了防止飽和,必須對於權重矩陣初始化特別留意。比如,如果初始化權重過大,那麼大多數神經元將會飽和,導致網絡就幾乎不學習了。
Sigmoid函數的輸出不是零中心的。這個性質並不是我們想要的,因爲在神經網絡後面層中的神經元得到的數據將不是零中心的。這一情況將影響梯度下降的運作,因爲如果輸入神經元的數據總是正數(比如在f=w^Tx+b中每個元素都x>0),那麼關於w的梯度在反向傳播的過程中,將會要麼全部是正數,要麼全部是負數(具體依整個表達式f而定)。這將會導致梯度下降權重更新時出現z字型的下降。然而,可以看到整個批量的數據的梯度被加起來後,對於權重的最終更新將會有不同的正負,這樣就從一定程度上減輕了這個問題。因此,該問題相對於上面的神經元飽和問題來說只是個小麻煩,沒有那麼嚴重。

Tanh。tanh非線性函數圖像如上圖右邊所示。它將實數值壓縮到[-1,1]之間。和sigmoid神經元一樣,它也存在飽和問題,但是和sigmoid神經元不同的是,它的輸出是零中心的。因此,在實際操作中,tanh非線性函數比sigmoid非線性函數更受歡迎。注意tanh神經元是一個簡單放大的sigmoid神經元,具體說來就是:tanh(x)=2σ(2x)1

————————————————————————————————————————

Alt text
左邊是ReLU(校正線性單元:Rectified Linear Unit)激活函數,當x=0 時函數值爲0。當x>0 函數的斜率爲1。右邊是從 Krizhevsky等的論文中截取的圖表,指明使用ReLU比使用tanh的收斂快6倍。

————————————————————————————————————————

ReLU。在近些年ReLU變得非常流行。它的函數公式是f(x)=max(0,x) 。換句話說,這個激活函數就是一個關於0的閾值(如上圖左側)。使用ReLU有以下一些優缺點:

1.優點:相較於sigmoid和tanh函數,ReLU對於隨機梯度下降的收斂有巨大的加速作用( Krizhevsky 等的論文指出有6倍之多)。據稱這是由它的線性,非飽和的公式導致的。
2.優點:sigmoid和tanh神經元含有指數運算等耗費計算資源的操作,而ReLU可以簡單地通過對一個矩陣進行閾值計算得到。
3.缺點:在訓練的時候,ReLU單元比較脆弱並且可能“死掉”。舉例來說,當一個很大的梯度流過ReLU的神經元的時候,可能會導致梯度更新到一種特別的狀態,在這種狀態下神經元將無法被其他任何數據點再次激活。如果這種情況發生,那麼從此所以流過這個神經元的梯度將都變成0。也就是說,這個ReLU單元在訓練中將不可逆轉的死亡,因爲這導致了數據多樣化的丟失。例如,如果學習率設置得太高,可能會發現網絡中40%的神經元都會死掉(在整個訓練集中這些神經元都不會被激活)。通過合理設置學習率,這種情況的發生概率會降低。

Leaky ReLU。Leaky ReLU是爲解決“ReLU死亡”問題的嘗試。ReLU中當x<0時,函數值爲0。而Leaky ReLU則是給出一個很小的負數梯度值,比如0.01。所以其函數公式爲f(x)=1(x<0)(αx)+1(x>=0)(x) 其中\alpha是一個小的常量。有些研究者的論文指出這個激活函數表現很不錯,但是其效果並不是很穩定。Kaiming He等人在2015年發佈的論文Delving Deep into Rectifiers中介紹了一種新方法PReLU,把負區間上的斜率當做每個神經元中的一個參數。然而該激活函數在在不同任務中均有益處的一致性並沒有特別清晰。

Maxout。一些其他類型的單元被提了出來,它們對於權重和數據的內積結果不再使用f(w^Tx+b)函數形式。一個相關的流行選擇是Maxout(最近由Goodfellow等發佈)神經元。Maxout是對ReLU和leaky ReLU的一般化歸納,它的函數是:max(w1Tx+b1,w2Tx+b2) 。ReLU和Leaky ReLU都是這個公式的特殊情況(比如ReLU就是當w_1,b_1=0的時候)。這樣Maxout神經元就擁有ReLU單元的所有優點(線性操作和不飽和),而沒有它的缺點(死亡的ReLU單元)。然而和ReLU對比,它每個神經元的參數數量增加了一倍,這就導致整體參數的數量激增。

以上就是一些常用的神經元及其激活函數。最後需要注意一點:在同一個網絡中混合使用不同類型的神經元是非常少見的,雖然沒有什麼根本性問題來禁止這樣做。

一句話:“那麼該用那種呢?”用ReLU非線性函數。注意設置好學習率,或許可以監控你的網絡中死亡的神經元佔的比例。如果單元死亡問題困擾你,就試試Leaky ReLU或者Maxout,不要再用sigmoid了。也可以試試tanh,但是其效果應該不如ReLU或者Maxout。

3.神經網絡結構

3.1 靈活地組織層

將神經網絡算法以神經元的形式圖形化。神經網絡被建模成神經元的集合,神經元之間以無環圖的形式進行連接。也就是說,一些神經元的輸出是另一些神經元的輸入。在網絡中是不允許循環的,因爲這樣會導致前向傳播的無限循環。通常神經網絡模型中神經元是分層的,而不是像生物神經元一樣聚合成大小不一的團狀。對於普通神經網絡,最普通的層的類型是全連接層(fully-connected layer)。全連接層中的神經元與其前後兩層的神經元是完全成對連接的,但是在同一個全連接層內的神經元之間沒有連接。下面是兩個神經網絡的圖例,都使用的全連接層:
————————————————————————————————————————
Alt text

左邊是一個2層神經網絡,隱層由4個神經元(也可稱爲單元(unit))組成,輸出層由2個神經元組成,輸入層是3個神經元。右邊是一個3層神經網絡,兩個含4個神經元的隱層。注意:層與層之間的神經元是全連接的,但是層內的神經元不連接。

————————————————————————————————————————

命名規則。當我們說N層神經網絡的時候,我們沒有把輸入層算入。因此,單層的神經網絡就是沒有隱層的(輸入直接映射到輸出)。因此,有的研究者會說邏輯迴歸或者SVM只是單層神經網絡的一個特例。研究者們也會使用人工神經網絡(Artificial Neural Networks 縮寫ANN)或者多層感知器(Multi-Layer Perceptrons 縮寫MLP)來指代神經網絡。很多研究者並不喜歡神經網絡算法和人類大腦之間的類比,他們更傾向於用單元(unit)而不是神經元作爲術語。

輸出層。和神經網絡中其他層不同,輸出層的神經元一般是不會有激活函數的(或者也可以認爲它們有一個線性相等的激活函數)。這是因爲最後的輸出層大多用於表示分類評分值,因此是任意值的實數,或者某種實數值的目標數(比如在迴歸中)。

確定網絡尺寸。用來度量神經網絡的尺寸的標準主要有兩個:一個是神經元的個數,另一個是參數的個數,用上面圖示的兩個網絡舉例:

  • 第一個網絡有4+2=6個神經元(輸入層不算),[3x4]+[4x2]=20個權重,還有4+2=6個偏置,共26個可學習的參數。
  • 第二個網絡有4+4+1=9個神經元,[3x4]+[4x4]+[4x1]=32個權重,4+4+1=9個偏置,共41個可學習的參數。

爲了方便對比,現代卷積神經網絡能包含約1億個參數,可由10-20層構成(這就是深度學習)。然而,有效(effective)連接的個數因爲參數共享的緣故大大增多。在後面的卷積神經網絡內容中我們將學習更多。

3.2 前向傳播計算舉例

不斷重複的矩陣乘法與激活函數交織。將神經網絡組織成層狀的一個主要原因,就是這個結構讓神經網絡算法使用矩陣向量操作變得簡單和高效。用上面那個3層神經網絡舉例,輸入是[3x1]的向量。一個層所有連接的強度可以存在一個單獨的矩陣中。比如第一個隱層的權重W1 是[4x3],所有單元的偏置儲存在b1 中,尺寸[4x1]。這樣,每個神經元的權重都在W1 的一個行中,於是矩陣乘法np.dot(W1,x) 就能計算該層中所有神經元的激活數據。類似的,W2將會是[4x4]矩陣,存儲着第二個隱層的連接,W3 是[1x4]的矩陣,用於輸出層。完整的3層神經網絡的前向傳播就是簡單的3次矩陣乘法,其中交織着激活函數的應用。

# 一個3層神經網絡的前向傳播:
f = lambda x: 1.0/(1.0 + np.exp(-x)) # 激活函數(用的sigmoid)
x = np.random.randn(3, 1) # 含3個數字的隨機輸入向量(3x1)
h1 = f(np.dot(W1, x) + b1) # 計算第一個隱層的激活數據(4x1)
h2 = f(np.dot(W2, h1) + b2) # 計算第二個隱層的激活數據(4x1)
out = np.dot(W3, h2) + b3 # 神經元輸出(1x1)

在上面的代碼中,W1W2W3b1b2b3 都是網絡中可以學習的參數。注意x並不是一個單獨的列向量,而可以是一個批量的訓練數據(其中每個輸入樣本將會是x中的一列),所有的樣本將會被並行化的高效計算出來。注意神經網絡最後一層通常是沒有激活函數的(例如,在分類任務中它給出一個實數值的分類評分)。

全連接層的前向傳播一般就是先進行一個矩陣乘法,然後加上偏置並運用激活函數。

3.3 表達能力

理解具有全連接層的神經網絡的一個方式是:可以認爲它們定義了一個由一系列函數組成的函數族,網絡的權重就是每個函數的參數。如此產生的問題是:該函數族的表達能力如何?存在不能被神經網絡表達的函數嗎?

現在看來,擁有至少一個隱層的神經網絡是一個通用的近似器。在研究(例如1989年的論文Approximation by Superpositions of Sigmoidal Function,或者Michael Nielsen的這個直觀解釋。)中已經證明,給出任意連續函數f(x) 和任意ϵ>0 ,均存在一個至少含1個隱層的神經網絡g(x)(並且網絡中有合理選擇的非線性激活函數,比如sigmoid),對於x ,使得|f(x)g(x)|<ϵ 。換句話說,神經網絡可以近似任何連續函數。

既然一個隱層就能近似任何函數,那爲什麼還要構建更多層來將網絡做得更深?答案是:雖然一個2層網絡在數學理論上能完美地近似所有連續函數,但在實際操作中效果相對較差。在一個維度上,雖然以a,b,c 爲參數向量“指示塊之和”函數g(x)=ici1(ai<x<bi) 也是通用的近似器,但是誰也不會建議在機器學習中使用這個函數公式。神經網絡在實踐中非常好用,是因爲它們表達出的函數不僅平滑,而且對於數據的統計特性有很好的擬合。同時,網絡通過最優化算法(例如梯度下降)能比較容易地學習到這個函數。類似的,雖然在理論上深層網絡(使用了多個隱層)和單層網絡的表達能力是一樣的,但是就實踐經驗而言,深度網絡效果比單層網絡好。

另外,在實踐中3層的神經網絡會比2層的表現好,然而繼續加深(做到4,5,6層)很少有太大幫助。卷積神經網絡的情況卻不同,在卷積神經網絡中,對於一個良好的識別系統來說,深度是一個極端重要的因素(比如數十(以10爲量級)個可學習的層)。對於該現象的一種解釋觀點是:因爲圖像擁有層次化結構(比如臉是由眼睛等組成,眼睛又是由邊緣組成),所以多層處理對於這種數據就有直觀意義。

全面的研究內容還很多,近期研究的進展也很多。如果你對此感興趣,我麼推薦你閱讀下面文獻:

Deep Learning的Chapter6.4,作者是Bengio等。
Do Deep Nets Really Need to be Deep?
FitNets: Hints for Thin Deep Nets

3.4 設置層的數量和尺寸

在面對一個具體問題的時候該確定網絡結構呢?到底是不用隱層呢?還是一個隱層?兩個隱層或更多?每個層的尺寸該多大?

首先,要知道當我們增加層的數量和尺寸時,網絡的容量上升了。即神經元們可以合作表達許多複雜函數,所以表達函數的空間增加。例如,如果有一個在二維平面上的二分類問題。我們可以訓練3個不同的神經網絡,每個網絡都只有一個隱層,但是每層的神經元數目不同:
————————————————————————————————————————
Alt text
更大的神經網絡可以表達更復雜的函數。數據是用不同顏色的圓點表示他們的不同類別,決策邊界是由訓練過的神經網絡做出的。你可以在ConvNetsJS demo上練練手。
————————————————————————————————————————

在上圖中,可以看見有更多神經元的神經網絡可以表達更復雜的函數。然而這既是優勢也是不足,優勢是可以分類更復雜的數據,不足是可能造成對訓練數據的過擬合。過擬合(Overfitting)是網絡對數據中的噪聲有很強的擬合能力,而沒有重視數據間(假設)的潛在基本關係。舉例來說,有20個神經元隱層的網絡擬合了所有的訓練數據,但是其代價是把決策邊界變成了許多不相連的紅綠區域。而有3個神經元的模型的表達能力只能用比較寬泛的方式去分類數據。它將數據看做是兩個大塊,並把個別在綠色區域內的紅色點看做噪聲。在實際中,這樣可以在測試數據中獲得更好的泛化(generalization)能力。

基於上面的討論,看起來如果數據不是足夠複雜,則似乎小一點的網絡更好,因爲可以防止過擬合。然而並非如此,防止神經網絡的過擬合有很多方法(L2正則化,dropout和輸入噪音等),後面會詳細討論。在實踐中,使用這些方法來控制過擬合比減少網絡神經元數目要好得多。

不要減少網絡神經元數目的主要原因在於小網絡更難使用梯度下降等局部方法來進行訓練:雖然小型網絡的損失函數的局部極小值更少,也比較容易收斂到這些局部極小值,但是這些最小值一般都很差,損失值很高。相反,大網絡擁有更多的局部極小值,但就實際損失值來看,這些局部極小值表現更好,損失更小。因爲神經網絡是非凸的,就很難從數學上研究這些特性。即便如此,還是有一些文章嘗試對這些目標函數進行理解,例如The Loss Surfaces of Multilayer Networks這篇論文。在實際中,你將發現如果訓練的是一個小網絡,那麼最終的損失值將展現出多變性:某些情況下運氣好會收斂到一個好的地方,某些情況下就收斂到一個不好的極值。從另一方面來說,如果你訓練一個大的網絡,你將發現許多不同的解決方法,但是最終損失值的差異將會小很多。這就是說,所有的解決辦法都差不多,而且對於隨機初始化參數好壞的依賴也會小很多。

重申一下,正則化強度是控制神經網絡過擬合的好方法。看下圖結果:
————————————————————————————————————————
Alt text
不同正則化強度的效果:每個神經網絡都有20個隱層神經元,但是隨着正則化強度增加,它的決策邊界變得更加平滑。你可以在ConvNetsJS demo上練練手。

需要記住的是:不應該因爲害怕出現過擬合而使用小網絡。相反,應該進儘可能使用大網絡,然後使用正則化技巧來控制過擬合。

小結

小結如下:

介紹了生物神經元的粗略模型;討論了幾種不同類型的激活函數,其中ReLU是最佳推薦;介紹了神經網絡,神經元通過全連接層連接,層間神經元兩兩相連,但是層內神經元不連接;理解了分層的結構能夠讓神經網絡高效地進行矩陣乘法和激活函數運算;理解了神經網絡是一個通用函數近似器,但是該性質與其廣泛使用無太大關係。之所以使用神經網絡,是因爲它們對於實際問題中的函數的公式能夠某種程度上做出“正確”假設。

討論了更大網絡總是更好的這一事實。然而更大容量的模型一定要和更強的正則化(比如更高的權重衰減)配合,否則它們就會過擬合。在後續章節中我們講學習更多正則化的方法,尤其是dropout。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章