深度學習與計算機視覺系列(6)_神經網絡結構與神經元激勵函數

作者:寒小陽 && 龍心塵
時間:2016年1月。
出處:
http://blog.csdn.net/han_xiaoyang/article/details/50447834
http://blog.csdn.net/longxinchen_ml/article/details/50448267
聲明:版權所有,轉載請聯繫作者並註明出處

1.神經元與含義

大家都知道最開始深度學習與神經網絡,是受人腦的神經元啓發設計出來的。所以我們按照慣例也交代一下背景,從生物學的角度開始介紹,當然也是對神經網絡研究的先驅們致一下敬。

1.1 神經元激勵與連接

大家都知道,人腦的基本計算單元叫做神經元。現代生物學表明,人的神經系統中大概有860億神經元,而這數量巨大的神經元之間大約是通過10141015 個突觸連接起來的。下面有一幅示意圖,粗略地描繪了一下人體神經元與我們簡化過後的數學模型。每個神經元都從樹突接受信號,同時順着某個軸突傳遞信號。而每個神經元都有很多軸突和其他的神經元樹突連接。而我們可以看到右邊簡化的神經元計算模型中,信號也是順着軸突(比如x0 )傳遞,然後在軸突處受到激勵(w0 倍)然後變成w0x0 。我們可以這麼理解這個模型:在信號的傳導過程中,突觸可以控制傳導到下一個神經元的信號強弱(數學模型中的權重w ),而這種強弱是可以學習到的。在基本生物模型中,樹突傳導信號到神經元細胞,然後這些信號被加和在一塊兒了,如果加和的結果被神經元感知超過了某種閾值,那麼神經元就被激活,同時沿着軸突向下一個神經元傳導信號。在我們簡化的數學計算模型中,我們假定有一個『激勵函數』來控制加和的結果對神經元的刺激程度,從而控制着是否激活神經元和向後傳導信號。比如說,我們在邏輯迴歸中用到的sigmoid函數就是一種激勵函數,因爲對於求和的結果輸入,sigmoid函數總會輸出一個0-1之間的值,我們可以認爲這個值表明信號的強度、或者神經元被激活和傳導信號的概率。

神經元生物學模型
神經元數學模型

下面是一個簡單的程序例子,表明前向傳播中單個神經元做的事情:

class Neuron:
  # ... 
  def forward(inputs):
    """ 
    假定輸入和權重都是1維的numpy數組,同時bias是一個數 
    """
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid activation function
    return firing_rate

稍加解釋,每個神經元對於輸入和權重做內積,加上偏移量bias,然後通過激勵函數(比如說這裏是sigmoid函數),然後輸出結果。

特別說明:實際生物體內的神經元相當複雜,比如說,神經元的種類就灰常灰常多,它們分別有不同的功能。而加和信號之後的激勵函數的非線性變換,也比數學上模擬出來的函數複雜得多。我們用數學建模的神經網絡只是一個非常簡化後的模型,有興趣的話你可以閱讀材料1或者材料2

1.2 單個神經元的分類作用

以sigmoid函數作爲神經元的激勵函數爲例,這個大家可能稍微熟悉一點,畢竟我們邏輯迴歸部分重點提到了這個非線性的函數,把輸入值壓縮成0-1之間的一個概率值。而通過這個非線性映射和設定的閾值,我們可以把空間切分開,分別對應正樣本區域和負樣本區域。而對應回現在的神經元場景,我們如果稍加擬人化,可以認爲神經元具備了喜歡(概率接近1)和不喜歡(概率接近0)線性劃分的某個空間區域的能力。這也就是說,只要調整好權重,單個神經元可以對空間做線性分割。

二值Softmax分類器
對於Softmax分類器詳細的內容歡迎參見前面的博文系列,我們標記σ 爲sigmoid映射函數,則σ(iwixi+b) 可視作二分類問題中屬於某個類的概率P(yi=1xi;w) ,當然,這樣我們也可以得到相反的那個類別的概率爲P(yi=0xi;w)=1P(yi=1xi;w) 。根據前面博文提到的知識,我們可以使用互熵損失作爲這個二值線性分類器的損失函數(loss function),而最優化損失函數得到的一組參數W,b ,就能幫助我們將空間線性分割,得到二值分類器。當然,和邏輯迴歸中看到的一樣,最後神經元預測的結果y值如果大於0.5,那我們會判定它屬於這個類別,反之則屬於另外一個類別。

二值SVM分類器
同樣的,我們可以設定max-margin hinge loss作爲損失函數,從而將神經元訓練成一個二值支持向量機分類器。詳細的內容依舊歡迎大家查看之前的博客

對於正則化的解釋
對於正則化的損失函數(不管是SVM還是Softmax),其實我們在神經元的生物特性上都能找到對應的解釋,我們可以將其(正則化項的作用)視作信號在神經元傳遞過程中的逐步淡化/衰減(gradual forgetting),因爲正則化項的作用是在每次迭代過程中,控制住權重w 的幅度,往0上靠攏。

單個神經元的作用,可視作完成一個二分類的分類器(比如Softmax或者SVM分類器)

1.3 常用激勵函數

每一次輸入和權重w線性組合之後,都會通過一個激勵函數(也可以叫做非線性激勵函數),經非線性變換後輸出。實際的神經網絡中有一些可選的激勵函數,我們一一說明一下最常見的幾種:

1.3.1 sigmoid


sigmoid圖像

sigmoid函數提到的次數太多,相信大家都知道了。數學形式很簡單,是σ(x)=1/(1+ex) ,圖像如上圖所示,功能是把一個實數壓縮至0到1之間。輸入的數字非常大的時候,結果會接近1,而非常大的負數作爲輸入,則會得到接近0的結果。不得不說,早期的神經網絡中,sigmoid函數作爲激勵函數使用非常之多,因爲大家覺得它很好地解釋了神經元受到刺激後是否被激活和向後傳遞的場景(從幾乎沒有被激活,也就是0,到完全被激活,也就是1)。不過似乎近幾年的實際應用場景中,比較少見到它的身影,它主要的缺點有2個:

  • sigmoid函數在實際梯度下降中,容易飽和終止梯度傳遞。我們來解釋一下,大家知道反向傳播過程,依賴於計算的梯度,在一元函數中,即斜率。而在sigmoid函數圖像上,大家可以很明顯看到,在縱座標接近0和1的那些位置(也就是輸入信號的幅度很大的時候),斜率都趨於0了。我們回想一下反向傳播的過程,我們最後用於迭代的梯度,是由中間這些梯度值結果相乘得到的,因此如果中間的局部梯度值非常小,直接會把最終梯度結果拉近0,也就是說,殘差回傳的過程,因爲sigmoid函數的飽和殺死了。說個極端的情況,如果一開始初始化權重的時候,我們取值不是很恰當,而激勵函數又全用的sigmoid函數,那麼很有可能神經元一個不剩地飽和無法學習,整個神經網絡也根本沒辦法訓練起來。
  • sigmoid函數的輸出沒有0中心化,這是一個比較鬧心的事情,因爲每一層的輸出都要作爲下一層的輸入,而未0中心化會直接影響梯度下降,我們這麼舉個例子吧,如果輸出的結果均值不爲0,舉個極端的例子,全部爲正的話(例如f=wTx+b 中所有x>0 ),那麼反向傳播回傳到w 上的梯度將全部爲負,這帶來的後果是,梯度更新的時候,不是平緩地迭代變化,而是類似鋸齒狀的突變。當然,要多說一句的是,這個缺點相對於第一個缺點,還稍微好一點,第一個缺點的後果是,很多場景下,神經網絡根本沒辦法學習。

1.3.2 Tanh


Tanh函數

Tanh函數的圖像如上圖所示。它會將輸入值壓縮至-1到1之間,當然,它同樣也有sigmoid函數裏說到的第一個缺點,在很大或者很小的輸入值下,神經元很容易飽和。但是它緩解了第二個缺點,它的輸出是0中心化的。所以在實際應用中,tanh激勵函數還是比sigmoid要用的多一些的。

1.3.3 ReLU


ReLU函數圖像

ReLU是修正線性單元(The Rectified Linear Unit)的簡稱,近些年使用的非常多,圖像如上圖所示。它對於輸入x計算f(x)=max(0,x) 。換言之,以0爲分界線,左側都爲0,右側是y=x這條直線。

它有它對應的優勢,也有缺點:

  • 優點1:實驗表明,它的使用,相對於sigmoid和tanh,可以非常大程度地提升隨機梯度下降的收斂速度。不過有意思的是,很多人說,這個結果的原因是它是線性的,而不像sigmoid和tanh一樣是非線性的。具體的收斂速度結果對比如下圖,收斂速度大概能快上6倍:

    ReLU與收斂速度
  • 優點2:相對於tanh和sigmoid激勵神經元,求梯度不要簡單太多好麼!!!畢竟,是線性的嘛。。。
  • 缺點1:ReLU單元也有它的缺點,在訓練過程中,它其實挺脆弱的,有時候甚至會掛掉。舉個例子說吧,如果一個很大的梯度流經ReLU單元,那權重的更新結果可能是,在此之後任何的數據點都沒有辦法再激活它了。一旦這種情況發生,那本應經這個ReLU回傳的梯度,將永遠變爲0。當然,這和參數設置有關係,所以我們要特別小心,再舉個實際的例子哈,如果學習速率被設的太高,結果你會發現,訓練的過程中可能有高達40%的ReLU單元都掛掉了。所以我們要小心設定初始的學習率等參數,在一定程度上控制這個問題。

1.3.4 Leaky ReLU

上面不是提到ReLU單元的弱點了嘛,所以孜孜不倦的ML researcher們,就嘗試修復這個問題咯,他們做了這麼一件事,在x<0的部分,leaky ReLU不再讓y的取值爲0了,而是也設定爲一個坡度很小(比如斜率0.01)的直線。f(x)因此是一個分段函數,x<0時,f(x)=αx (α 是一個很小的常數),x>0時,f(x)=x 。有一些researcher們說這樣一個形式的激勵函數幫助他們取得更好的效果,不過似乎並不是每次都比ReLU有優勢。

1.3.5 Maxout

