本文為CS231N學習筆記,主要參考PPT和官方筆記,省略了一些基礎知識,同時做了擴展。
主要內容:Activation functions, data processing, Batch Normalization
更好的閱讀體驗點擊閱讀原文跳轉。
Quick intro
在線性分類部分,使用公式 s = Wx 計算給定圖像所屬不同類別的分數,其中 W 是權重矩陣,x 是包含圖像所有像素數據的輸入列向量。在CIFAR-10的情況下,x 是 [3072x1] 列向量,W 是 [10x3072] 矩陣,因此輸出是一個包含10個類別得分的向量。
神經網絡的計算公式改為 s = W2 max(0, W1x)。其中,W1 可以是 [100x3072] 矩陣,可將圖像轉換為100維中間向量(intermediate vector)。函數 max(0,-) 是非線性的,逐元素(elementwise)地應用。我們還可以選擇其它的非線性激活函數(將在下文進行研究),但這是一種常見選擇,max函數將小於等於零的值置零。最終,矩陣 W2 的大小為 [10x100] ,以使得 s 輸出10類的得分。注意,非線性在計算上很關鍵。如果將其忽略,則兩個矩陣可以合為一個矩陣,因此預測的類分數將再次是輸入的線性函數。非線性函數是改變的關鍵點。參數 W2, W1 是通過隨機梯度下降學習的,其梯度是通過鏈式規則導出的(並通過反向傳播計算)。
一個三層的神經網絡可以類比地看做 s = W3 max(0, W2 max(0, W1 x)),其中 W3, W2, W1 是需要學習的參數,中間隱藏向量的尺寸是網絡的超參數。
神經網絡領域最初的靈感主要來自對生物神經系統建模,但此後出現分歧,成為工程問題,並在機器學習任務中取得了良好的成績。儘管如此,我們還是從受到啟發的生物系統的的描述開始討論。
Biological motivation and connections大腦的基本計算單元是神經元(neuron)。人類神經系統中大約有860億個神經元,它們與大約 1e14-1e15 的突觸(synapses)相連。下圖顯示了生物神經元模型(左)和常見的數學模型(右)。每個神經元從其樹突(dendrites)接收輸入信號,並沿單個軸突(axon)產生輸出信號。軸突最終分支並通過突觸連接到其他神經元的樹突。在神經元的計算模型中,沿著軸突(例如 x0)傳播的信號會根據另一個神經元的突觸(例如 w0)的突觸強度與其他神經元的樹突進行乘法交互(例如 w0x0)。這個想法是,突觸強度(synaptic strengths)(權重 w) 是可學習的,並且可以控制一個神經元對另一神經元的影響強度及其方向:興奮(excitory;正權重)或抑制(inhibitory;負權重)。在基本模型中,樹突將信號傳遞到細胞體(cell body),然後將它們全部求和。如果總和超過某個閾值,則神經元被激活,沿其軸突發送峰值信號。在計算模型中,假設峰值信號的的精確定時無關緊要,僅觸發頻率可以傳遞信息。基於此速率編碼(rate code)解釋,激活函數 f(表示沿軸突的峰值信號頻率)對神經元的放電速率進行建模。從歷史上看,激活函數的一個常見選擇是sigmoid函數 sigma(x) = 1/(1+e^{-x}),它將實值輸入(求和後的信號強度)壓縮在0到1之間。
用於向前傳播單個神經元的示例代碼如下所示:
class Neuron(object):
# ...
def forward(self, inputs):
""" assume inputs and weights are 1-D numpy arrays and bias is a number """
cell_body_sum = np.sum(inputs * self.weights) + self.bias # sigmoid activation function
firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum))
return firing_rate
粗糙模型(Coarse model):要注意這個對於生物神經元的建模是非常粗糙的:實際上有很多不同類型的神經元,每種都有不同的屬性。生物神經元的樹突(dendrites)可以進行複雜的非線性計算。突觸(synapses)並不就是一個簡單的權重,它們是複雜的非線性動態系統。在許多系統中輸出峰值信號的準確時序很重要,這表明速率編碼的近似可能不成立。
Single neuron as a linear classifier正如在線性分類器中看到的,神經元具有「喜歡」(激活函數值接近1)或不喜歡(激活函數值接近0)輸入空間中的某些線性區域的特性。因此,在神經元輸出上使用適當的損失函數,可以將單個神經元變成線性分類器:
Binary SVM classifier. 或者可以在神經元的輸出外增加一個最大邊界折葉損失(max-margin hinge loss)函數,將其訓練成一個二分類的支持向量機(SVM)。
Regularization interpretation. 在這種生物學觀點下,兩種SVM/Softmax情況下的正則化損失都可以解釋為逐漸遺忘(gradual forgetting),因為它會在每次參數更新後將所有突觸權重 w 置零。
【A single neuron can be used to implement a binary classifier (e.g. binary Softmax or binary SVM classifiers)】
Commonly used activation functions激活函數(或非線性函數)對輸入執行某個固定的數學運算。實踐中有幾種常用的激活函數:
Sigmoid. sigmoid非線性激活函數 sigma(x) = 1 / (1 + e^{-x}) 如上圖所示。它將輸入」擠壓」 到0到1之間。特別是,大的負數變為0,大的正數變為1。因為它可以很好地解釋神經元的發射速率:從根本不發射(0)到以假定的最大頻率(1)完全飽和發射。在實踐中,sigmoid已很少使用。它有兩個主要缺點:
sigmoid飽和導致梯度消失。
sigmoid的一個非常不好的特性是,當神經元的激活在0或1的尾部飽和時,這些區域的梯度幾乎為零。
回想一下,在反向傳播期間,此(局部)梯度將與整個目標的此門輸出的梯度相乘。
因此,如果局部梯度很小,它將有效地「殺死」該梯度,並且幾乎沒有信號將通過神經元流向其權重並遞歸地傳遞至其數據。
另外,在初始化使用sigmoid激活的神經元的權重以防止飽和時必須格外小心。例如,如果初始權重太大,則大多數神經元將變得飽和,網絡將幾乎無法學習。
sigmoid輸出不是零中心的。
這是不希望的情況,因為神經網絡中處理的後續層中的神經元將接收到非零中心的數據。
這將影響梯度下降,因為如果進入神經元的數據始終為正(例如,在 f = w^Tx + b 中的每個元素 x>0),則權重 w 的梯度將在反向傳播期間全部變為正,或全部為負(取決於整個表達式 f 的梯度)。
這可能會在權重的梯度更新中引入之字形下降(zig-zagging dynamics)。將一批數據的梯度相加之後,權重的最終更新就具有不同的符號,從而在某種程度上緩解了此問題。因此,這是一個不便,但是與上面的飽和激活問題相比,後果不那麼嚴重。
Tanh. tanh非線性顯示在右上方的圖像中。它將實數值壓縮到[-1,1]範圍內。像sigmoid神經元一樣,它的激活是飽和的,但是與sigmoid神經元不同,它的輸出是零中心的。因此,實際上,tanh非線性總是比S形非線性更可取。還應注意,tanh神經元是一個簡單放大的sigmoid神經元,成立條件為:tanh(x) = 2 sigma(2x) -1。
ReLU. 近些年ReLU變得非常流行。函數公式為 f(x) = max(0, x),它就是一個關於0的閾值(如上圖左側)。ReLU有以下一些優缺點:
(+)與Sigmoid/tanh函數相比,隨機梯度下降的收斂速度大大加快。
有人認為這是由於其線性,非飽和形式。
(+)與涉及耗費資源的操作(指數運算)的tanh /Sigmoid神經元相比,ReLU可以通過簡單地將激活矩陣閾值設為零來實現。
(-)不幸的是,ReLU單元在訓練過程中可能很脆弱,並且可能「死亡(die)」。
例如,流經ReLU神經元的大梯度可能導致神經元不會在任何數據上被激活。
如果發生這種情況,那麼從該點開始,流經該神經元的梯度將永遠為零。
也就是說,ReLU單元在訓練期間會不可逆地死亡(irreversibly die),因為它們可能會從數據總管上脫落(knocked off)。
例如,如果將學習率設置得太高,會發現多達40%的網絡可能是「死亡」的(即永遠不會在整個訓練數據集中激活的神經元)。
這可以通過正確設置學習率來緩解。
Leaky ReLU. Leaky ReLU是解決「dying ReLU」問題的一種嘗試。當x<0時,函數不為零,而有較小的負斜率(約為0.01)。即該函數 f(x) = 1(x < 0) (α x) + 1(x>=0) (x),其中 α 是一個小常數。有研究指出使用這種形式的激活函數效果較好,但結果並不總是一致。負區域中的斜率也可以作為每個神經元的參數,如Kaiming He等人在2015年的 Delving Deep into Rectifiers 中介紹的PReLU神經元中所示。但目前並不清楚其跨任務效果的一致性。
以上內容就是對常見的神經元類型及其激活函數的討論。
最後,在同一網絡中混合使用不同類型的神經元很少見,儘管這樣做根本沒有問題。
TLDR(Too Long; Didn’t Read.):應該使用哪種神經元類型?如果選擇ReLU,應該特別注意學習率的設置,並監視網絡中「死」單元的比例。如果存在 dying 的情況,可以嘗試Leaky ReLU或Maxout。切勿使用Sigmoid。嘗試使用tanh,但它的性能可能比ReLU/Maxout差。
(PS:在時間序列預測任務中,往往使用sigmoid,尤其是被預測量全為正值時!使用tanh會導致大量負值,造成很大的誤差!最好多測試幾個激活函數,選擇效果最好的!!!)
Neural Network architecturesLayer-wise organization神經網絡被建模為在無環圖中連接的神經元的集合。換句話說,某些神經元的輸出可以成為其他神經元的輸入。不允許使用循環,因為這將意味著網絡的正向傳遞中存在無限循環。神經網絡模型通常被組織成不同的神經元層,而不是像生物神經元那樣連接成無定形斑點(amorphous blobs)。對於常規的神經網絡,最常見的層類型是全連接層,其中兩個相鄰層之間的神經元完全成對連接,但是層內的神經元不共享任何連接。以下是兩個示例神經網絡拓撲,它們使用一堆全連接層:
Naming conventions. 注意,當我們說N層神經網絡時,不包括輸入層。因此,單層神經網絡描述了沒有隱藏層(輸入直接映射到輸出)的網絡。從這種意義上講,邏輯回歸或SVM只是單層神經網絡的一種特殊情況。有時這些網絡也稱為人工神經網絡(ANN)或多層感知器(MLP)。
Output layer. 與神經網絡中的所有層不同,輸出層神經元通常不使用激活函數(可以認為它們具有線性恆等映射激活函數)。這是因為通常將最後一個輸出層用於表示類別分數(如分類),這些分數是任意的實數值或某種實值的目標(如回歸)。
Sizing neural networks. 人們通常用來衡量神經網絡大小的兩個指標是神經元數量和參數數量。使用上圖中的兩個示例網絡:
現代的卷積網絡包含大約1億個參數,通常由大約10到20層組成(因此稱為深度學習)。但是,由於參數共享,有效連接的數量大大增加。
Example feed-forward computation重複的矩陣乘法與激活函數交織在一起。神經網絡被組織成層次的主要原因是這種結構使得使用矩陣向量運算來評估神經網絡非常簡單有效。使用上圖中的示例三層神經網絡,輸入是[3x1]向量。一層的所有連接強度都可以存儲在一個矩陣中。例如,第一個隱藏層的權重W1的大小為[4x3],所有單元的偏差都在矢量b1中,大小為[4x1]。在這裡,每個神經元在W1行中都有其權重,因此矩陣向量乘法np.dot(W1,x)就能評估該層中所有神經元的激活。類似地,W2是一個[4x4]矩陣,用於存儲第二個隱藏層的連接,而W3是一個[1x4]矩陣,用於輸出層。然後,此三層神經網絡的完整前向傳播就是三個矩陣乘法,並與激活函數交織在一起:
# forward-pass of a 3-layer neural network:f = lambda x: 1.0/(1.0 + np.exp(-x)) # activation function (use sigmoid)x = np.random.randn(3, 1) # random input vector of three numbers (3x1)h1 = f(np.dot(W1, x) + b1) # calculate first hidden layer activations (4x1)h2 = f(np.dot(W2, h1) + b2) # calculate second hidden layer activations (4x1)out = np.dot(W3, h2) + b3 # output neuron (1x1)
在上面的代碼中,W1,W2,W3,b1,b2,b3是網絡的可學習參數。還要注意,x不是單獨的列向量,而可以容納整批訓練數據(每個輸入樣本是x的列),然後可以並行地有效評估所有樣本。注意,神經網絡輸出層通常不適用激活函數(例如,分類問題中表示分類設置中的(實值)分類得分)。
【The forward pass of a fully-connected layer corresponds to one matrix multiplication followed by a bias offset and an activation function.】
Representational power理解具有全連接層的神經網絡的一種方法是,它們定義了一系列函數,其參數就是網絡的權重。這一系列函數表示什麼?是否存在無法用神經網絡建模的函數?
如果一個隱藏層足以逼近任何函數,為什麼還要使用更多的層以使網絡更深? 實踐是檢驗真理的唯一標準!神經網絡在實踐中之所效果很好,是因為它們表達出的函數不僅平滑,而且對於數據的統計特性有很好的擬合。同時,網絡通過最優化算法(例如梯度下降)能比較容易地學習到這個函數。雖然理論上深層網絡(多個隱層)和單層網絡的表達能力是一樣的,但實踐中深度網絡效果比單層網絡好。
在實踐中,三層神經網絡通常會勝過兩層網絡,然而繼續加深(4,5,6層)則很少有太大幫助。這與卷積網絡形成了鮮明的對比,在卷積神經網絡中,深度被認為是良好識別系統的一個極其重要的組成部分(比如10個可學習層)。該現象的一個論據是圖像擁有層次化結構(比如臉是由眼睛等組成,眼睛又是由邊緣組成),因此多層處理對該數據域具有直觀意義。
如果對這些主題感興趣,可進一步閱讀:
Deep Learning book in press by Bengio, Goodfellow, Courville, in particular Chapter 6.4.
Do Deep Nets Really Need to be Deep?
FitNets: Hints for Thin Deep Nets
Setting number of layers and their sizes面對實際問題時,我們如何決定使用哪種架構?應該使用隱藏層嗎?一個隱藏層?兩個隱藏層?每層應該多大?隨著增加神經網絡中層的大小和數量,網絡的容量也會增加。也就是說,由於神經元可以協作表達許多不同的函數,因此可表示函數的空間不斷增長。例如,假設在兩個維度上都有一個二分類問題。可以訓練三個獨立的神經網絡,每個神經網絡具有一個大小不等的隱藏層,並獲得以下分類器:
較大的神經網絡可以表示更複雜的函數。數據(圓圈)按其類別進行著色著色,顯示了經過訓練的神經網絡的決策區域。可以ConvNetsJS demo中使用這些示例。
在上圖中,我們可以看到具有更多神經元的神經網絡可以表達更複雜的函數。但是,這既是一種好的徵兆(因為可以學習對更複雜的數據進行分類),又是一種不好的信號(因為更容易過擬合訓練數據)。當具有高容量的模型擬合數據中的噪聲而不是(假定的)基礎關係時,就會發生過擬合。例如,具有20個隱藏神經元的模型可以擬合所有訓練數據,但其代價是將空間劃分為許多不相交的紅色和綠色決策區域。具有3個隱藏神經元的模型僅具有基本的表示能力,可以大致進行分類。它將數據建模為兩個簇,並將綠色簇內的幾個紅色點看作離群值(噪聲)。實際上,這可以實現對測試集更好的泛化(generalization)能力。
根據上面的討論,如果數據不夠複雜以防止過擬合,則似乎應該使用較小的神經網絡。但是,這是不正確的。稍後我們將討論降低神經網絡過擬合風險的其它許多首選方法(例如L2正則化,Dropout,輸入噪聲)。在實踐中,最好使用這些方法來控制過擬合,而不是控制神經元的數量。
這背後的一個微妙原因是,較小的網絡更難使用諸如梯度下降之類的局部方法進行訓練:很明顯,它們的損失函數具有相對較少的局部最小值,其中許多最小值更易於收斂,但事實證明,他們是壞的(即高損失)。相反,更大的神經網絡包含更多的局部最小值,但這些最小值在實際損失方面要好得多。由於神經網絡是非凸的,因此很難用數學方法研究這些屬性,但是已經做了一些嘗試來理解這些目標函數,例如在最近的論文 The Loss Surfaces of Multilayer Networks中。實際上,如果訓練一個小型網絡,最終的損失會顯示出很大的方差——在某些情況下,會收斂到一個好的位置,但在某些情況下,則會陷入一個糟糕的最小值。如果訓練一個大型網絡,會找到許多不同的解決方案,但最終實現的損失方差會小得多。換句話說,所有解決方案都差不多,並且更少依賴於隨機初始化的好壞。
重申一下,正則化強度(regularization strength)是控制神經網絡過擬合的首選方法。可以看看通過三種不同設置獲得的結果:
結論是:不應該因為擔心過擬合而使用較小的網絡,相反,應該在計算預算允許的範圍內使用儘可能大的神經網絡,並使用正則化技術來控制過擬合。