原文:Towards Data Science
deephub翻譯組:zhangzc
自2012年以來,神經網絡研逐漸成為了人工智慧研究的主流,深度模型迅速取代了之前的各種benchmarks。在這些創新中,激活函數對神經網絡的性能和穩定性起著至關重要的作用。這篇文章將儘可能簡要地概述激活函數研究的最新進展,介紹它們的起源以及何時應該被使用。
內容提要
激活函數有什麼作用?增強函數的非線性能力增強函數特定的數值性質ReLU 類激活函數整流器: ReLU,LeakyReLU,和 PReLU指數類: ELU和SELU非單調類: Swish和SERLU特殊的激活函數線性函數:輸出原始數據或進行融合操作Tanh:回歸 +L1/L2正則項Sigmoid:二分類 + 二元交叉熵。Softmax:多分類+ 多元交叉熵結語為什麼要使用激活函數?
簡而言之,激活函數解決了神經網絡中的兩個關鍵問題:
確保函數是非線性映射確保某些輸出具有我們需要的數值性質,例如,輸出值在 [-1, 1] 範圍內,或保證輸出服從某個概率分布。非線性
要了解為什麼需要非線性激活函數,請考慮以下兩個函數:<Object: word/embeddings/oleObject1.bin> 和<Object: word/embeddings/oleObject2.bin>。前者只有兩個參數a,b,而第二個函數有四個參數c,d,e,f。那麼:它們是兩個不同的函數嗎?
答案是否定的,因為"(c +d)"和"a"實際上是一回事,它們的表達能力相同。例如,如果您選擇c = 10和d = 2,我可以選擇 a= 12,我們得到相同的結果。"(e + f)"和"b"也是如此。為了使<Object: word/embeddings/oleObject3.bin>擁有更強的表示能力,它的四個參數不能那樣組合在一起。在數學中,這意味著這些參數之間的關係必須是非線性的。例如,<Object: word/embeddings/oleObject4.bin>是具有四個參數的非線性模型。
在神經網絡中,如果網絡的每層都是線性映射,那麼這些層組合起來依然是線性的。因此,多層的線性映射複合後實際上只是起到了一層的效果。為了使網絡的映射不是線性的,所有層的輸出都要傳遞到非線性函數中,如 ReLU 函數和 Tanh 函數,這樣作用之後就成為了非線性函數。
數值性質
當回答"圖像中是否有存在人臉"時,false 被建模為0,true被為1。給定一張圖像,如果網絡輸出為 0.88,則表示網絡回答為true,因為 0.88 更接近於 1 而不是0。但是,當網絡的輸出是 2 或 -7時。我們如何保證其答案在 [0, 1] 範圍內?
為此,我們可以設計激活函數來保證輸出滿足這些數值性質。對於二分類,sigmoid函數<Object: word/embeddings/oleObject5.bin>將<Object: word/embeddings/oleObject6.bin>內的值映射到 [0, 1] 範圍內。同樣,雙曲切線函數 (tanh(x))將<Object: word/embeddings/oleObject7.bin>內的值映射到 [-1, 1]。對於使用獨熱編碼的分類數據,softmax函數將所有值壓縮到 [0, 1] 內,並確保它們都加起來為 1。
通常只有網絡的最後一層(輸出層)中需要用到這些數值性質,因為它是唯一需要特殊處理的圖層。對於其他的網絡層,可以使用更簡單的非線性函數,例如 ReLU 。雖然在某些情況下,網絡中間層需要特殊激活函數,例如目標檢測模型和attention層,但這些並不常見,因此不在本文討論範圍之內。
ReLU類
在上一節中,我們說明了為什麼需要激活函數,以及它們可以解決哪些問題。此外,我們注意到所有層都需要獨立的激活函數,但這些激活函數只有很少有特殊的功能。對於大部分中間層,通常使用 ReLU類函數作為激活函數。
在討論細節之前,我想強調的是,選擇ReLU類中哪一個函數作為激活函數並沒有很充分的理由。在實踐中,人們需要在十幾個epochs中嘗試,看看哪些函數在任務上表現最好。
也就是說,根據經驗法則,在建立模型的時候中儘可能先選擇原始 ReLU 作為激活激活。如果模型性能不佳,遵循Tensorflow 2 文檔(對於 PyTorch 用戶也適用)中給出的建議,再選擇 SELU 作為激活函數,並去掉所有的batch normalization。我知道這聽起來有點不可思議,但這很有效,通常可以給網路帶來5%到10%的提升效果。
下圖總結了 ReLU 類中最常用的激活函數圖(左)及其在 CIFAR-10 數據集上的表現(右圖)。
Figure :ReLU類中最常用的函數圖(左)及其各自在CIFAR10數據集上的性能,共訓練了200epochs,沒有用Dropout。圖像來源: Effectiveness of Scaled Exponentially-Regularized Linear Units (SERLUs)
線性整流單元 (The Rectifier Linear Unit ,ReLU)
ReLU的數學定義是:
ReLU(x) = max(0,x)
用文字來表述,如果x為正,則返回x,如果x為負,則返回 0。
這是最簡單的非線性激活函數之一,因為計算最大函數值非常簡單。ReLU 函數最早在AlexNet 體系結構中使用,該網絡使用此激活函數訓練速度幾乎是傳統 Tanh 函數的八倍。直到今天,大多數網絡還是會選擇ReLU,因為它們在計算上簡單有效,這是「雙贏」的選擇。
此外,早期的神經網絡受到梯度爆炸/消失問題的困擾。總的來說,在反向傳播期間,不同層的梯度在網絡反向傳播中時會相乘,因此具有較大數值的梯度會越傳越大(爆炸),接近零的梯度使得後面的梯度會變的更小(消失)。而使用 ReLU 激活,只有兩個可能的情況:正部分的梯度是1,負部分的梯度是0。ReLU有效地解決了梯度爆炸這一問題,但是卻也導致了梯度死亡或者神經元壞死現象。
Leaky單元
大多數人第一次看到ReLU時會提出這樣的問題:負部分真的需要被捨棄掉嗎?對此,研究人員提出了Leaky ReLU,它會弱化負部分的影響,而不是直接扔掉。Leaky ReLU在數學上的表達式如下:
LeakyReLU(x) = max(0, x) + min(0.01 x, 0)
這樣,一個負值信號不會被完全丟棄,在「Leaky因子」的作用下會保留一部分負值信號的特徵。實踐證明了在某些情況下「Leaky因子」是有效的。此外,它緩解了梯度死亡的問題,允許部分負值信號通過。在下面要介紹的激活函數中,一個反覆出現的話題就是如何修正ReLU的負部分。
接下來要介紹的是參數化 ReLU,簡稱 PReLU。通過理性的思考我們會問:為什麼Leaky單元的係數是0.01?所以我們引入一個變量<Object: word/embeddings/oleObject8.bin>,這樣,我們不需要自己定義Leaky因子,而是讓網絡自己學習最合適的變量值。PReLU的表達式如下:
PReLU(x) = max(0,x) = min(<Object: word/embeddings/oleObject9.bin>x,0)
請記住<Object: word/embeddings/oleObject10.bin>變量不是全局變量。每個整流單元都有可訓練的<Object: word/embeddings/oleObject11.bin>。這種激活函數展示了數據科學的思維方式:如果能夠讓模型決定什麼是最佳,為什麼自己要設置?
指數單位
尋找性能更好的激活函數的研究還在繼續,使用指數函數作為ReLU負部分的想法出現在2015年末。指數函數對負數是飽和的,這意味著它平滑地趨向於一個常數。使用指數函數我們可以更好地模擬原始的ReLU函數,同時在一定程度上保留負部分。下面是ELU的數學公式:
ELU(x) = max(0, x) + min(e — 1, 0)
在許多情況下,ELU函數比原始 ReLU 函數有更好的表現。相比之下,Leaky單元的加入並不一定使ReLU有更好的表現。
縮放指數線性單元(Scaled Exponential Linear Unit,SELU)是該領域的最新進展之一,其主要創新是self-normalizing。當訓練時,它的輸出均值是0,方差是1。實際上,這種self-normalizing會使batch normalization變得冗餘。因此,使用 SELU 的模型會更簡單,需要的操作更少。self-normalizing是用常數縮放正負部分來實現的,其數學表達式:
SELU(x) ≈ 1.0507 max(0, x) + 1.7580 min(e — 1, 0) 有關這個激活函數的使用和係數推導的更多細節,請參閱論文和Tensorflow文檔。上述常數是通過將最初的SELU簡化為更緊湊的形式得到的。
非單調激活函數
到目前為止,ReLU類的所有激活函數都是單調遞增的。用文字來表述,這意味著函數值只會增長。標誌性的非單調函數如,拋物線(x)先下降後增長,正弦函數(sin (x))周期性的上升和下降。第一個成功提出非單調激活函數的是Google Brain team,他們提出的非單調激活函數叫做Swish函數,它被定義為:
F(x) = x σ(x)
σ(x)代表的是sigmoid 函數。雖然此表達式與 ReLU 函數不同,但他們的函數圖像 是明顯相似的,其正部分基本相同,而Swish函數在負部分有一個「凹陷」且在負無窮除趨近於零(Fig1)。這是通過"自控"機制實現的:假設x是"信號",σ(x)是一個「門函數」(一個飽和於0的函數),σ(x)乘以x是就是讓信號進行自我控制。在實驗中,他們發現這種激活函數在非常深的網絡(30 層)中優於 ReLU 函數。
最後,SERLU 激活函數是對 SELU 的改進,在保留self-normalizing的同時,引入了「自控機制」使負值極限於零。作者沒有用sigmoid函數,而是使用指數函數作為「門函數」,並重新計算常係數來實現self-normalizing。這導致函數的負部分類似於 Swish 函數,出現了比Swish 函數更明顯的"凹陷"(圖 1,紅色曲線)。SERLU 的數學表達式為:
SERLU(x) ≈ 1.0786 max(0, x) + 3.1326 min(x e — 1, 0)
請注意 x e 和x σ(x)之間的相似性,兩者都實現了自控機制。
雖然現在已經是2020 年,但判斷這些非單調函數是否能經受時間考驗,是否能替代ReLU 或 SELU作為通用的激活函數還為時過早。不過我敢打賭,self-normalizing這個操作將會一直存在。
特殊的激活函數
如前所述ReLU並非萬能的,神經網絡有些層需要特殊的激活函數,對於這些層,可以使用線性、sigmoid、tanh 和 softmax 等激活函數,下面給出了一些例子:
線性激活函數:當您需要網絡的原始輸出時可以用線性函數。線性函數對於融合操作很有用,例如sigmoid 交叉熵和softmax交叉熵函數,它們在數值上更穩定。此外,在理論分析中,這種激活函數對於調試和簡化網絡非常有用。Tanh: 可用於正則化回歸問題,其輸出在 [-1, 1] 範圍內。通常與 L2 損失結合使用。Sigmoid: 用於二分類問題中。將輸出壓縮到 [0, 1] 範圍內。大部分時候都與二元交叉熵損失一起使用。Softmax:在多分類中經常使用,使網絡輸出的是有效的概率分布。這意味著所有值都在 [0, 1] 範圍內,且總和為 1。可與多元交叉熵損失一起使用。正如您所看到的,給出一個問題,選擇使用哪個激活函數是非常簡單的事情。此外,選定激活函數也表明了應使用或考慮哪些損失函數。如前所述,經驗法則告訴我們在大部分情況下都要使用 ReLU 激活函數,然後為輸出層選擇最合適的特殊激活函數,並在以後的訓練中擴大選擇範圍並嘗試替代這些函數。
最後值得一提的是,對於一些分類問題,類別之間不是相互排斥的。在此特殊情況下,單個輸入可能被對應多個類。在這些情況下是應按類使用Sigmoid,而不是用softmax。這樣,所有輸出都被壓縮到 [0, 1] 範圍,但它們的和不是1。
結語
本文回顧了激活函數中的state-of-the-art,並介紹了如何選擇和使用它們。總之,激活函數使網絡變成非線性的映射,使得輸出層具有某些數值性質。對於中間層,使用 ReLU 類的激活函數。並且根據經驗,儘可能地使用 ReLU,然後再考慮用 SELU 激活函數並刪除所有batch normalization操作。對於輸出層,請考慮對非正則化/正則化回歸使用線性/tanh激活函數,對二分類/多分類使用 sigmoid/softmax。
很少有一本指南能面面俱到,有些東西總是會被遺漏。在這裡,我故意遺漏了那些不太為人所知或使用的函數,如softplus, softsign,和relu6函數。我選擇這樣做,是為了使保持文章儘可能簡短的同時,讓大家了解常用的激活函數。如果您未能理解這篇文章中的任何函數,不同意我的論述,或希望看到一些擴展的概念,請在評論部分留言讓我知道,我會儘可能保持本文檔的更新:)