TensorFlow2.0(7):激活函數


 

注:本系列所有博客將持續更新並發布在github上,您可以通過github下載本系列所有文章筆記文件。

 

1 什么是激活函數

 

激活函數是深度學習,亦或者說人工神經網絡中一個十分重要的組成部分,它可以對神經元的接收信息進行非線性變換,將變換后的信息輸出到下一層神經元。激活函數作用方式如下公式所示:

 
$$y = Activation(\sum\limits_i^N {{w_i} \cdot {x_i} + b} )$$
 

其中,$Activation()$就是激活函數。

 

為什么要使用激活函數呢?當我們不用激活函數時,網絡中各層只會根據權重$w$和偏差$b$只會進行線性變換,就算有多層網絡,也只是相當於多個線性方程的組合,依然只是相當於一個線性回歸模型,解決復雜問題的能力有限。我們希望我們的神經網絡能夠處理復雜任務,如語言翻譯和圖像分類等,線性變換永遠無法執行這樣的任務。激活函數得加入能對輸入進行非線性變換,使其能夠學習和執行更復雜的任務。

另外,激活函數使反向傳播成為可能,因為激活函數的誤差梯度可以用來調整權重和偏差。如果沒有可微的非線性函數,這就不可能實現。

總之,激活函數的作用是能夠給神經網絡加入一些非線性因素,使得神經網絡可以更好地解決較為復雜的問題。

 

2 常用激活函數

2.1 sigmoid函數

 

sigmoid函數可以將整個實數范圍的的任意值映射到[0,1]范圍內,當當輸入值較大時,sigmoid將返回一個接近於1的值,而當輸入值較小時,返回值將接近於0。sigmoid函數數學公式和函數圖像如下所示:

 
$$f(x) = \frac{1}{{1 + {e^{ - x}}}}$$
 

image

 

感受一下TensorFlow中的sigmoid函數:

In [1]:
import tensorflow as tf
x = tf.linspace(-5., 5.,6)
x
Out[1]:
<tf.Tensor: id=3, shape=(6,), dtype=float32, numpy=array([-5., -3., -1.,  1.,  3.,  5.], dtype=float32)>
 

有兩種方式可以調用sigmoid函數:

In [2]:
tf.keras.activations.sigmoid(x)
Out[2]:
<tf.Tensor: id=4, shape=(6,), dtype=float32, numpy=
array([0.00669285, 0.04742587, 0.26894143, 0.7310586 , 0.95257413,
       0.9933072 ], dtype=float32)>
In [3]:
tf.sigmoid(x)
Out[3]:
<tf.Tensor: id=5, shape=(6,), dtype=float32, numpy=
array([0.00669285, 0.04742587, 0.26894143, 0.7310586 , 0.95257413,
       0.9933072 ], dtype=float32)>
 

看,$x$中所有值都映射到了[0,1]范圍內。

 

sigmoid優缺點總結:

  • 優點:輸出的映射區間(0,1)內單調連續,非常適合用作輸出層,並且比較容易求導。

  • 缺點:具有軟飽和性,即當輸入x趨向於無窮的時候,它的導數會趨於0,導致很容易產生梯度消失。

 

2.2 relu函數

 

Relu(Rectified Linear Units修正線性單元),是目前被使用最為頻繁得激活函數,relu函數在x<0時,輸出始終為0。由於x>0時,relu函數的導數為1,即保持輸出為x,所以relu函數能夠在x>0時保持梯度不斷衰減,從而緩解梯度消失的問題,還能加快收斂速度,還能是神經網絡具有稀疏性表達能力,這也是relu激活函數能夠被使用在深層神經網絡中的原因。由於當x<0時,relu函數的導數為0,導致對應的權重無法更新,這樣的神經元被稱為"神經元死亡"。

relu函數公式和圖像如下:

 
$$f(x) = \max (0,x)$$
 

image

 

在TensorFlow中,relu函數的參數情況比sigmoid復雜,我們先來看一下:

 

tf.keras.activations.relu( x, alpha=0.0, max_value=None, threshold=0 )

  • x:輸入的變量
  • alpha:上圖中左半邊部分圖像的斜率,也就是x值為負數(准確說應該是小於threshold)部分的斜率,默認為0
  • max_value:最大值,當x大於max_value時,輸出值為max_value
  • threshold:起始點,也就是上面圖中拐點處x軸的值
In [4]:
x = tf.linspace(-5., 5.,6)
x
Out[4]:
<tf.Tensor: id=9, shape=(6,), dtype=float32, numpy=array([-5., -3., -1.,  1.,  3.,  5.], dtype=float32)>
In [5]:
tf.keras.activations.relu(x)
Out[5]:
<tf.Tensor: id=10, shape=(6,), dtype=float32, numpy=array([0., 0., 0., 1., 3., 5.], dtype=float32)>
In [6]:
tf.keras.activations.relu(x,alpha=2.)
Out[6]:
<tf.Tensor: id=11, shape=(6,), dtype=float32, numpy=array([-10.,  -6.,  -2.,   1.,   3.,   5.], dtype=float32)>
In [7]:
tf.keras.activations.relu(x,max_value=2.)  # 大於2部分都將輸出為2.
Out[7]:
<tf.Tensor: id=16, shape=(6,), dtype=float32, numpy=array([0., 0., 0., 1., 2., 2.], dtype=float32)>
In [8]:
tf.keras.activations.relu(x,alpha=2., threshold=3.5)  # 小於3.5的值按照alpha * (x - threshold)計算
Out[8]:
<tf.Tensor: id=27, shape=(6,), dtype=float32, numpy=array([-17., -13.,  -9.,  -5.,  -1.,   5.], dtype=float32)>
 

2.3 softmax函數

 

softmax函數是sigmoid函數的進化,在處理分類問題是很方便,它可以將所有輸出映射到成概率的形式,即值在[0,1]范圍且總和為1。例如輸出變量為[1.5,4.4,2.0],經過softmax函數激活后,輸出為[0.04802413, 0.87279755, 0.0791784 ],分別對應屬於1、2、3類的概率。softmax函數數學公式如下:

 
$$f({x_i}) = \frac{{{e^{{x_i}}}}}{{\sum\limits_i {{e^{{x_i}}}} }}$$
In [9]:
tf.nn.softmax(tf.constant([[1.5,4.4,2.0]]))
Out[9]:
<tf.Tensor: id=29, shape=(1, 3), dtype=float32, numpy=array([[0.04802413, 0.87279755, 0.0791784 ]], dtype=float32)>
In [10]:
tf.keras.activations.softmax(tf.constant([[1.5,4.4,2.0]]))
Out[10]:
<tf.Tensor: id=31, shape=(1, 3), dtype=float32, numpy=array([[0.04802413, 0.87279755, 0.0791784 ]], dtype=float32)>
In [11]:
x = tf.random.uniform([1,5],minval=-2,maxval=2)
x
Out[11]:
<tf.Tensor: id=38, shape=(1, 5), dtype=float32, numpy=
array([[ 1.9715171 ,  0.49954653, -0.37836075,  1.6178164 ,  0.80509186]],
      dtype=float32)>
In [12]:
tf.keras.activations.softmax(x)
Out[12]:
<tf.Tensor: id=39, shape=(1, 5), dtype=float32, numpy=
array([[0.42763966, 0.09813169, 0.04078862, 0.30023944, 0.13320053]],
      dtype=float32)>
 

2.4 tanh函數

 

tanh函數無論是功能還是函數圖像上斗魚sigmoid函數十分相似,所以兩者的優缺點也一樣,區別在於tanh函數將值映射到[-1,1]范圍,其數學公式和函數圖像如下:

 
$$f(x) = \frac{{\sinh x}}{{\cosh x}} = \frac{{1 - {e^{ - 2x}}}}{{1 + {e^{ - 2x}}}}$$
 

image

In [13]:
x = tf.linspace(-5., 5.,6)
x
Out[13]:
<tf.Tensor: id=43, shape=(6,), dtype=float32, numpy=array([-5., -3., -1.,  1.,  3.,  5.], dtype=float32)>
In [14]:
tf.keras.activations.tanh(x)
Out[14]:
<tf.Tensor: id=44, shape=(6,), dtype=float32, numpy=
array([-0.99990916, -0.9950547 , -0.7615942 ,  0.7615942 ,  0.9950547 ,
        0.99990916], dtype=float32)>
 

3 總結

 

神經網絡中,隱藏層之間的輸出大多需要通過激活函數來映射(當然,也可以不用,沒有使用激活函數的層一般稱為logits層),在構建模型是,需要根據實際數據情況選擇激活函數。TensorFlow中的激活函數可不止這4個,本文只是介紹最常用的4個,當然,其他激活函數大多是這幾個激活函數的變種。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM