最全的激活函數詳解

博客已遷至知乎,本文鏈接:https://zhuanlan.zhihu.com/p/70821070

前言

這篇文章首先講了神經網絡中爲什麼要引入激活函數,以及一個激活函數應該具有哪些性質。最後詳細地對比了幾種常見的激活函數的優缺點,其中重點講了sigmoid函數的非0均值問題和ReLU函數的Dead ReLU問題。


神經元

圖片來自:https://zhuanlan.zhihu.com/p/25110450

上圖是一個神經元的設計,其傳輸模式類似於人類大腦神經元之間的信息傳遞。在一個神經元中,突觸(synapse)接受其它神經元的軸突(axon)傳來的信息,通過軸突將信息傳遞出去。

在這裏,所有xix_i是其它神經元的軸突傳來的信息,所有wiw_i 是突觸接收信息的程度,所有wixiw_ix_i則是其它神經元軸突上傳來的信息。這些信息經由神經元整合後,z=wixi+bz=\sum w_ix_i+b,再由激活函數f(z)f(z)激活。

在這裏,整合的過程是線性加權的過程,各輸入特徵xix_i之間沒有相互作用。而激活函數都是非線性的,各輸入特徵xix_i在此處相互作用


在神經網絡中,爲什麼要引入激活函數呢?

簡而言之,只有線性的模型表達能力不夠,不能擬合非線性函數,激活函數(Activation Function)是非線性的,只要給予網絡足夠的隱藏單元,線性+激活函數可以無限逼近任意函數(萬能近似定理)。

萬能近似定理:Hornik et al. 1989; Cybenko, 1989

加與不加的區別:
線性函數 f(x)=Wx+bf(x)= Wx+b 之後添加激活函數g(a)g(a),變成
a(x)=g(f(x))=g(Wx+b)a(x)=g(f(x))=g(Wx+b)