也有一些其他的激勵函數,它們並不是對WTX+b 做非線性映射f(WTX+b) 。一個近些年非常popular的激勵函數是Maxout(詳細內容請參見Maxout)。簡單說來,它是ReLU和Leaky ReLU的一個泛化版本。對於輸入x,Maxout神經元計算max(wT1x+b1,wT2x+b2) 。有意思的是,如果你仔細觀察,你會發現ReLU和Leaky ReLU都是它的一個特殊形式(比如ReLU,你只需要把w1,b1 設爲0)。因此Maxout神經元繼承了ReLU單元的優點,同時又沒有『一不小心就掛了』的擔憂。如果要說缺點的話,你也看到了,相比之於ReLU,因爲有2次線性映射運算,因此計算量也double了。

1.4 激勵函數/神經元小總結

以上就是我們總結的常用的神經元和激勵函數類型。順便說一句,即使從計算和訓練的角度看來是可行的,實際應用中,其實我們很少會把多種激勵函數混在一起使用。

那我們咋選用神經元/激勵函數呢?一般說來,用的最多的依舊是ReLU,但是我們確實得小心設定學習率,同時在訓練過程中,還得時不時看看神經元此時的狀態(是否還『活着』)。當然,如果你非常擔心神經元訓練過程中掛掉,你可以試試Leaky ReLU和Maxout。額,少用sigmoid老古董吧,有興趣倒是可以試試tanh,不過話說回來,通常狀況下,它的效果不如ReLU/Maxout。

2. 神經網絡結構

2.1 層級連接結構

神經網絡的結構其實之前也提過,是一種單向的層級連接結構,每一層可能有多個神經元。再形象一點說,就是每一層的輸出將會作爲下一層的輸入數據,當然,這個圖一定是沒有循環的,不然數據流就有點混亂了。一般情況下,單層內的這些神經元之間是沒有連接的。最常見的一種神經網絡結構就是全連接層級神經網絡,也就是相鄰兩層之間,每個神經元和每個神經元都是相連的,單層內的神經元之間是沒有關聯的。下面是兩個全連接層級神經網的示意圖:


2層神經網絡
3層神經網絡

命名習俗
有一點需要注意,我們再說N層神經網絡的時候,通常的習慣是不把輸入層計算在內,因此輸入層直接連接輸出層的,叫做單層神經網絡。從這個角度上說,其實我們的邏輯迴歸SVM是單層神經網絡的特例。上圖中兩個神經網絡分別是2層和3層的神經網絡。

輸出層
輸出層是神經網絡中比較特殊的一層,由於輸出的內容通常是各類別的打分/概率(在分類問題中),我們通常都不在輸出層神經元中加激勵函數。

關於神經網絡中的組件個數
通常我們在確定一個神經網絡的時候,有幾個描述神經網絡大小的參數會提及到。最常見的兩個是神經元個數,以及細化一點說,我們可以認爲是參數的個數。還是拿上面的圖舉例:

  • 第一個神經網絡有4+2=6個神經元(我們不算輸入層),因此有[3*4]+[4*2]=20個權重和4+2=6個偏移量(bias項),總共26個參數。
  • 第二個神經網絡有4+4+1個神經元,有[3*4]+[4*4]+[4*1]=32個權重,再加上4+4+1=9個偏移量(bias項),一共有41個待學習的參數。

給大家個具體的概念哈,現在實用的卷積神經網,大概有億級別的參數,甚至可能有10-20層(因此是深度學習嘛)。不過不用擔心這麼多參數的訓練問題,因此我們在卷積神經網裏會有一些有效的方法,來共享參數,從而減少需要訓練的量。

2.2 神經網絡的前向計算示例

神經網絡組織成以上的結構,一個重要的原因是,每一層到下一層的計算可以很方便地表示成矩陣之間的運算,就是一直重複權重和輸入做內積後經過激勵函數變換的過程。爲了形象一點說明,我們還舉上面的3層神經網絡爲例,輸入是一個3*1的向量,而層和層之間的連接權重可以看做一個矩陣,比如第一個隱藏層的權重W1 是一個[4*3]的矩陣,偏移量b1 是[4*1]的向量,因此用python中的numpy做內積操作np.dot(W1,x)實際上就計算出輸入下一層的激勵函數之前的結果,經激勵函數作用之後的結果又作爲新的輸出。用簡單的代碼表示如下:

# 3層神經網絡的前向運算:
f = lambda x: 1.0/(1.0 + np.exp(-x)) # 簡單起見,我們還是用sigmoid作爲激勵函數吧
x = np.random.randn(3, 1) # 隨機化一個輸入
h1 = f(np.dot(W1, x) + b1) # 計算第一層的輸出
h2 = f(np.dot(W2, h1) + b2) # 計算第二層的輸出
out = np.dot(W3, h2) + b3 # 最終結果 (1x1)

上述代碼中,W1,W2,W3,b1,b2,b3都是待學習的神經網絡參數。注意到我們這裏所有的運算都是向量化/矩陣化之後的,x不再是一個數,而是包含訓練集中一個batch的輸入,這樣並行運算會加快計算的速度,仔細看代碼,最後一層是沒有經過激勵函數,直接輸出的。

