(這裡不支援letex,排版很差)
多層神經網路
前面說到的感知器是一種最基礎的神經網路,他只有輸入層和輸出層,感知器只能處理線性可分問題,而對於非線性問題就需要多層神經網路。一般如下圖所示,有多個層,比如左邊的包含輸入層、隱層和輸出層,而右邊的則包含了兩個隱層。每層的神經元與下一神經元全互連,同層之間的神經元不會相連,輸入層用於接收輸入,經過隱層加工後再到輸出層加工並輸出。
如何訓練多層網路
對於多層網路我們常用誤差逆傳播演算法來訓練,而我們最常見的BP神經網路指的是使用誤差逆傳播來訓練的多層前饋神經網路。除此之外其他型別的神經網路也可能會用誤差逆傳播演算法來訓練。
總的來說,誤差逆傳播是使用梯度下降法,通過反向傳播不斷調整神經網路中各個權重從而使輸出層的誤差平方和最小。
BP神經網路
BP神經網路好的地方就是我們完全不必事先考慮怎麼用數學方程來描述輸入和輸出之間的關係,轉而考慮的是設計一個N層神經網路,而要多少層、每層要多少個節點就可以我們根據經驗來設計,可通過不同的網路模型來看哪個模型能更好地擬合。
BP神經網路其實很直觀很好理解,整個過程如下。
下面是一個三層(不算輸入層)神經網路,兩個輸入經過幾層網路後得到一個輸出。
這麼一來就得到第一層隱層的所有訊號輸出,接下去往下一層傳播,這時對於第二層隱層來說,第一層隱層的所有節點的輸出就是它的輸入,這時輸入節點變為3個,分別為,對應權重為,則
於是又得到第二層隱層的兩個輸出,繼續往下一層(輸出層)傳播,對於輸出層,第二層隱層的兩個節點的輸出即為它的輸入,此時輸入節點為2個,分別為,假設權重分別為,則
誤差逆傳播
往下看看誤差逆傳播是怎麼一回事。通過上面的過程我們獲取到了一個最終的輸出,而這個輸出與目標值可能存在誤差,表示為。則對於樣本的目標函式為
使用梯度下降法更新每一個權重,即。解決了上面的式子就可以完成迭代優化了。
如下圖,對於每個節點輸入有,
根據鏈式求導法則有,
於是只要求得即知道梯度權重更新。
對於輸出層,其中,則有
,則
有了上面的更新公式後就可以對輸出層進行迭代更新了。
對於隱層,設節點j的所有輸出為A,則下一層網路有多少個節點,則它的集合大小為多少,比如上圖中,對於節點1,它的輸出集合A大小為2,分別輸出到節點4和節點5。隱層節點的輸入通過影響所有輸出A再往下影響,再設為下一層的輸入,則是的函式,且是的函式。對於節點輸入,由於其輸出A包含多個元素,有多個影響分量,所以,
正則化
為了抑制過擬合,對於整個訓練樣本集目標函式進行正則化。
全域性最小
神經網路的訓練可能陷入區域性最小中,有時需要一些策略跳出區域性最小,以便有一定機率得到全域性最小。
- 模擬退火
- 隨機梯度下降
- 多個不同的初始點
實現3-5-1網路
import numpy as np
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
X = np.array([[0,0,1],
[0,1,1],
[1,0,1],
[1,1,1]])
y = np.array([[0],
[1],
[1],
[0]])
np.random.seed(1)
syn0 = 2*np.random.random((3,5)) - 1
syn1 = 2*np.random.random((5,1)) - 1
for j in range(60000):
l0 = X
l1 = nonlin(np.dot(l0,syn0))
l2 = nonlin(np.dot(l1,syn1))
l2_error = y - l2
if (j% 10000) == 0:
print("Error:" + str(np.mean(np.abs(l2_error))))
l2_delta = l2_error*nonlin(l2,deriv=True)
l1_error = l2_delta.dot(syn1.T)
l1_delta = l1_error * nonlin(l1,deriv=True)
g = 0.01
syn1 += g * l1.T.dot(l2_delta)
syn0 += g * l0.T.dot(l1_delta)
print(l2)複製程式碼
====廣告時間,可直接跳過====
鄙人的新書《Tomcat核心設計剖析》已經在京東預售了,有需要的朋友可以到 item.jd.com/12185360.ht… 進行預定。感謝各位朋友。
=========================
歡迎關注: