激活函數可視化
https://segmentfault.com/a/1190000014001934?utm_source=channel-hottest
前言
簡單來說,激活函數在神經網絡裏的作用就是引入Non-linearity。假如沒有激活函數的話,一個多層的神經網絡等同於一個一層的神經網絡。簡單來說,一個神經網絡的層可以寫成$act(WX)$,其中$W$是權重,$act$是激活函數。兩層也就是 $act(W_2(act(W_1X)))$,如果現在沒有了$act$,那這兩層就能寫成$W_2W_1X$,然後我們簡單的用$W=W_2W_1$替換,就變成了$WX$。也就是一個兩層的神經網絡退化成了一個單層的神經網絡。
所以說激活函數在神經網絡裏面是必要的,但不同的激活函數有各自的優缺點,在不同的任務中,大家會選擇不同的激活函數。現在很難一概而論說哪個激活函數一定就最好。所以最好還是多試幾個,找到最適合自己任務的。
所以這篇文章也不會給出一個最好的激活函數,也就是講講每種激活函數的特性。看看激活函數是如何引入非線性的,以及神經網絡如何利用這個非線性做而分類的。
激活函數介紹
S形(Sigmoidal)函數
Sigmoid函數是神經網絡初期的激活函數。更早的是在Percepton裏面使用的threshold函數,不過threshold函數零點不可導,其他部分導數又全是0,無法通過Backpropagation(BP)訓練,故這裏不做介紹。Sigmoid函數可以看作threshold函數的soft版本,它從0平滑的過渡到1。在之後又發展出多種S形的激活函數,先上公式和圖像(函數圖$f(x)$及導數圖$f‘(x)$):
Sigmoid: f(x)=11+e−x
Tanh: f(x)=ex−e−xex+e−x
從圖中可以看到sigmoid導數小,最大的地方導數才0.25,這樣在BP的時候,往後乘一乘梯度就沒有嘞,也就是深層網絡經常會遇到的Gradient Vanishing(梯度消失)。另外sigmoid的輸出在0-1之間,而神經網絡更好的輸入的值是關於原點對稱的。
tanh作為sigmoid的改進版,一定程度上減輕了以上的兩個問題,tanh在原點附近接近$f(x)=x$,關於原點對稱且在原店附近導數接近1。就是希望能夠做到原點附近的數據不被壓縮能夠很好的傳遞到下一層,而周邊的數據被一定程度的壓縮來引入非線性。
其他不常用的激活函數如反正切$arctan$,$softsign$,以及Inverse Square Root Unit(ISRU)同樣減輕了以上問題。從導數的函數圖中可以看到$arctan$的導數較大,估計對學習速度應該會有幫助。sigmoid和tanh被廣泛使用據說是因為導數比較好求(來自這裏)。$\sigma‘(x) = \sigma(x) (1-\sigma(x)) $,$tanh‘(x) = 1 - tanh^2(x) $。
ReLU及其變體
上面說的Sigmoidal函數都或多或少都存在梯度消失的問題,這使得深層的網絡難以訓練。後來出現的ReLU(Rectified Linear Unit)基本解決了這個問題,它保證了至少在$x>0$的時候導數是不會減少的。這樣在BP的過程中梯度就不會莫名消失。只不過ReLU有個dead neuron的問題,從函數圖上可以看到,負半軸的值為0導數也為0,也就是forward pass和backward pass都不能傳遞任何信息。在使用ReLU的時候不要用太大的learning rate,否則很容易造成一堆dead neuron。
後來出現了Leaky ReLU(LReLU)解決了dead neuron的問題,而且使得輸出數據分布在0的兩側,一定程度上對學習有幫助。後來有人做了一些改進如Parametric ReLU (PReLU)以及Randomized ReLU (RReLU)。在PReLU裏,下面公式裏的$\alpha$是變量,可通過BP學習,Randomized ReLU則是在訓練時隨機在一定範圍內選擇$\alpha$,而在測試中則是使用均值。如訓練時$\alpha$在 $\left[0.1,0.3\right]$ 範圍內隨機選擇,則在測試時$\alpha$的值即為$0.2$。
ReLU: f(x)={0,x,x < 0x ≥ 0
ReLU6: f(x)=???0,x,6,x < 00 ≤ x ≤ 6x > 6
Leaky ReLU: f(x)={αx,x,x < 0x ≥ 0, where 0<α<1
形狀差不多的還有Softplus,Swish,Exponential Linear Unit (ELU),以及Scaled ELU(SELU),公式如下:
Softplus: f(x)=log(1+ex)
ELU: f(x)={αex−1,x,x < 0x ≥ 0
SELU: f(x)={s(αex−1),sx,x < 0x ≥ 0
其中SELU的$a = 1.6732632423543772848170429916717$,$s = 1.0507009873554804934193349852946$。這兩個數字都是作者在論文中算出來的。90頁的推導過程,簡直神一般。
Softplus相對ReLU的好處是其在每個點的導數都不為0,避免了使用ReLU出現的dead neuron的問題。ELU相對於ReLU的優點是其輸出在原點兩側且在每個點導數都不為0。SELU在論文中介紹的優點是,如果輸入是均值為0,標準差為1的話,經過SELU激活之後,輸出的均值也為0,標準差也為1,如果是這樣的話,不知道是不是能少用幾層Batch Norm。這三個激活函數的計算時間較ReLU,Leaky ReLU要長,當想要極限的優化網絡速度的時候,這也能是一個優化點。
上圖!
其他激活函數
Swish是最近(2017.10) Google Brain提出的激活函數,據說效果不錯,Tanh-shrink和Bent-identity分別是在pytorch內建的激活函數庫和Wikipedia上看到的,在此也附上圖。後續想做個測試,應該也蠻有意思的!在這兒就先附上公式和圖。
Swish: f(x)=xσ(x), where σ is sigmoid function
Tanh-shrink: f(x)=x−tanh(x)
Bent-identity: f(x)=x2+1−−−−−√−12+x
神經網絡如何改變數據分布
上面的分析給出了激活函數的定義,接下來我們看看激活函數如何改變數據分布。這裏用一個中心點在原點的螺旋狀的數據(見下圖中identity一列)來表示數據分布,為了讓圖形簡單一點,咱們忽略bias,於是一個層可以寫作$H=act(WX)$。從公式可以看出,神經網絡的一層會對輸入的數據先做一個線形的變換,然後再通過激活函數做非線性的變換。之後我們再把激活後的數據映射回原來的空間($X‘ = W^{-1}H$)。這麽做的結果是,對於激活函數不改變的點,它該在什麽位置就還在什麽位置,也就可以和原圖的螺線比較著看激活函數的效果。
這個螺線的數據的$x, y$可以作為兩個節點的輸入層的輸入數據。這裏的$W$的維度可以有多種理解。
1\. 假設$W$是一個$n\times2$的矩陣,那麽這個$act(WX)$就相當與一個$n$個節點的隱層;
2\. 從空間的角度上說,這相當於把數據映射到一個$n?$維的空間後,再在新的空間中做非線性變換;
3\. 把$W$拆成$n$個$1\times2$的矩陣,就還可以理解成$n$個$X$的線形組合,在思考決策邊界的時候有用。
這裏主要采用第二種思維,下面這張圖各列顯示了不同的激活函數在$n=2,5,30$時對應的變換。讓$W$的值都在$[-1,1]$之間取值,這樣$W$就能在映射到$2,5,30$維空間時產生旋轉、縮放、斜切、拉伸等效果(不包括平移)。
這裏我就選了幾種激活函數玩玩。可以看到identity函數($f(x)=x$)是不改變數據形狀的,不管映射到多少維。S型函數將周圍的一圈都映射到了一起去,其中sigmoid擠壓的最甚(所以輸入的時候一定得standardize,否則信息全都被壓縮了)。ReLU很好的保留了其中的一部分信息,且醉著維度的增加,保留的信息也增加(MobileNet V2就是基於這種想法設計了Inverted Residual Block)。ELU其實在低維就能夠保存不少信息,看起來圖形會稍微好看一些,實際的效果還是有待驗證。tanhshrink覺得比較有意思也就加上去了。
神經網絡學習的過程
上面給出了神經網絡如何扭曲數據分布的,其實在$W$隨機取值的情況下,我們很難去理解神經網絡如何去學習的,下面來看看神經網絡如何根據標簽改變扭曲的過程。這裏就選了ReLU和Sigmoid,4個節點的隱層。最後使用了softmax做分類,下圖顯示了輸入數據和對應的神經網絡。
不同於以上的圖在輸入數據$(x, y)$的二維空間,下面這些圖的橫坐標和縱坐標分別是$x‘, y‘$,這兩個值是unnormalized probability。對於一個坐標點$(x‘, y‘)$,假如 $x‘>y‘$,則預測類別為藍點,反之則為紅點。所以這裏我們也把$y‘=x‘$這條線畫出來,代表了在$x‘, y‘$這個平面的決策邊界。以下是以ReLU為激活函數的神經網絡學習的過程,從螺線可以看出來原始的數據分布正在慢慢的被扭曲,直到這條黑線能夠穿過紅線和藍線之間。在訓練的過程中,每個紅點都會把它周圍的空間(藍線)往左上角拉,相反每個藍點都會往右下角拉,在這兩個力以及權重衰減的力的作用下,空間就會被扭曲成需要的樣子(如右下角所示)。
下面這張圖顯示了Sigmoid學習的過程。和ReLU的情況很像,只是它扭曲的方式不太一樣
兩個學習的過程都特別的像折紙,對,就是折紙!當你發現直直的一剪刀剪不出個圓的時候,你就可以考慮折出幾個皺褶,然後再給一剪刀。再提一下,如果是多個隱層的話,相當於把上面的圖當作輸入再進行扭曲。從折紙的角度上說,就類似於“對折再對折再對折”這種做法,這樣就能用少量的隱層節點做出更多的非線性(褶子)。
神經網絡學習的結果
最後來看看不同激活函數的決策邊界(下圖)。這次的坐標還是原始輸入的$(x, y)$,這相當於把上面的圖往回展平以後,上圖的黑線所在的位置。Sigmoid 4的意思就是對於一個4個節點的隱層,使用Sigmoid作為激活函數的神經網絡。可以看出決策邊界是由3個不同斜率的決策邊界組成的(實際上這裏有4條邊界,有兩個決策邊界太近了就沒體現出來)。Softplus可以看出來這4條邊,ReLU這張圖雖然只有6個邊界,但它其實可以有8條,這是因為當兩個ReLU形成的決策邊界相交時,會產生兩個轉折點,4個決策邊界能產生8條線。
最後試了一下300個隱層的情況,可以看出來決策邊界已經很接近圓了。是的!等於多折幾下,再給一刀。
如果想玩動圖,就上這兒http://playground.tensorflow....
結論
所以說,神經網絡就像剪紙,激活函數決定怎麽折,節點數決定在原圖上折幾個折痕,隱層的數量決定折幾次。
如果想讓結果在$(0,1)$之間,使用sigmoid(如LSTM的各種gates);如果想訓練的很深,不要用S系的;ReLU,LReLU什麽的多試幾個,不會錯的。
需要註意如果使用ReLU,則最好使用He Initialization。實際上這次的實驗中所有ReLU系的激活函數(除了Softplus),使用He Initialization都收斂的比較快。如果使用Sigmoid,則使用Xavier Initialization,要不真的能把空間扭曲成一個奇怪的形狀,然後長時間不收斂
激活函數可視化