2.3 神經網絡的表達力與size

一個神經網絡結構搭起來之後,它就包含了數以億計的參數和函數。我們可以把它看做對輸入的做了一個很複雜的函數映射,得到最後的結果用於完成空間的分割(分類問題中)。那我們的參數對於這個所謂的複雜映射有什麼樣的影響呢?

其實,包含一個隱藏層(2層神經網絡)的神經網絡已經具備大家期待的能力,即只要隱藏層的神經元個數足夠,我們總能用它(2層神經網絡)去逼近任何連續函數(即輸入到輸出的映射關係)。詳細的內容可以參加Approximation by Superpositions of Sigmoidal Function或者Michael Nielsen的介紹。我們之前的博文手把手入門神經網絡系列(1)_從初等數學的角度初探神經網絡也有提到。

問題是,如果單隱藏層的神經網絡已經可以近似逼近任意的連續值函數,那麼爲什麼我們還要用那麼多層呢?很可惜的是,即使數學上我們可以用2層神經網近似幾乎所有函數,但在實際的工程實踐中,卻是沒啥大作用的。多隱藏層的神經網絡比單隱藏層的神經網絡工程效果好很多,即使從數學上看,表達能力應該是一致的。

不過還得說一句的是,通常情況下,我們工程中發現,3層神經網絡效果優於2層神經網絡,但是如果把層數再不斷增加(4,5,6層),對最後結果的幫助就沒有那麼大的跳變了。不過在卷積神經網上還是不一樣的,深層的網絡結構對於它的準確率有很大的幫助,直觀理解的方式是,圖像是一種深層的結構化數據,因此深層的卷積神經網絡能夠更準確地把這些層級信息表達出來。

2.4 層數與參數設定的影響

一個很現實的問題是,我們拿到一個實際問題的時候,怎麼知道應該如何去搭建一個網絡結構,可以最好地解決這個問題?應該搭建幾層?每一層又應該有多少個神經元?
我們直觀理解一下這個問題,當我們加大層數以及每一層的神經元個數的時候,我們的神經網絡容量變大了。更通俗一點說,神經網絡的空間表達能力變得更豐富了。放到一個具體的例子裏我們看看,加入我們現在要處理一個2分類問題,輸入是2維的,我們訓練3個不同神經元個數的單隱層神經網絡,它們的平面表達能力對比畫出來如下:
空間表達能力對比

在上圖中,我們可以看出來,更多的神經元,讓神經網絡有更好的擬合複雜空間函數的能力。但是任何事物都有雙面性,擬合越來越精確帶來的另外一個問題是,太容易過擬合了!!!,如果你很任性地做一個實驗,在隱藏層中放入20個神經元,那對於上圖這個一個平面,你完全可以做到100%把兩類點分隔開,但是這樣一個分類器太努力地學習和記住我們現在圖上的這些點的分佈狀況了,以至於連噪聲和離羣點都被它學習下來了,這對於我們在新數據上的泛化能力,也是一個噩夢。

經我們上面的討論之後,也許你會覺得,好像對於不那麼複雜的問題,我們用更少數目的層數和神經元,會更不容易過擬合,效果好一些。但是這個想法是錯誤的!!!永遠不要用減少層數和神經元的方法來緩解過擬合!!!這會極大影響神經網絡的表達能力!!!我們有其他的方法,比如說之前一直提到的正則化來緩解這個問題。

不要使用少層少神經元的簡單神經網絡的另外一個原因是,其實我們用梯度下降等方法,在這種簡單神經網上,更難訓練得到合適的參數結果。對,你會和我說,簡單神經網絡的損失函數有更少的局部最低點,應該更好收斂。是的,確實是的,更好收斂,但是很快收斂到的這些個局部最低點,通常都是全局很差的。相反,大的神經網絡,確實損失函數有更多的局部最低點,但是這些局部最低點,相對於上面的局部最低點,在實際中效果卻更好一些。對於非凸的函數,我們很難從數學上給出100%精準的性質證明,大家要是感興趣的話,可以參考論文The Loss Surfaces of Multilayer Networks

如果你願意做多次實驗,會發現,訓練小的神經網絡,最後的損失函數收斂到的最小值變動非常大。這意味着,如果你運氣夠好,那你maybe能找到一組相對較爲合適的參數,但大多數情況下,你得到的參數只是在一個不太好的局部最低點上的。相反,大的神經網絡,依舊不能保證收斂到最小的全局最低點,但是衆多的局部最低點,都有相差不太大的效果,這意味着你不需要藉助”運氣”也能找到一個近似較優的參數組。

最後,我們提一下正則化,我們說了要用正則化來控制過擬合問題。正則話的參數是λ ,它的大小體現我們對參數搜索空間的限制,設置小的話,參數可變動範圍大,同時更可能過擬合,設置太大的話,對參數的抑制作用太強,以至於不太能很好地表徵類別分佈了。下圖是我們在上個問題中,使用不同大小的正則化參數λ 得到的平面分割結果。

正則化參數大小與泛化

