詳解神經網路中的神經元和激活函數
在上一節,我們通過兩個淺顯易懂的例子表明,人工智慧的根本目標就是在不同的數據集中找到他們的邊界,依靠這條邊界線,當有新的數據點到來時,只要判斷這個點與邊界線的相互位置就可以判斷新數據點的歸屬。
上一節我們舉得例子中,數據集可以使用一條直線區分開。但對很多問題而言,單一直線是無法把數據點區分開的,例如亦或運算, 當兩數的值不同時,亦或結果為1,相同時亦或運算結果為0,我們用 oxr 標記亦或運算,那麼輸入是0和1時,有以下幾種情況:
我們把輸入的四種情況繪製到坐標軸上看看:
我們看到,兩個綠色點屬於同一集合,因為綠色點做亦或運算後結果都是1,紅色點屬於統一集合,因為他們做運算後結果都是0,然而面對這種情形,你根本無法用一根直線把兩種集合點區分開來,你必須如上圖所示,用兩根直線才能區分,如果點在兩根直線之間,那麼他們屬於同一集合,如果點處於兩跟直線之外,那麼他們屬於另外一個集合。
所謂神經網路就是由很多個神經元組成的集合,我們可以認為一個神經元用於繪製一段分割線,複雜的數據分布需要很多條形狀各異的線條才能組成合理的分界線,數據分布的情況越複雜,我們就需要越多個神經元來進行運算。
深度學習的神經網路藉助了生物學對腦神經系統的研究成果。一個生物大腦神經元如下所示:
最左邊的部分』dendrite『叫突觸,它用來接收外界輸入的電信號,中間部分axon叫軸突,它把突觸接收的信號進行整合處理,右邊部分terminals叫終端輸出,它把軸突整合後的信號切分成多部分,分別傳送給其他神經元。下圖是腦神經學家從鴿子腦子獲取的神經元圖像:
人的大腦大概有一千億個神經元組成一個龐大的計算網路。蒼蠅大腦只有十萬個神經元,儘管如此,蒼蠅就能夠控制飛行,尋找食物,識別和躲避危險,這些很看似簡單的動作操控就連現在最強大的計算機都無法實現。生物大腦其運算能力遠遜於計算機,為何生物能輕而易舉做到的事情計算機卻做不到呢?大腦的運行機制目前人類還沒有完全搞懂,但有一點可以肯定的是,生物大腦的運算運行存在「模糊性」,而電子計算機不行。
我們看一個神經元是如何工作的。神經元接收的是電信號,然後輸出另一種電信號。如果輸入電信號的強度不夠大,那麼神經元就不會做出任何反應,如果電信號的強度大於某個界限,那麼神經元就會做出反應,向其他神經元傳遞電信號:
想像你把手指深入水中,如果水的溫度不高,你不會感到疼痛,如果水的溫度不斷升高,當溫度超過某個度數時,你會神經反射般的把手指抽出來,然後才感覺到疼痛,這就是輸入神經元的電信號強度超過預定閾值後,神經元做出反應的結果。為了模擬神經元這種根據輸入信號強弱做出反應的行為,在深度學習演算法中,運用了多種函數來模擬這種特性,最常用的分布是步調函數和sigmoid函數,我們先看看步調函數的特性,我們通過以下代碼來繪製步調函數:
上面代碼運行後結果如下:
我們看到,這個函數的特點是,當輸入的x小於1時,函數的輸出一直都是零。當輸入的x大於等於1時,輸出一下子從零躍遷到1,當x輸入處於1到2之間時,輸出一直是1,當x增大到2以上時,輸出一下子躍遷到2,以此類推。
第二種常用的模擬函數就是sigmoid,它的形狀就像字母S,輸入下面代碼繪製sigmoid函數:
上面代碼執行後結果如下:
從函數圖我們看到,當輸入小於0時,函數的輸出增長很緩慢,當輸入大於0時,輸出便極具增長,等到x大到一定程度後,輸出保持在固定水準。sigmoid函數的代數式子如下:
其中的字母e表示歐拉常數,它的值約為2.71828。以後面對更複雜的問題時,我們還得使用更複雜的模擬函數,所有這些模擬神經元對電信號進行反應的函數統稱為激活函數。
一個神經元會同時接收多個電信號,把這些電信號統一起來,用激活函數處理後再輸出新的電信號,如下圖:
神經網路演算法中設計的神經元會同時接收多個輸入參數,它把這些參數加總求和,然後代入用激活函數,產生的結果就是神經元輸出的電信號。如果輸入參數加總的值不大,那麼輸出的信號值就會很小,如果輸入信號中,有某一個值很大其他的都很小,那麼加總後值很大,輸出的信號值就會變大,如果每個輸入參數都不算太大,但加總後結果很大,於是輸出的信號值就會很大,這種情況就使得運算具備一定的模糊性,這樣就跟生物大腦的神經元運轉方式很相像。
神經元不是各自為戰,而是連成一個網路,並對電信號的處理形成一種鏈式反應:
前一個神經元接收輸入信號,處理後會把輸出信號分別傳送給下一層的多個神經元。在神經網路演算法上也會模擬這種特性,在演算法設計中,我們會構造如下的數據結構:
上面有三層節點,每層有三個節點,第一層的節點接收輸入,進行運算後,把輸出結果分別提交給下一層的三個節點,如此類推直到最後一層。現在問題是,這種結構如何像上一節我們舉得例子那樣,根據誤差進行學習調整呢?事實上,在上一層的節點把處理後的電信號傳達到下一層的節點時,輸出信號會分成若干部分分別傳給下一層的不同節點,每一部分都對應一個權值,如下圖:
我們看到,第一層的節點1把輸出信號傳給第二層的節點1時,傳遞路徑上有一個權值W(1,1),也就是節點1輸出的電信號值乘以這個權值W(1,1)後,所得的結果才會提交給第二層的節點1,同理第一層節點1輸出的信號要乘以W(1,2)這個權值後,所得結果才會傳遞給第二層節點2.
這些參數就對應於我們上一節例子中用於調整的參數,整個網路對輸入進行運算後,在最外層產生輸出,輸出會跟結果進行比對,獲取誤差,然後網路再根據誤差反過來調整這些層與層之間的傳遞參數,只不過參數調整的演算法比我們前一節的例子要複雜不少。接下來我們看看一個具體的兩層網路信號傳遞運算過程。
上圖是一個兩層網路,每個網路有兩個節點,假設從第一次開始輸入兩個信號,分別是1,0.5:
第一層神經元直接把輸入加總後分發到第二層,第二層神經元使用的激活函數是sigmoid, 神經元之間的信號權值如下:
就如上一節例子描述的,一開始每層節點間的權值是隨機獲取的。於是第一層神經元處理信號後把輸出傳遞給第二層:
主要的運算髮生在第二層的神經元節點。第二層的神經元要把第一層傳來的信號值加總然後在傳給sigmoid激活函數
從第一層第一個節點傳給第二層第一個節點的信號值是 1.00.9 = 0.9; 第一層第二個節點傳給第二層第一個節點的信號值是 0.50.3 = 0.15。第二層第一個節點把這些信號值加總後得 X = 0.9 + 0.15 = 1.05; 再把這個值傳給sigmoid函數: 1 / (1 + exp(-x));也就是y = 1 / (1 + exp(-1.05)) = 0.7408;
第一層第一個節點傳遞給第二層第二個節點的信號值是 1.00.2 = 0.2; 第一層第二個節點傳給第二層第二個節點的信號值是 0.50.8 = 0.4, 第二層第二個節點把這些信號值加總得 X = 0.2 + 0.4 = 0.6, 再將其傳入激活函數得 y = 1 / (1 + exp(-0.6)) = 0.6457,最後我們得到神經網路的輸出結果為: (0.7408, 0.6457)。
下一節我們將深入研究如何使用張量運算加快神經網路的運算,以及探討如何通過誤差調整網路中節點間的權值。


TAG:Coding迪斯尼 |