1. 程式人生 > >【深度學習】python實現簡單神經網路以及手寫數字識別案例

【深度學習】python實現簡單神經網路以及手寫數字識別案例

前言

\quad \quad 為了能夠解決感知機人工設定權重的工作,即確定合適的、能符合預期的輸入與輸出的權重,神經網路便出現了,神經網路的一個重要的性質是它可以自動地從資料中學習得到合適的權重引數。

神經網路

在這裡插入圖片描述

\quad \quad 如上圖,我們把最左邊的一列稱為輸入層,最右邊的稱為輸出層,中間的稱為中間層(也可稱為隱藏層),一般情況下,我們通常將輸入層、隱藏層、輸出層的總數減去1後的數量來表示神經網路的名稱,上圖即可稱為兩層神經網路。

\quad

\quad 從圖上看,神經網路的形狀與感知機很類似,實際上,就神經元的連線方式與感知機並沒有差別。

感知機

在這裡插入圖片描述

\quad \quad

圖中感知機接收 x 1 x_1 x 2 x_2 兩個輸入訊號,輸出 y y 。用數學表示式可表示為(圖中偏置項沒畫出來):
y = { 0 ( b + w 1 x 1 + w 2 x 2 0 1 ( b + w 1 x 1 + w 2 x 2 > 0 y = \begin{cases} 0 \quad (b+w_1x_1+w_2x_2 \leqslant 0)\\ 1 \quad (b+w_1x_1+w_2x_2 > 0) \end{cases}

b b 稱為偏置,用於控制神經元被啟用的容易程度; w 1 w_1 w 2 w_2 表示各個訊號的權重引數,用於控制各個訊號的重要性。

\quad \quad 進一步,我們可以引入一個新函式 h ( x ) h(x) ,將上面的式子改寫為:

y = h ( b + w 1 x 1 + w 2 x 2 ) h ( x ) = { 0 ( x 0 ) 1 ( x > 0 ) y = h(b+w_1x_1+w_2x_2 ) \\ h(x) = \begin{cases} 0 \quad (x \leqslant 0) \\ 1 \quad (x > 0) \end{cases}

輸入訊號的總和會被函式 h ( x ) h(x) 轉換,轉換後的值就是輸出 y y

啟用函式

\quad \quad 在前面,我們提到函式 h ( x ) h(x) 會將輸入訊號的總和轉換為輸出訊號,這種函式就叫啟用函式

我們先將式子改寫為:
a = b + w 1 x 1 + w 2 x 2 a = b+w_1x_1+w_2x_2
y = h ( a ) y = h(a)

畫出如下圖:
在這裡插入圖片描述

上面的啟用函式 h ( ) h() 是以閥值為界,一旦輸入超過閥值,就切換輸出。這樣的啟用函式為“階躍函式”,因此,可以說感知機中使用熱階躍函式作為啟用函式,那麼感知機使用其他啟用函式呢?實際上,如果將啟用函式從階躍函式換成其他的,就可以進入神經網路的世界了。

  • sigmoid函式

數學表示式為:
h ( x ) = 1 1 + e x h(x) = \frac{1}{1+e^{-x}}

python實現:

import numpy as np
import matplotlib.pylab as plt

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

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
# 畫圖
plt.plot(x,y)
plt.ylim(-0.1, 1.1) # 指定y軸的範圍
plt.show()

在這裡插入圖片描述

  • 階躍函式

數學表示式:
h ( x ) = { 0 ( x 0 ) 1 ( x > 0 ) h(x) = \begin{cases} 0 \quad (x \leqslant 0) \\ 1 \quad (x > 0) \end{cases}

python實現:

# 方法一
def step_function1(x):
	if x > 0:
		return 1
	else:
		return 0
# 方法二		
def step_function2(x):
    return np.array(x>0, dtype=np.int)

x = np.arange(-5.0, 5.0, 0.1) # 在-0.5到0.5的範圍內,以0.1為單位,生成NumPy陣列([-5.0,-4.9,...,4.9])
y = step_function2(x)

plt.plot(x,y)
plt.ylim(-0.1, 1.1) # 指定y軸的範圍
plt.show()

在這裡插入圖片描述

  • 階躍函式與sigmoid函式的比較
  1. “平滑性”不同,sigmoid函式是一條平滑的曲線,而階躍函式在0處有突變,輸出發生急劇性變化,sigmoid函式的平滑性對神經網路的學習具有重要意義;
  2. 返回值的不同,階躍函式只能返回0和1,sigmoid函式可以返回0到1的任意數,這和平滑性有關,也就是說,感知機中神經元之間流動的是0和1的二元訊號,而神經網路中流動的是連續的實值訊號;
  3. 二者也有共同性質,輸入較小時,輸出接近0(或為0),隨著輸入增大,輸出向1靠近(或變成1),也就是說,當輸入訊號為重要資訊時,兩者都會輸出較大的值,當輸入訊號不重要的時,兩者都會輸出較小的值;
  4. 二者輸出值都在0到1之前
  • ReLU函式

數學表示式:
h ( x ) = { x ( x > 0 ) 0 ( x 0 ) h(x) = \begin{cases} x \quad (x > 0) \\ 0 \quad (x \leqslant 0) \end{cases}

python實現:

def relu(x):
    return np.maximum(0,x)

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)

plt.plot(x,y)
plt.ylim(-0.1, 5) # 指定y軸的範圍
plt.show()

在這裡插入圖片描述