恩,總之一句話,我們在很多實際問題中,還是得使用多層多神經元的大神經網絡,而使用正則化來減緩過擬合現象。

3. 其他參考資料

1.神經元與含義

大家都知道最開始深度學習與神經網絡,是受人腦的神經元啓發設計出來的。所以我們按照慣例也交代一下背景,從生物學的角度開始介紹,當然也是對神經網絡研究的先驅們致一下敬。

1.1 神經元激勵與連接

大家都知道,人腦的基本計算單元叫做神經元。現代生物學表明,人的神經系統中大概有860億神經元,而這數量巨大的神經元之間大約是通過10141015 個突觸連接起來的。下面有一幅示意圖,粗略地描繪了一下人體神經元與我們簡化過後的數學模型。每個神經元都從樹突接受信號,同時順着某個軸突傳遞信號。而每個神經元都有很多軸突和其他的神經元樹突連接。而我們可以看到右邊簡化的神經元計算模型中,信號也是順着軸突(比如x0 )傳遞,然後在軸突處受到激勵(w0 倍)然後變成w0x0 。我們可以這麼理解這個模型:在信號的傳導過程中,突觸可以控制傳導到下一個神經元的信號強弱(數學模型中的權重w ),而這種強弱是可以學習到的。在基本生物模型中,樹突傳導信號到神經元細胞,然後這些信號被加和在一塊兒了,如果加和的結果被神經元感知超過了某種閾值,那麼神經元就被激活,同時沿着軸突向下一個神經元傳導信號。在我們簡化的數學計算模型中,我們假定有一個『激勵函數』來控制加和的結果對神經元的刺激程度,從而控制着是否激活神經元和向後傳導信號。比如說,我們在邏輯迴歸中用到的sigmoid函數就是一種激勵函數,因爲對於求和的結果輸入,sigmoid函數總會輸出一個0-1之間的值,我們可以認爲這個值表明信號的強度、或者神經元被激活和傳導信號的概率。

神經元生物學模型
神經元數學模型

下面是一個簡單的程序例子,表明前向傳播中單個神經元做的事情:

class Neuron:
  # ... 
  def forward(inputs):
    """ 
    假定輸入和權重都是1維的numpy數組,同時bias是一個數 
    """
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid activation function
    return firing_rate

稍加解釋,每個神經元對於輸入和權重做內積,加上偏移量bias,然後通過激勵函數(比如說這裏是sigmoid函數),然後輸出結果。

特別說明:實際生物體內的神經元相當複雜,比如說,神經元的種類就灰常灰常多,它們分別有不同的功能。而加和信號之後的激勵函數的非線性變換,也比數學上模擬出來的函數複雜得多。我們用數學建模的神經網絡只是一個非常簡化後的模型,有興趣的話你可以閱讀材料1或者材料2

1.2 單個神經元的分類作用

以sigmoid函數作爲神經元的激勵函數爲例,這個大家可能稍微熟悉一點,畢竟我們邏輯迴歸部分重點提到了這個非線性的函數,把輸入值壓縮成0-1之間的一個概率值。而通過這個非線性映射和設定的閾值,我們可以把空間切分開,分別對應正樣本區域和負樣本區域。而對應回現在的神經元場景,我們如果稍加擬人化,可以認爲神經元具備了喜歡(概率接近1)和不喜歡(概率接近0)線性劃分的某個空間區域的能力。這也就是說,只要調整好權重,單個神經元可以對空間做線性分割。

二值Softmax分類器
對於Softmax分類器詳細的內容歡迎參見前面的博文系列,我們標記σ 爲sigmoid映射函數,則σ(iwixi+b) 可視作二分類問題中屬於某個類的概率P(yi=1xi;w) ,當然,這樣我們也可以得到相反的那個類別的概率爲P(yi=0xi;w)=1P(yi=1xi;w) 。根據前面博文提到的知識,我們可以使用互熵損失作爲這個二值線性分類器的損失函數(loss function),而最優化損失函數得到的一組參數W,b ,就能幫助我們將空間線性分割,得到二值分類器。當然,和邏輯迴歸中看到的一樣,最後神經元預測的結果y值如果大於0.5,那我們會判定它屬於這個類別,反之則屬於另外一個類別。

二值SVM分類器
同樣的,我們可以設定max-margin hinge loss作爲損失函數,從而將神經元訓練成一個二值支持向量機分類器。詳細的內容依舊歡迎大家查看之前的博客

對於正則化的解釋
對於正則化的損失函數(不管是SVM還是Softmax),其實我們在神經元的生物特性上都能找到對應的解釋,我們可以將其(正則化項的作用)視作信號在神經元傳遞過程中的逐步淡化/衰減(gradual forgetting),因爲正則化項的作用是在每次迭代過程中,控制住權重w 的幅度,往0上靠攏。

單個神經元的作用,可視作完成一個二分類的分類器(比如Softmax或者SVM分類器)

1.3 常用激勵函數

每一次輸入和權重w線性組合之後,都會通過一個激勵函數(也可以叫做非線性激勵函數),經非線性變換後輸出。實際的神經網絡中有一些可選的激勵函數,我們一一說明一下最常見的幾種:

1.3.1 sigmoid


