用神經網絡解決分類問題
神經網絡也稱為人工神經網絡(Artificial Neural Network, ANN)。
神經網絡的4個概念:
- 神經元
- 興奮傳遞
- 激活函數
- 反向傳播機制
用圓圈表示神經元,箭頭表示資料流向,一個神經元如圖所示:
上圖表示的是從一個方向擷取資料,經過神經元處理後,将結果資料向三個方向進行輸出。
神經元的内部結構
神經元從數學的角度來說,我們可以認為代表了一個函數。
但是神經元函數通常由兩個部分組成:
- 線性函數
- 非線性函數,稱為激活函數(Activation Function)
神經元内部結構圖

多個神經元之間互相連接配接,就構成了人工神經網絡:
激活函數用于産生二進制輸出,描述如下:
if (滿足激活條件):
return 1
else:
return 0
這也就是神經網絡可以用于分類的原因。
神經網絡的傳遞機制
神經元的作用就兩個:
- 感受刺激
- 傳遞興奮
由于激活函數的存在,神經元就能夠根據需要傳遞1或者0,最終利用“興奮傳遞”機制完成判斷:
這個過程稱為正向傳播。
什麼樣的函數能夠成為激活函數?
從原理上來說,激活函數的輸出不是“0”就是“1”,這是非常典型的階躍函數。Sgn函數就是最知名的一個階躍函數,但是由于它不可導,這對于優化算法來說非常緻命。
而Logistic函數即可以模拟“階躍”的效果,又可導,是以Logistic函數是一個非常好的激活函數的選擇,在神經網絡中,習慣将其稱為Sigmoid函數。Sigmoid函數在0點附近,特别是在\((-1,1)\)區間非常平緩,變化率非常小,在使用梯度下降等優化方法時,很容易導緻梯度彌散甚至梯度消失。
是以,業界開始使用Tanh函數來作為激活函數,Tanh同樣滿足可導和階躍兩大要求。同時,相比Sigmoid函數,Tanh函數梯度更大,使用梯度下降等優化方法時收斂更快,所需要的學習時間更短。雖然梯度比Sigmoid函數大,但是越接近0點,變化率越小的問題依然存在。為了解決這個問題,又開發出了ReLu函數來作為激活函數,這也是目前公認效果最好的激活函數。
Logistic回歸可以看成隻有一層的神經網絡。
在神經網絡中,層(Layer)是非常重要的概念,深度學習中所謂的“深度”就是神經網絡的層數很多、很深的意思。
一個三層的神經網絡構成如下:
- 輸入層:第一層,直接接受輸入資料的神經元;
- 隐藏層:中間所有層,既不直接接受輸入,也不直接産生輸出,是以統稱為隐藏層;
- 輸出層:最後一層,産生最終資料并輸出到外部。
這就是最簡單的神經網絡,隻有一層隐藏層。
一般來說,神經元的個數和層數越多,模型的學習能力就越強。
神經網絡分類的算法原理
基本思路
為了訓練,神經網絡引入了正向傳播和反向傳播機制。正向傳播扮演的是傳播輸入的功能,輸入層首先接收輸入,通過激勵函數産生輸出,而輸出則作為隐藏層的輸入,就這樣一步一步的傳遞下去,直到輸出層産生輸出。
而反向傳播的意義是為了調節每個神經元的權重,首先通過輸出層擷取偏差,調整權值,然後一層一層地反向傳播,一直到輸出層,整個神經網絡就完成了一輪權值更新。
數學解析
1.激活函數
Tanh函數(雙曲正切函數)的數學表達式如下:
\[tanh(x) = \frac{\sinh(x)}{\cosh(x)} = \frac{e^x-e^{-x}}{e^x+e^{-x}}
\]
ReLu函數(線性整流函數,Rectified Linear Unit)的數學表達式如下:
\[ReLu(x) = \max(0,x)
2.反向傳播
正向傳播實際上就是簡單的代數指派運算過程,比較難的是反向傳播。
神經網絡算法的反向傳播的獨特之處在于方向。神經網絡中一個神經元的輸入可能源于多個神經元的輸出,比如A、B、C都給D貢獻了輸入:
現在知道了D的損失偏差,怎麼計算A、B、C分别“貢獻”了多少偏差呢?這就是反向傳播要解決的核心問題。
方法就是用偏導。
具體步驟
神經網絡分類算法是一種有監督的分類算法。
神經網絡分類算法資訊表
使用神經網絡分類算法需要五步:
- 初始化所有神經元激勵函數的權值;
- 輸入層接收輸入,通過正向傳播産生輸出;
- 根據輸出的預測值,結合實際值計算偏差;
- 輸出層接收偏差,通過反向傳播機制讓所有神經元更新權值;
- 重複2~4步訓練過程,直到偏差最小。
在Python中使用神經網絡分類算法
在sklearn中,基于神經網絡的算法模型都在
neural_network
包中,神經網絡算法在sklearn中被稱為多層感覺機(Multi-layer Perceptron, MLP)。
本章介紹的神經網絡分類算法可通過
MLPClassifier
類調用,用法如下:
# 從sklearn中導入神經網絡模型中的神經網絡分類算法
from sklearn.neural_network import MLPClassifier
# 載入鸢尾花資料集
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
# 訓練模型
clf = MLPClassifier().fit(X, y)
# 使用模型進行分類預測
clf.predict(X)
預測結果如下:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
使用預設的性能評估器評分:
clf.score(X, y)
性能得分如下:
0.98
神經網絡分類算法的使用場景
神經網絡分類算法的特點