神經網絡第一篇:激活函數是連接感知機和神經網絡的橋樑

前面發佈的文章介紹了感知機,瞭解了感知機可以通過疊加層表示複雜的函數。遺憾的是,設定合適的、能符合預期的輸入與輸出的權重,是由人工進行的。從本章開始,將進入神經網絡的學習,首先介紹激活函數,因爲它是連接感知機和神經網絡的橋樑。如果讀者認知閱讀了本專題知識,相信你必有收穫。

感知機數學表達式的簡化

前面我們介紹了用感知機接收兩個輸入信號的數學表示如下:

                                         

現在將上式改成更加簡潔的形式,我們不妨想一下,上面的表達式(或者說是函數)輸出y只有兩種值0和1。因此,我們引入一個新函數將上式改寫成下式:

                                        

式(2)中,輸入信號的總和會被函數h(x)轉換,轉換後的值就是輸出y。而式(3)所表示的h(x)在輸入超過0時返回1,否則返回0。不難理解,式(1)和式(2)、(3)做的是一件事情。其實這和數學中的複合函數的意思一樣(將b+w1x1+w2x2整體作爲變量x,變量名可隨便取)。

激活函數登場

 我們剛引入的h(x)函數能將輸入信號的總和轉換爲輸出信號(只有0和1),這種函數就是激活函數。正如“激活”二字,激活函數就是決定如何來激活輸入信號的總和。讀者意識可能有點模糊,我們對上面的式子再分析一下,將式(2)分爲兩個階段,如下式,第一階段是計算輸入信號的加權和,第二階段則用激活函數來轉換這一加權和。

                                      

式(4)計算輸入信號和偏置b的總和,記爲a,接着用h()函數將a轉換爲輸出y。這裏我們用下圖來形象地表示式(4)和式(5)。

                                     

    0表示神經元,這裏我們新增了一個輸入信號爲常數1的神經元(灰色),其權重爲b,主要是把偏置b(控制神經元被激活的容易程度)添加至感知機中。把上圖和上面的公式結合起來分析,節點a接收了輸入信號的加權和,接着節點a被激活函數h()轉換爲節點y輸出。注意節點和神經元是一樣的意思。

試想什麼樣的函數的輸出只有0和1兩種值,毫無疑問,階躍函數(0處突變爲1)的輸出就是這樣的。這裏科普一下,一般而言,單層感知機也稱爲樸素感知機,即使用了階躍函數作爲激活函數的單層網絡。多層感知機指神經網絡,即使用了sigmoid函數等平滑函數作爲激活函數的多層網絡。

式(3)表明,輸入一旦超過閥值,激活函數就切換輸出,因此在感知機中的激活函數是“階躍函數”。我們不難發問,如果感知機使用其他函數作爲激活函數,結果會怎麼樣呢?答案是使用其他激活函數,那我們就進入了神經網絡的世界了。下面我們詳細介紹在神經網絡中常用的幾種激活函數。

階躍函數

    如式(3),輸入大於0,輸出爲1,否則輸出爲0。Python實現如下:

import numpy as np

import matplotlib.pylab as plt

"""numpy輕易實現"""

def step_function(x):

    return np.array(x>0,dtype=np.int) #true爲1,false爲0

"""繪圖"""

x=np.arange(-3.0,3.0,0.1)

y=step_function(x)

plt.plot(x,y)

plt.ylim(-0.1,1.1)

plt.show()


 

sigmoid函數

在神經網絡中,sigmoid函數常作爲激活函數,其表達式如下:

                                      

式(6)中exp(-x)表示e-x次方的意思。實際上,感知機和神經網絡的主要區別就在於激活函數的不同。Sigmoid函數作爲激活函數,對信號進行轉換,轉換後的信號被傳送給下一個神經元。Python實現如下:

"""sigmoid函數,除了函數不一樣,繪圖代碼同上"""

def sigmoid(x):

    return 1/(1+np.exp(-x))  #numpy的廣播功能

 

                                     

 

比較

繪圖代碼如下:

# coding: utf-8
#階躍函數和sigmoid函數比較
import numpy as np
import matplotlib.pylab as plt


def sigmoid(x):
    return 1 / (1 + np.exp(-x))    


def step_function(x):
    return np.array(x > 0, dtype=np.int)

x = np.arange(-5.0, 5.0, 0.1)
y1 = sigmoid(x)
y2 = step_function(x)

plt.plot(x, y1)
plt.plot(x, y2, 'k--')
plt.ylim(-0.1, 1.1) #指定圖中繪製的y軸的範圍
plt.show()

                                              

不同點:

    (1)sigmoid函數是一條平滑的曲線,即輸出隨輸入發生連續的變化,階躍函數以0爲界,發生急劇性的變化。sigmoid函數的平滑性對神經網絡的學習極有幫助。

    (2)階躍函數只能輸出0或1(二元信號),而sigmoid函數可輸出連續的實數信號。

相同點:

    (1)形狀相似,輸入小時,輸出接近0;輸入增大時,輸出向1靠近。也就是說,當輸入信號爲重要信息時,階躍函數和sigmoid函數都會輸出較大的值;當輸入信號爲不重要的信息時,兩者都輸出較小的值。

    (2)輸出信號值均在0~1之間。

    (3)兩者都是非線性函數。階躍函數是一條折線,sigmoid函數是一條曲線。實際上,神經網絡的激活函數必須使用非線性函數,否則加深層的意義就沒有了。對於線性函數而言,不管如何加深層,總存在與之等效的無隱藏層的神經網絡。舉個例子,激活函數h(x)=cx,把y(x)=h(h(x))的運算對應2層神經網絡,顯然y(x)=c·c·x=c2·x=ax(a= c2)。所以爲了利用多層神經網絡的優勢,激活函數必須使用非線性函數。

Relu函數

    Sigmoid函數的使用歷史比較久,現在主要流行ReLU(Rectified Linear Unit)函數,如下:

                                      

    式(7)表明,輸入大於0,則直接輸出該值;輸入小於等於0時,輸出0。Python實現也很簡單,代碼如下:

# 只給出函數,繪圖代碼同上

def relu(x):

    return np.maximum(0, x) #小於0的爲0,大於0的爲其本身

 

 

                              

本章剩餘部分的內容一直採用sigmoid函數作爲激活函數,在靠後的知識點中,才使用ReLU函數。

今天的內容就講到這裏了,希望讀者好好回顧一下激活函數的產生及特點。下一篇知識點,將介紹使用numpy數組實現神經網絡。歡迎讀者訂閱我的微信公衆號“Python生態智聯”,充分利用好零碎時間學AI

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章