sigmoid圖像

sigmoid函數提到的次數太多,相信大家都知道了。數學形式很簡單,是σ(x)=1/(1+ex) ,圖像如上圖所示,功能是把一個實數壓縮至0到1之間。輸入的數字非常大的時候,結果會接近1,而非常大的負數作爲輸入,則會得到接近0的結果。不得不說,早期的神經網絡中,sigmoid函數作爲激勵函數使用非常之多,因爲大家覺得它很好地解釋了神經元受到刺激後是否被激活和向後傳遞的場景(從幾乎沒有被激活,也就是0,到完全被激活,也就是1)。不過似乎近幾年的實際應用場景中,比較少見到它的身影,它主要的缺點有2個:

  • sigmoid函數在實際梯度下降中,容易飽和終止梯度傳遞。我們來解釋一下,大家知道反向傳播過程,依賴於計算的梯度,在一元函數中,即斜率。而在sigmoid函數圖像上,大家可以很明顯看到,在縱座標接近0和1的那些位置(也就是輸入信號的幅度很大的時候),斜率都趨於0了。我們回想一下反向傳播的過程,我們最後用於迭代的梯度,是由中間這些梯度值結果相乘得到的,因此如果中間的局部梯度值非常小,直接會把最終梯度結果拉近0,也就是說,殘差回傳的過程,因爲sigmoid函數的飽和殺死了。說個極端的情況,如果一開始初始化權重的時候,我們取值不是很恰當,而激勵函數又全用的sigmoid函數,那麼很有可能神經元一個不剩地飽和無法學習,整個神經網絡也根本沒辦法訓練起來。
  • sigmoid函數的輸出沒有0中心化,這是一個比較鬧心的事情,因爲每一層的輸出都要作爲下一層的輸入,而未0中心化會直接影響梯度下降,我們這麼舉個例子吧,如果輸出的結果均值不爲0,舉個極端的例子,全部爲正的話(例如f=wTx+b 中所有x>0 ),那麼反向傳播回傳到w 上的梯度將全部爲負,這帶來的後果是,梯度更新的時候,不是平緩地迭代變化,而是類似鋸齒狀的突變。當然,要多說一句的是,這個缺點相對於第一個缺點,還稍微好一點,第一個缺點的後果是,很多場景下,神經網絡根本沒辦法學習。

1.3.2 Tanh


Tanh函數

Tanh函數的圖像如上圖所示。它會將輸入值壓縮至-1到1之間,當然,它同樣也有sigmoid函數裏說到的第一個缺點,在很大或者很小的輸入值下,神經元很容易飽和。但是它緩解了第二個缺點,它的輸出是0中心化的。所以在實際應用中,tanh激勵函數還是比sigmoid要用的多一些的。

1.3.3 ReLU


ReLU函數圖像

ReLU是修正線性單元(The Rectified Linear Unit)的簡稱,近些年使用的非常多,圖像如上圖所示。它對於輸入x計算f(x)=max(0,x) 。換言之,以0爲分界線,左側都爲0,右側是y=x這條直線。

它有它對應的優勢,也有缺點:

  • 優點1:實驗表明,它的使用,相對於sigmoid和tanh,可以非常大程度地提升隨機梯度下降的收斂速度。不過有意思的是,很多人說,這個結果的原因是它是線性的,而不像sigmoid和tanh一樣是非線性的。具體的收斂速度結果對比如下圖,收斂速度大概能快上6倍:

    ReLU與收斂速度
  • 優點2:相對於tanh和sigmoid激勵神經元,求梯度不要簡單太多好麼!!!畢竟,是線性的嘛。。。
  • 缺點1:ReLU單元也有它的缺點,在訓練過程中,它其實挺脆弱的,有時候甚至會掛掉。舉個例子說吧,如果一個很大的梯度流經ReLU單元,那權重的更新結果可能是,在此之後任何的數據點都沒有辦法再激活它了。一旦這種情況發生,那本應經這個ReLU回傳的梯度,將永遠變爲0。當然,這和參數設置有關係,所以我們要特別小心,再舉個實際的例子哈,如果學習速率被設的太高,結果你會發現,訓練的過程中可能有高達40%的ReLU單元都掛掉了。所以我們要小心設定初始的學習率等參數,在一定程度上控制這個問題。

1.3.4 Leaky ReLU

上面不是提到ReLU單元的弱點了嘛,所以孜孜不倦的ML researcher們,就嘗試修復這個問題咯,他們做了這麼一件事,在x<0的部分,leaky ReLU不再讓y的取值爲0了,而是也設定爲一個坡度很小(比如斜率0.01)的直線。f(x)因此是一個分段函數,x<0時,f(x)=αx (α 是一個很小的常數),x>0時,f(x)=x 。有一些researcher們說這樣一個形式的激勵函數幫助他們取得更好的效果,不過似乎並不是每次都比ReLU有優勢。

1.3.5 Maxout

