筆記參考:https://zhuanlan.zhihu.com/p/21407711?refer=intelligentunit
感謝原作者的翻譯!!
非原創,禁止轉載本文
內容列表:
- 不用大腦做類比的快速簡介
-
- 單個神經元建模
- 2.1 生物動機和連接
- 2.2 作為線性分類器的單個神經元
- 2.3 常用的激活函數 譯者注:上篇翻譯截止處
-
- 神經網絡結構
- 3.1 層組織
- 3.2 前向傳播計算例子
- 3.3 表達能力
- 3.4 設置層的數量和尺寸
- 小節
1. 快速簡介
在不訴諸大腦的類比的情況下,依然是可以對神經網絡算法進行介紹的。在線性分類一節中,在給出圖像的情況下,是使用 s = Wx 來計算不同視覺類別的評分,其中 W 是一個矩陣, x是一個輸入列向量,它包含了圖像的全部像素數據。在使用數據庫CIFAR-10的案例中, x 是一個[3072x1]的列向量, W 是一個[10x3072]的矩陣,所以輸出的評分是一個包含10個分類評分的向量。
神經網絡算法則不同,它的計算公式是
其中 W1 的含義是這樣的:舉個例子來說,它可以是一個[100x3072]的矩陣,其作用是將圖像轉化為一個100維的過渡向量。函數 max(0, -) 是非線性的,它會作用到每個元素。這個非線性函數有多種選擇,后續將會學到。但這個形式是一個最常用的選擇,它就是簡單地設置閾值,將所有小于0的值變成0。最終,矩陣 W2 的尺寸是[10x100],因此將得到10個數字,這10個數字可以解釋為是分類的評分。注意非線性函數在計算上是至關重要的,如果略去這一步,那么兩個矩陣將會合二為一,對于分類的評分計算將重新變成關于輸入的線性函數。這個非線性函數就是改變的關鍵點。參數 W1 , W2 將通過隨機梯度下降來學習到,他們的梯度在反向傳播過程中,通過鏈式法則來求導計算得出。
一個三層的神經網絡可以類比地看做
其中 W1 , W2 , W3 是需要進行學習的參數。中間隱層的尺寸是網絡的超參數,后續將學習如何設置它們。現在讓我們先從神經元或者網絡的角度理解上述計算。
2. 單個神經元建模
2.1 生物動機與連接
大腦的基本計算單位是神經元(neuron)。人類的神經系統中大約有860億個神經元,它們被大約10^14 - 10^15個突觸(synapses)連接起來。下面圖表的左邊展示了一個生物學的神經元,右邊展示了一個常用的數學模型。每個神經元都從它的樹突獲得輸入信號,然后沿著它唯一的軸突(axon)產生輸出信號。軸突在末端會逐漸分枝,通過突觸和其他神經元的樹突相連。
在神經元的計算模型中,沿著軸突傳播的信號(比如 x0 )將基于突觸的突觸強度(比如 W0 ),與其他神經元的樹突進行乘法交互(比如 W0 x0 )。其觀點是,突觸的強度(也就是權重 W ),是可學習的且可以控制一個神經元對于另一個神經元的影響強度(還可以控制影響方向:使其興奮(正權重)或使其抑制(負權重))。在基本模型中,樹突將信號傳遞到細胞體,信號在細胞體中相加。如果最終之和高于某個閾值,那么神經元將會激活,向其軸突輸出一個峰值信號。在計算模型中,我們假設峰值信號的準確時間點不重要,是激活信號的頻率在交流信息。基于這個速率編碼的觀點,將神經元的激活率建模為激活函數(activation function) f ,它表達了軸突上激活信號的頻率。由于歷史原因,激活函數常常選擇使用sigmoid函數 σ ,該函數輸入實數值(求和后的信號強度),然后將輸入值壓縮到0-1之間。在本節后面部分會看到這些激活函數的各種細節。
左邊是生物神經元,右邊是數學模型。
一個神經元前向傳播的實例代碼如下:
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函數[圖片上傳失敗。在本節的末尾部分將介紹不同激活函數的細節。
粗糙模型:要注意這個對于生物神經元的建模是非常粗糙的:在實際中,有很多不同類型的神經元,每種都有不同的屬性。生物神經元的樹突可以進行復雜的非線性計算。突觸并不就是一個簡單的權重,它們是復雜的非線性動態系統。很多系統中,輸出的峰值信號的精確時間點非常重要,說明速率編碼的近似是不夠全面的。鑒于所有這些已經介紹和更多未介紹的簡化,如果你畫出人類大腦和神經網絡之間的類比,有神經科學背景的人對你的板書起哄也是非常自然的。如果你對此感興趣,可以看看這份評論或者最新的另一份。
2.2 作為線性分類器的單個神經元
神經元模型的前向計算數學公式看起來可能比較眼熟。就像在線性分類器中看到的那樣,神經元有能力“喜歡”(激活函數值接近1),或者不喜歡(激活函數值接近0)輸入空間中的某些線性區域。因此,只要在神經元的輸出端有一個合適的損失函數,就能讓單個神經元變成一個線性分類器。
二分類Softmax分類器。舉例來說,可以把 σ(∑iWixi + b) 看做其中一個分類的概率 P(yi = 1|xi; W),其他分類的概率為 P(yi = 0|xi; W) = 1 - P(yi = 1|xi; W) ,因為它們加起來必須為1。根據這種理解,可以得到交叉熵損失,這個在線性分一節中已經介紹。然后將它最優化為二分類的Softmax分類器(也就是邏輯回歸)。因為sigmoid函數輸出限定在0-1之間,所以分類器做出預測的基準是神經元的輸出是否大于0.5。
二分類SVM分類器。或者可以在神經元的輸出外增加一個最大邊界折葉損失(max-margin hinge loss)函數,將其訓練成一個二分類的支持向量機。
理解正則化。在SVM/Softmax的例子中,正則化損失從生物學角度可以看做逐漸遺忘,因為它的效果是讓所有突觸權重 W 在參數更新過程中逐漸向著0變化。
一個單獨的神經元可以用來實現一個二分類分類器,比如二分類的Softmax或者SVM分類器。
2.3 常用激活函數
每個激活函數(或非線性函數)的輸入都是一個數字,然后對其進行某種固定的數學操作。下面是在實踐中可能遇到的幾種激活函數:
左邊是Sigmoid非線性函數,將實數壓縮到[0,1]之間。右邊是tanh函數,將實數壓縮到[-1,1]。
Sigmoid
sigmoid非線性函數的數學公式是 σ(x) = 1/(1 + e-x) ,函數圖像如上圖的左邊所示。在前一節中已經提到過,它輸入實數值并將其“擠壓”到0到1范圍內。更具體地說,很大的負數變成0,很大的正數變成1。在歷史上,sigmoid函數非常常用,這是因為它對于神經元的激活頻率有良好的解釋:從完全不激活(0)到在求和后的最大頻率處的完全飽和(saturated)的激活(1)。然而現在sigmoid函數已經不太受歡迎,實際很少使用了,這是因為它有兩個主要缺點:
- Sigmoid函數飽和使梯度消失。sigmoid神經元有一個不好的特性,就是當神經元的激活在接近0或1處時會飽和:在這些區域,梯度幾乎為0。回憶一下,在反向傳播的時候,這個(局部)梯度將會與整個損失函數關于該門單元輸出的梯度相乘。因此,如果局部梯度非常小,那么相乘的結果也會接近零,這會有效地“殺死”梯度,幾乎就有沒有信號通過神經元傳到權重再到數據了。還有,為了防止飽和,必須對于權重矩陣初始化特別留意。比如,如果初始化權重過大,那么大多數神經元將會飽和,導致網絡就幾乎不學習了。
- Sigmoid函數的輸出不是零中心的。這個性質并不是我們想要的,因為在神經網絡后面層中的神經元得到的數據將不是零中心的。這一情況將影響梯度下降的運作,因為如果輸入神經元的數據總是正數(比如在 f = wTx + b 中每個元素都 x > 0),那么關于 w 的梯度在反向傳播的過程中,將會要么全部是正數,要么全部是負數(具體依整個表達式 f 而定)。這將會導致梯度下降權重更新時出現z字型的下降。然而,可以看到整個批量的數據的梯度被加起來后,對于權重的最終更新將會有不同的正負,這樣就從一定程度上減輕了這個問題。因此,該問題相對于上面的神經元飽和問題來說只是個小麻煩,沒有那么嚴重。
tanh
tanh非線性函數圖像如上圖右邊所示。它將實數值壓縮到[-1,1]之間。和sigmoid神經元一樣,它也存在飽和問題,但是和sigmoid神經元不同的是,它的輸出是零中心的。因此,在實際操作中,tanh非線性函數比sigmoid非線性函數更受歡迎。注意tanh神經元是一個簡單放大的sigmoid神經元,具體說來就是:
左邊是ReLU(校正線性單元:Rectified Linear Unit)激活函數,當 x = 0 時函數值為0。當 x > 0 函數的斜率為1。右邊是從 Krizhevsky等的論文中截取的圖表,指明使用ReLU比使用tanh的收斂快6倍。
ReLU
近些年ReLU變得非常流行。它的函數公式是 f(x) = max(0, x)。換句話說,這個激活函數就是一個關于0的閾值(如上圖左側)。使用ReLU有以下一些優缺點:
-
優點
- 相較于sigmoid和tanh函數,ReLU對于隨機梯度下降的收斂有巨大的加速作用( Krizhevsky 等的論文指出有6倍之多)。據稱這是由它的線性,非飽和的公式導致的。
- sigmoid和tanh神經元含有指數運算等耗費計算資源的操作,而ReLU可以簡單地通過對一個矩陣進行閾值計算得到。
-
缺點
在訓練的時候,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) ,其中 α 是一個小的常量。有些研究者的論文指出這個激活函數表現很不錯,但是其效果并不是很穩定。Kaiming He等人在2015年發布的論文Delving Deep into Rectifiers中介紹了一種新方法PReLU,把負區間上的斜率當做每個神經元中的一個參數。然而該激活函數在在不同任務中均有益處的一致性并沒有特別清晰。
Maxout。一些其他類型的單元被提了出來,它們對于權重和數據的內積結果不再使用 f = wTx + b 函數形式。一個相關的流行選擇是Maxout(由Goodfellow等發布)神經元。Maxout是對ReLU和leaky ReLU的一般化歸納,它的函數是:max( w1Tx + b1,w2Tx + b2) 。ReLU和Leaky ReLU都是這個公式的特殊情況(比如ReLU就是當 w1,b1 = 0 的時候)。這樣Maxout神經元就擁有ReLU單元的所有優點(線性操作和不飽和),而沒有它的缺點(死亡的ReLU單元)。然而和ReLU對比,它每個神經元的參數數量增加了一倍,這就導致整體參數的數量激增。
以上就是一些常用的神經元及其激活函數。最后需要注意一點:在同一個網絡中混合使用不同類型的神經元是非常少見的,雖然沒有什么根本性問題來禁止這樣做。
一句話:“那么該用那種呢?”用ReLU非線性函數。注意設置好學習率,或許可以監控你的網絡中死亡的神經元占的比例。如果單元死亡問題困擾你,就試試Leaky ReLU或者Maxout,不要再用sigmoid了。也可以試試tanh,但是其效果應該不如ReLU或者Maxout。
3. 神經經網絡結構
3.1 靈活的組織層
將神經網絡算法以神經元的形式圖形化。神經網絡被建模成神經元的集合,神經元之間以無環圖的形式進行連接。也就是說,一些神經元的輸出是另一些神經元的輸入。在網絡中是不允許循環的,因為這樣會導致前向傳播的無限循環。通常神經網絡模型中神經元是分層的,而不是像生物神經元一樣聚合成大小不一的團狀。對于普通神經網絡,最普通的層的類型是全連接層(fully-connected layer)。全連接層中的神經元與其前后兩層的神經元是完全成對連接的,但是在同一個全連接層內的神經元之間沒有連接。下面是兩個神經網絡的圖例,都使用的全連接層:
左邊是一個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)
在上面的代碼中,W1,W2,W3,b1,b2,b3都是網絡中可以學習的參數。注意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個不同的神經網絡,每個網絡都只有一個隱層,但是每層的神經元數目不同:
更大的神經網絡可以表達更復雜的函數。數據是用不同顏色的圓點表示他們的不同類別,決策邊界是由訓練過的神經網絡做出的。你可以在ConvNetsJS demo上練練手。
在上圖中,可以看見有更多神經元的神經網絡可以表達更復雜的函數。然而這既是優勢也是不足,優勢是可以分類更復雜的數據,不足是可能造成對訓練數據的過擬合。過擬合(Overfitting)是網絡對數據中的噪聲有很強的擬合能力,而沒有重視數據間(假設)的潛在基本關系。舉例來說,有20個神經元隱層的網絡擬合了所有的訓練數據,但是其代價是把決策邊界變成了許多不相連的紅綠區域。而有3個神經元的模型的表達能力只能用比較寬泛的方式去分類數據。它將數據看做是兩個大塊,并把個別在綠色區域內的紅色點看做噪聲。在實際中,這樣可以在測試數據中獲得更好的泛化(generalization)能力。
基于上面的討論,看起來如果數據不是足夠復雜,則似乎小一點的網絡更好,因為可以防止過擬合。然而并非如此,防止神經網絡的過擬合有很多方法(L2正則化,dropout和輸入噪音等),后面會詳細討論。在實踐中,使用這些方法來控制過擬合比減少網絡神經元數目要好得多。
不要減少網絡神經元數目的主要原因在于小網絡更難使用梯度下降等局部方法來進行訓練:雖然小型網絡的損失函數的局部極小值更少,也比較容易收斂到這些局部極小值,但是這些最小值一般都很差,損失值很高。相反,大網絡擁有更多的局部極小值,但就實際損失值來看,這些局部極小值表現更好,損失更小。因為神經網絡是非凸的,就很難從數學上研究這些特性。即便如此,還是有一些文章嘗試對這些目標函數進行理解,例如The Loss Surfaces of Multilayer Networks這篇論文。在實際中,你將發現如果訓練的是一個小網絡,那么最終的損失值將展現出多變性:某些情況下運氣好會收斂到一個好的地方,某些情況下就收斂到一個不好的極值。從另一方面來說,如果你訓練一個大的網絡,你將發現許多不同的解決方法,但是最終損失值的差異將會小很多。這就是說,所有的解決辦法都差不多,而且對于隨機初始化參數好壞的依賴也會小很多。
正則化強度是控制神經網絡過擬合的好方法。看下圖結果:
不同正則化強度的效果:每個神經網絡都有20個隱層神經元,但是隨著正則化強度增加,它的決策邊界變得更加平滑。
4. 小結
- 介紹了生物神經元的粗略模型;
- 討論了幾種不同類型的激活函數,其中ReLU是最佳推薦;
- 介紹了神經網絡,神經元通過全連接層連接,層間神經元兩兩相連,但是層內神經元不連接;
- 理解了分層的結構能夠讓神經網絡高效地進行矩陣乘法和激活函數運算;
- 理解了神經網絡是一個通用函數近似器,但是該性質與其廣泛使用無太大關系。之所以使用神經網絡,是因為它們對于實際問題中的函數的公式能夠某種程度上做出“正確”假設。
- 討論了更大網絡總是更好的這一事實。然而更大容量的模型一定要和更強的正則化(比如更高的權重衰減)配合,否則它們就會過擬合。在后續章節中我們講學習更多正則化的方法,尤其是dropout。