github博客傳送門
csdn博客傳送門
神經網絡中激活函數的真正意義?一個激活函數需要具有哪些必要的屬性?還有哪些屬性是好的屬性但不必要的?
1. 非線性:
即導數不是常數。這個條件是多層神經網絡的基礎,保證多層網絡不退化成單層線性網絡。這也是激活函數的意義所在。
2. 幾乎處處可微:
可微性保證了在優化中梯度的可計算性。傳統的激活函數如sigmoid等滿足處處可微。對於分段線性函數比如ReLU,只滿足幾乎處處可微(即僅在有限個點處不可微)。對於SGD算法來說,由於幾乎不可能收斂到梯度接近零的位置,有限的不可微點對於優化結果不會有很大影響。
3. 計算簡單:
非線性函數有很多。極端的說,一個多層神經網絡也可以作為一個非線性函數,類似於Network In Network中把它當做卷積操作的做法。但激活函數在神經網絡前向的計算次數與神經元的個數成正比,因此簡單的非線性函數自然更適合用作激活函數。這也是ReLU之流比其它使用Exp等操作的激活函數更受歡迎的其中一個原因。
4. 非飽和性(saturation):
飽和指的是在某些區間梯度接近於零(即梯度消失),使得參數無法繼續更新的問題。最經典的例子是Sigmoid,它的導數在x為比較大的正值和比較小的負值時都會接近於0。更極端的例子是階躍函數,由於它在幾乎所有位置的梯度都為0,因此處處飽和,無法作為激活函數。ReLU在x>0時導數恆為1,因此對於再大的正值也不會飽和。但同時對於x<0,其梯度恆為0,這時候它也會出現飽和的現象(在這種情況下通常稱為dying ReLU)。Leaky ReLU和PReLU的提出正是為了解決這一問題。
5. 單調性(monotonic):
即導數符號不變。這個性質大部分激活函數都有,除了諸如sin、cos等。個人理解,單調性使得在激活函數處的梯度方向不會經常改變,從而讓訓練更容易收斂。
6. 輸出范圍有限:
有限的輸出范圍使得網絡對於一些比較大的輸入也會比較穩定,這也是為什么早期的激活函數都以此類函數為主,如Sigmoid、TanH。但這導致了前面提到的梯度消失問題,而且強行讓每一層的輸出限制到固定范圍會限制其表達能力。因此現在這類函數僅用於某些需要特定輸出范圍的場合,比如概率輸出(此時loss函數中的log操作能夠抵消其梯度消失的影響)、LSTM里的gate函數。
7. 接近恆等變換(identity):
即約等於x。這樣的好處是使得輸出的幅值不會隨着深度的增加而發生顯著的增加,從而使網絡更為穩定,同時梯度也能夠更容易地回傳。這個與非線性是有點矛盾的,因此激活函數基本只是部分滿足這個條件,比如TanH只在原點附近有線性區(在原點為0且在原點的導數為1),而ReLU只在x>0時為線性。這個性質也讓初始化參數范圍的推導更為簡單。這種恆等變換的性質也被其他一些網絡結構設計所借鑒,比如CNN中的ResNet和RNN中的LSTM。
8. 參數少:
大部分激活函數都是沒有參數的。像PReLU帶單個參數會略微增加網絡的大小。還有一個例外是Maxout,盡管本身沒有參數,但在同樣輸出通道數下k路Maxout需要的輸入通道數是其它函數的k倍,這意味着神經元數目也需要變為k倍;但如果不考慮維持輸出通道數的情況下,該激活函數又能將參數個數減少為原來的k倍。
歸一化(normalization):
這個是最近才出來的概念,對應的激活函數是SELU,主要思想是使樣本分布自動歸一化到零均值、單位方差的分布,從而穩定訓練。在這之前,這種歸一化的思想也被用於網絡結構的設計,比如Batch Normalization。
print_r('點個贊吧');
var_dump('點個贊吧');
NSLog(@"點個贊吧!")
System.out.println("點個贊吧!");
console.log("點個贊吧!");
print("點個贊吧!");
printf("點個贊吧!\n");
cout << "點個贊吧!" << endl;
Console.WriteLine("點個贊吧!");
fmt.Println("點個贊吧!")
Response.Write("點個贊吧");
alert(’點個贊吧’)