也有一些其他的激勵函數,它們並不是對WTX+b 做非線性映射f(WTX+b) 。一個近些年非常popular的激勵函數是Maxout(詳細內容請參見Maxout)。簡單說來,它是ReLU和Leaky ReLU的一個泛化版本。對於輸入x,Maxout神經元計算max(wT1x+b1,wT2x+b2) 。有意思的是,如果你仔細觀察,你會發現ReLU和Leaky ReLU都是它的一個特殊形式(比如ReLU,你只需要把w1,b1 設爲0)。因此Maxout神經元繼承了ReLU單元的優點,同時又沒有『一不小心就掛了』的擔憂。如果要說缺點的話,你也看到了,相比之於ReLU,因爲有2次線性映射運算,因此計算量也double了。

1.4 激勵函數/神經元小總結

以上就是我們總結的常用的神經元和激勵函數類型。順便說一句,即使從計算和訓練的角度看來是可行的,實際應用中,其實我們很少會把多種激勵函數混在一起使用。

那我們咋選用神經元/激勵函數呢?一般說來,用的最多的依舊是ReLU,但是我們確實得小心設定學習率,同時在訓練過程中,還得時不時看看神經元此時的狀態(是否還『活着』)。當然,如果你非常擔心神經元訓練過程中掛掉,你可以試試Leaky ReLU和Maxout。額,少用sigmoid老古董吧,有興趣倒是可以試試tanh,不過話說回來,通常狀況下,它的效果不如ReLU/Maxout。

2. 神經網絡結構

2.1 層級連接結構

神經網絡的結構其實之前也提過,是一種單向的層級連接結構,每一層可能有多個神經元。再形象一點說,就是每一層的輸出將會作爲下一層的輸入數據,當然,這個圖一定是沒有循環的,不然數據流就有點混亂了。一般情況下,單層內的這些神經元之間是沒有連接的。最常見的一種神經網絡結構就是全連接層級神經網絡,也就是相鄰兩層之間,每個神經元和每個神經元都是相連的,單層內的神經元之間是沒有關聯的。下面是兩個全連接層級神經網的示意圖:


2層神經網絡
3層神經網絡

命名習俗
有一點需要注意,我們再說N層神經網絡的時候,通常的習慣是不把輸入層計算在內,因此輸入層直接連接輸出層的,叫做單層神經網絡。從這個角度上說,其實我們的邏輯迴歸SVM是單層神經網絡的特例。上圖中兩個神經網絡分別是2層和3層的神經網絡。

輸出層
輸出層是神經網絡中比較特殊的一層,由於輸出的內容通常是各類別的打分/概率(在分類問題中),我們通常都不在輸出層神經元中加激勵函數。

關於神經網絡中的組件個數
通常我們在確定一個神經網絡的時候,有幾個描述神經網絡大小的參數會提及到。最常見的兩個是神經元個數,以及細化一點說,我們可以認爲是參數的個數。還是拿上面的圖舉例:

  • 第一個神經網絡有4+2=6個神經元(我們不算輸入層),因此有[3*4]+[4*2]=20個權重和4+2=6個偏移量(bias項),總共26個參數。
  • 第二個神經網絡有4+4+1個神經元,有[3*4]+[4*4]+[4*1]=32個權重,再加上4+4+1=9個偏移量(bias項),一共有41個待學習的參數。

給大家個具體的概念哈,現在實用的卷積神經網,大概有億級別的參數,甚至可能有10-20層(因此是深度學習嘛)。不過不用擔心這麼多參數的訓練問題,因此我們在卷積神經網裏會有一些有效的方法,來共享參數,從而減少需要訓練的量。

2.2 神經網絡的前向計算示例

神經網絡組織成以上的結構,一個重要的原因是,每一層到下一層的計算可以很方便地表示成矩陣之間的運算,就是一直重複權重和輸入做內積後經過激勵函數變換的過程。爲了形象一點說明,我們還舉上面的3層神經網絡爲例,輸入是一個3*1的向量,而層和層之間的連接權重可以看做一個矩陣,比如第一個隱藏層的權重W1 是一個[4*3]的矩陣,偏移量b1 是[4*1]的向量,因此用python中的numpy做內積操作np.dot(W1,x)實際上就計算出輸入下一層的激勵函數之前的結果,經激勵函數作用之後的結果又作爲新的輸出。用簡單的代碼表示如下:

# 3層神經網絡的前向運算:
f = lambda x: 1.0/(1.0 + np.exp(-x)) # 簡單起見,我們還是用sigmoid作爲激勵函數吧
x = np.random.randn(3, 1) # 隨機化一個輸入
h1 = f(np.dot(W1, x) + b1) # 計算第一層的輸出
h2 = f(np.dot(W2, h1) + b2) # 計算第二層的輸出
out = np.dot(W3, h2) + b3 # 最終結果 (1x1)

上述代碼中,W1,W2,W3,b1,b2,b3都是待學習的神經網絡參數。注意到我們這裏所有的運算都是向量化/矩陣化之後的,x不再是一個數,而是包含訓練集中一個batch的輸入,這樣並行運算會加快計算的速度,仔細看代碼,最後一層是沒有經過激勵函數,直接輸出的。

2.3 神經網絡的表達力與size

一個神經網絡結構搭起來之後,它就包含了數以億計的參數和函數。我們可以把它看做對輸入的做了一個很複雜的函數映射,得到最後的結果用於完成空間的分割(分類問題中)。那我們的參數對於這個所謂的複雜映射有什麼樣的影響呢?