神經網絡一般都是多層的,所以拿出前三層(包括輸入層)來看:有
a2(x)=g2(f2(g1(f1(x)))a_2(x) = g_2(f_2(g_1(f_1(x)))

而如果不加激活函數,這三層是這樣的:
y(x)=f2(f1(x))y(x)=f_2(f_1(x))

f(x)f(x)帶入上一個表達式:
y(x)=f2(f1(x))=W2(W1x+b1)+b2=W2W1x+(W2b1+b2)y(x)=f_2(f_1(x))=W_2(W_1x+b_1)+b_2=W_2W_1x+(W_2b_1+b_2)

可以看出來網絡還是線性的,還是沒有擬合非線性函數的能力,而且不管網絡有幾層都還是相當於單層線性網絡。


一個激活函數應該是什麼樣子的?

  1. 非線性:這是必須的,也是添加激活函數的原因。
  2. 幾乎處處可微:反向傳播中,損失函數要對參數求偏導,如果激活函數不可微,那就無法使用梯度下降方法更新參數了。(ReLU只在零點不可微,但是梯度下降幾乎不可能收斂到梯度爲0)
  3. 計算簡單:神經元(units)越多,激活函數計算的次數就越多,複雜的激活函數會降低訓練速度。
  4. 非飽和性:飽和指在某些區間梯度接近於零,使參數無法更新。Sigmoid和tanh都有這個問題,而ReLU就沒有,所以普遍效果更好。
  5. 有限的值域:這樣可以使網絡更穩定,即使有很大的輸入,激活函數的輸出也不會太大。

幾種常見的激活函數

Sigmoid

圖片來自:https://zhuanlan.zhihu.com/p/25110450

Sigmoid函數公式:
f(x)=11+exf(x)=\frac{1}{1+e^{-x}}

Sigmoid函數將輸入的值映射到0~1之間,輸入數值 (有正有負,正數>負數) 越小越接近0,數值越大越接近1。Sigmoid激活函數之所以流行過一段時間是因爲它能夠表達“激活”的意思,0爲未激活,1爲激活。
但由於以下三個缺點,現在Sigmoid已經不常用了。

1. Sigmoid容易飽和
輸入太大或太小都會使其梯度接近0,這點從圖像就能看出來,在反向傳播中梯度接近0時參數就會難以更新。另外還需要將參數初始化得比較小才能避免剛開始就梯度爲0。

2. Sigmoid的輸出不是0均值的
比如激活函數:(式中xx是上層神經元的輸出,也是這層神經元的輸入)
f(x,w,b)=f(wixi+b)f(x,w,b)=f(\sum w_ix_i+b)

訓練過程中通過反向傳播學習參數,即通過鏈式法則,求損失函數L(x)L(x)對某一參數wiw_i的偏導數(梯度),通過以下式子更新參數wiw_i:(其中η\eta是學習率)
wiwiηLwiw_i \gets w_i - \eta\cdot\frac{\partial L}{\partial w_i}
L(x)L(x)wiw_i求偏導:
Lwi=Lffwi=Lfxif(1f)\frac{\partial L}{\partial w_i} = \frac{\partial L}{\partial f}\frac{\partial f}{\partial w_i}=\frac{\partial L}{\partial f}\cdot x_i\cdot f(1-f)

參數更新方向:
因爲此處的ffsimgoidsimgoid函數,值域爲(0, 1),所以f(1f)f(1-f)恆大於0,又因爲Lf\frac{\partial L}{\partial f}對所有wiw_i是常數,所以wiw_i更新的方向完全由xix_i的符號決定,xix_i是上層Sigmoid激活函數的輸出,即xi>0x_i>0,所有xix_i的符號是一樣的,所以所有參數wiw_i的更新方向只能一致。
舉個例子:如果向最優解優化,參數w1w_1需要變小,而w2w_2需要變大,而每次梯度下降w1w_1w2w_2只能向一個方向更新,只能一起變大或一起變小,這樣模型收斂就需要消耗很多的時間。
而如果所有xix_i是零均值的,有正有負的,就不會出現上面的問題了。

3.冪運算相對比較耗時:這個不算太大的問題

tanh

函數公式:
f(x)=exexex+exf(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}

圖片來自:https://zhuanlan.zhihu.com/p/25110450

tanh激活函數的性質幾乎和Sigmoid一樣,主要解決了Sigmoid的輸出非0均值問題,模型收斂更快,但還是存在梯度消失的問題。另外Sigmoid的這個輸出0~1的性質可以使它的輸出作爲概率使用。

ReLU

ReLU,線性整流函數(Rectified Linear Unit),又稱修正線性單元。
函數公式:
f(x)=max(0,x)f(x)=max(0,x)

圖片來自:https://zhuanlan.zhihu.com/p/25110450

Relu是近幾年最常用且很有效的激活函數,雖然也有缺陷但還是推薦優先使用。
優點:
1.解決了梯度消失問題(正區間)
2.計算速度快,只需要判斷正負
3.收斂速度比Sigmoid和tanh快很多
缺點:
1.輸出不是0均值的
2.Dead ReLU Problem:一些神經元可能永遠不能被激活,導致相應參數不能更新。下面分析一下這個問題的原因:

首先我們把ww參數的更新公式寫出來:式中η\eta是學習率
wiwiηLwiw_i \gets w_i - \eta\cdot\frac{\partial L}{\partial w_i}

損失函數對wiw_i求導(激活函數爲ReLU):式中xix_i是上層神經元的輸出(上層激活函數的輸出)
Lwi=Lffwi=Lfxi\frac{\partial L}{\partial w_i} = \frac{\partial L}{\partial f}\frac{\partial f}{\partial w_i}=\frac{\partial L}{\partial f}\cdot x_i

將兩個式子合併:
wiwiηLfxiw_i \gets w_i - \eta\cdot \frac{\partial L}{\partial f}\cdot x_i

因爲xix_i是上層各個神經元的輸出,即上層每個神經元的激活函數的輸出,可知其值一定爲0或者正數,爲方便說明現在假設xix_i都爲正數。看上式,現在xix_i爲正數,學習率η\eta肯定也是正數,若損失函數對激活函數的導數Lf\frac{\partial L}{\partial f}也是正數且足夠大,並假設學習率η\eta也不小,那麼很多wiw_i更新這一次後就變成了負數,這會造成什麼影響呢?看該層網絡的下次前向傳播公式:
a=f(x,w,b)=ReLU(wixi+b)a=f(x,w,b)=ReLU(\sum w_ix_i+b)

其中aa是這個神經元的輸出,下層網絡的輸入。由上面假設,所有xix_i都爲正數,多數wiw_i爲負數,那麼:wixi+b\sum w_ix_i+b很大概率是個負數,由ReLU圖像可知,輸入爲負數,輸出就爲0,即a=ReLU()=0a=ReLU(負數)=0
由前向傳播公式可以看出,若神經元的輸出爲0,那麼該神經元的前向傳播在該層與下層網絡之間就斷開了,從而反向傳播也就斷了。

造成Dead ReLU Problem問題的主要原因可能爲:
1.學習率η\eta太大導致參數更新幅度太大
2.糟糕的權重初始化

爲了解決成Dead ReLU Problem問題,又有了Leaky ReLU函數和ELU (Exponential Linear Units) 函數。

Leaky ReLU

函數公式:
f(x)=max(0.01x,x)f(x)=max(0.01x,x)

圖片來自:https://zhuanlan.zhihu.com/p/25110450

前半段是0.01x而不是0,解決了Dead ReLU Problem問題。
還有一種想法是通過反向傳播訓練這個前半段函數:f(x)=max(αx,x)f(x)=max(\alpha x,x),其中α\alpha可以訓練。
雖然這兩種函數理論上比ReLU好,但是實踐中並沒有完全證明優於ReLU。

ELU (Exponential Linear Units)

函數公式:
f(x)={x,                          x>0α(ex1),x<=0f(x)=\begin{cases} x,\;\;\;\;\;\;\;\;\;\;\;\;\; x>0 \\ \alpha (e^x-1), x<=0\end{cases}

圖片來自:https://zhuanlan.zhihu.com/p/25110450

雖然也解決了Dead ReLU Problem,並且輸出接近0均值,但是也沒有在實踐中完全證明優於ReLU。


總結

Sigmoid可以當作概率輸出使用,但不建議當作中層激活函數。推薦使用ReLU,需要注意學習率的設置,ReLU變種可以嘗試。


references

[1] 深度學習(Deep Learning) Yoshua Bengio & Ian Goodfellow
[2] 神經網絡中激活函數的真正意義?一個激活函數需要具有哪些必要的屬性?還有哪些屬性是好的屬性但不必要的?
[3]【機器學習】神經網絡-激活函數-面面觀(Activation Function)
[4] 談談激活函數以零爲中心的問題
[5] ‘Dead ReLU Problem’ 產生的原因

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章