神經網絡術語大百科:優化函數、激活函數、損失函數、正則方法的簡介

neuralnetworks

簡述關於神經網絡的各種優化函數(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)、各種激活函數(Sigmoid,Tanh、Hard Sigmoid、Softplus、ReLU、ElU、PReLU、RReLU)、各種損失函數以及正則方法的簡述,並附帶代碼實現例子。

優化函數

先上兩張圖

激活函數

沒有激活函數,神經元就只是一個線性函數,那麼無論多少層的神經元疊加是沒有意義的。而主流激活函數也隨著神經網絡、深度學習的發展迭代進化了許多次代。

Sigmoid


Sigmoid是S形狀的意思,又因為它是邏輯回歸的激活函數又叫logistic函數,函數式為$

  • 值域位於0-1,那麼對於邏輯回歸,這是對於二分類的一個很自然的表達,也就是概率
  • 處處連續可導

不過呢,我們觀察它的形狀,可以得出,Sigmoid函數在兩端(靠近0和1的部分)梯度很小,這也意味著,如果神經元的輸出落到了這個地方,那麼它幾乎沒什麼梯度可以傳到後面,而隨著神經網絡的層層削弱,後面的層(靠近輸入的層)沒有多少梯度能傳過來,幾乎就“學不到什麼”了。這叫做梯度消失問題,一度是阻礙神經網絡往更深的層進化的主要困難,導致深度學習專家們絞盡腦汁想了許多方法來對抗這個問題,比如“Xavier and He Initialization”,比如我們要把weight隨機初始化為如下的範圍,
Screen Shot 2017-12-16 at 17.03.18

sigmoid的另一個問題是它不是0均值的,Sigmoid函數的輸出值恆大於0,這會導致模型訓練的收斂速度變慢。舉例來講,對,如果所有均為正數或負數,那麼其對的導數總是正數或負數,這會導致如下圖紅色箭頭所示的階梯式更新,這顯然並非一個好的優化路徑。深度學習往往需要大量時間來處理大量數據,模型的收斂速度是尤為重要的。所以,總體上來講,訓練深度學習網絡盡量使用zero-centered數據(可以經過數據預處理實現) 和zero-centered輸出。

如今,sigmoid函數應用最廣泛的在於其變種softmax在多元分類中,比如手寫數字識別,經過卷積神經網絡的處理,最後我們需要網絡輸出每個預測的概率值,最後預測為某一個數字,這裡就需要用到softmax,

以下是softmax的Keras代碼,注意其中一個trick,

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

def
"""Softmax activation function.

# Arguments
x : Tensor.
axis: Integer, axis along which the softmax normalization is applied.

# Returns
Tensor, output of softmax transformation.

# Raises
ValueError: In case `dim(x) == 1`.
"""
ndim = K.ndim(x)
if
return
elif
e = K.exp(x - K.
s = K.
return
else
raise

tanh

tanh 是sigmoid的變形: $tanh(x)=2sigmoid(2x)-1$,與sigmoid 不同的是,tanh 是0均值的。因此,實際應用中,tanh 會比sigmoid 更好一些,

ReLU家族

然而標準ReLU不是完美的,比如因為ReLU在小於0的坐標梯度都是0,那麼會造成“死亡”的神經元的問題:一旦神經元的輸入與權重之乘積是負的,那麼經過ReLU的激活,輸出就是0,而ReLU的0梯度讓“死亡”的神經元無法“復活”:沒辦法回到輸出不是0的狀態,這樣就出現了許多在ReLU的變種,一般都是對標準ReLU坐標軸左邊的部分做文章,比如其公式就是$LeakyReLU_ α (z) = max(alpha z,z)$。如圖,

這篇文章另外,對於parametric leaky ReLU (PReLU)(其中$alpha$作為網絡的一個參數,被反向傳播學習出來,之前的$alpha$都是超參數,不能學只能調節),這種變種對於大數據集不錯,但是數據量過小就有過擬合的風險。以下是Keras裡面relu的代碼,

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 def
"""Rectified linear unit.

With default values, it returns element-wise `max(x, 0)`.

# Arguments
x: A tensor or variable.
alpha: A scalar, slope of negative section (default=`0.`).
max_value: Saturation threshold.

# Returns
A tensor.
"""
if
negative_part = tf.nn.relu(-x)
x = tf.nn.relu(x)
if
max_value = _to_tensor(max_value, x.dtype.base_dtype)
zero = _to_tensor(
x = tf.clip_by_value(x, zero, max_value)
if
alpha = _to_tensor(alpha, x.dtype.base_dtype)
x -= alpha * negative_part
return

另外,在這篇文章裡面
$$
ELU_{alpha}(z) = alpha (exp(z)-1) if z lt 0 ; z if z gt 0;
$$

與標準ReLU最大的區別在於它處處連續可導,這使得梯度下降得到加速,收斂得到了加速,而使用了指數函數使得其測試階段的計算代價更高。 Keras裡elu的實現,

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 def
"""Exponential linear unit.

# Arguments
x: A tenor or variable to compute the activation function for.
alpha: A scalar, slope of positive section.

# Returns
A tensor.
"""
res = tf.nn.elu(x)
if
return
else
return

激活函數的選擇

一般來說,我們的選擇順序可以理解為:
ELU > leaky ReLU (以及其變種) > ReLU > tanh > logistic。但是,

  • 如果我們更顧慮模型運行速度,那麼leaky ReLU可能比ELU更好;
  • 如果我們不想調節超參數,那麼用默認的$alpha$就行,ReLU和ELU的分別是0.01和1;
  • 如果算力足夠可以用來調參,那麼如果網絡過擬合我們會選擇RReLU,如果訓練集數據足夠多,那可以用PReLU。

Leave a Comment

Your email address will not be published.