其實,包含一個隱藏層(2層神經網絡)的神經網絡已經具備大家期待的能力,即只要隱藏層的神經元個數足夠,我們總能用它(2層神經網絡)去逼近任何連續函數(即輸入到輸出的映射關係)。詳細的內容可以參加Approximation by Superpositions of Sigmoidal Function或者Michael Nielsen的介紹。我們之前的博文手把手入門神經網絡系列(1)_從初等數學的角度初探神經網絡也有提到。

問題是,如果單隱藏層的神經網絡已經可以近似逼近任意的連續值函數,那麼爲什麼我們還要用那麼多層呢?很可惜的是,即使數學上我們可以用2層神經網近似幾乎所有函數,但在實際的工程實踐中,卻是沒啥大作用的。多隱藏層的神經網絡比單隱藏層的神經網絡工程效果好很多,即使從數學上看,表達能力應該是一致的。

不過還得說一句的是,通常情況下,我們工程中發現,3層神經網絡效果優於2層神經網絡,但是如果把層數再不斷增加(4,5,6層),對最後結果的幫助就沒有那麼大的跳變了。不過在卷積神經網上還是不一樣的,深層的網絡結構對於它的準確率有很大的幫助,直觀理解的方式是,圖像是一種深層的結構化數據,因此深層的卷積神經網絡能夠更準確地把這些層級信息表達出來。

2.4 層數與參數設定的影響

一個很現實的問題是,我們拿到一個實際問題的時候,怎麼知道應該如何去搭建一個網絡結構,可以最好地解決這個問題?應該搭建幾層?每一層又應該有多少個神經元?
我們直觀理解一下這個問題,當我們加大層數以及每一層的神經元個數的時候,我們的神經網絡容量變大了。更通俗一點說,神經網絡的空間表達能力變得更豐富了。放到一個具體的例子裏我們看看,加入我們現在要處理一個2分類問題,輸入是2維的,我們訓練3個不同神經元個數的單隱層神經網絡,它們的平面表達能力對比畫出來如下:
空間表達能力對比

在上圖中,我們可以看出來,更多的神經元,讓神經網絡有更好的擬合複雜空間函數的能力。但是任何事物都有雙面性,擬合越來越精確帶來的另外一個問題是,太容易過擬合了!!!,如果你很任性地做一個實驗,在隱藏層中放入20個神經元,那對於上圖這個一個平面,你完全可以做到100%把兩類點分隔開,但是這樣一個分類器太努力地學習和記住我們現在圖上的這些點的分佈狀況了,以至於連噪聲和離羣點都被它學習下來了,這對於我們在新數據上的泛化能力,也是一個噩夢。

經我們上面的討論之後,也許你會覺得,好像對於不那麼複雜的問題,我們用更少數目的層數和神經元,會更不容易過擬合,效果好一些。但是這個想法是錯誤的!!!永遠不要用減少層數和神經元的方法來緩解過擬合!!!這會極大影響神經網絡的表達能力!!!我們有其他的方法,比如說之前一直提到的正則化來緩解這個問題。

不要使用少層少神經元的簡單神經網絡的另外一個原因是,其實我們用梯度下降等方法,在這種簡單神經網上,更難訓練得到合適的參數結果。對,你會和我說,簡單神經網絡的損失函數有更少的局部最低點,應該更好收斂。是的,確實是的,更好收斂,但是很快收斂到的這些個局部最低點,通常都是全局很差的。相反,大的神經網絡,確實損失函數有更多的局部最低點,但是這些局部最低點,相對於上面的局部最低點,在實際中效果卻更好一些。對於非凸的函數,我們很難從數學上給出100%精準的性質證明,大家要是感興趣的話,可以參考論文The Loss Surfaces of Multilayer Networks

如果你願意做多次實驗,會發現,訓練小的神經網絡,最後的損失函數收斂到的最小值變動非常大。這意味着,如果你運氣夠好,那你maybe能找到一組相對較爲合適的參數,但大多數情況下,你得到的參數只是在一個不太好的局部最低點上的。相反,大的神經網絡,依舊不能保證收斂到最小的全局最低點,但是衆多的局部最低點,都有相差不太大的效果,這意味着你不需要藉助”運氣”也能找到一個近似較優的參數組。

最後,我們提一下正則化,我們說了要用正則化來控制過擬合問題。正則話的參數是λ ,它的大小體現我們對參數搜索空間的限制,設置小的話,參數可變動範圍大,同時更可能過擬合,設置太大的話,對參數的抑制作用太強,以至於不太能很好地表徵類別分佈了。下圖是我們在上個問題中,使用不同大小的正則化參數λ 得到的平面分割結果。

正則化參數大小與泛化

恩,總之一句話,我們在很多實際問題中,還是得使用多層多神經元的大神經網絡,而使用正則化來減緩過擬合現象。

3. 其他參考資料

參考資料與原文

cs231n 神經網絡結構與神經元激勵函數

發佈了49 篇原創文章 · 獲贊 343 · 訪問量 69萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章