机器学习入门(05)— 使用 NumPy 实现 3 层简单神经网络
我們以圖 3-15 的3 層神經(jīng)網(wǎng)絡(luò)為對(duì)象,實(shí)現(xiàn)從輸入到輸出的(前向)處理。在代碼實(shí)現(xiàn)方面,使用上一節(jié)介紹的 NumPy 多維數(shù)組。
1. 符號(hào)定義
2. 各層之間信號(hào)傳遞
從輸入層到第 1 層的 第1 個(gè)神經(jīng)元的信號(hào)傳遞過(guò)程,如圖 3-17 所示。
圖 3-17 中增加了表示偏置的神經(jīng)元 “1”。請(qǐng)注意,偏置的右下角的索引號(hào)只有一個(gè)。這是因?yàn)榍耙粚拥钠蒙窠?jīng)元(神經(jīng)元“1”)只有一個(gè)。
用代碼實(shí)現(xiàn)上述過(guò)程:
In [1]: import numpy as npIn [2]: X = np.array([1.0, 0.5])In [3]: W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])In [5]: B1 = np.array([0.1, 0.2, 0.3])In [6]: A1 = np.dot(X, W1) + B1In [7]: A1
Out[7]: array([0.3, 0.7, 1.1])In [8]:
我們觀察第1 層中激活函數(shù)的計(jì)算過(guò)程。如果把這個(gè)計(jì)算過(guò)程用圖來(lái)表示的話,則如圖 3-18 所示。
如圖3-18 所示,隱藏層的加權(quán)和(加權(quán)信號(hào)和偏置的總和)用 a 表示,被激活函數(shù)轉(zhuǎn)換后的信號(hào)用 z 表示。此外,圖中 h() 表示激活函數(shù),這里我們使用的是sigmoid 函數(shù)。代碼如下所示。
In [8]: def sigmoid(x):...: return 1/(1+np.exp(-x))...: In [12]: Z1 = sigmoid(A1)In [13]: Z1
Out[13]: array([0.57444252, 0.66818777, 0.75026011])
下面,我們來(lái)實(shí)現(xiàn)第 1 層到第 2 層的信號(hào)傳遞(圖3-19)
In [14]: W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])In [15]: B2 = np.array([0.1, 0.2])In [16]: A2 = np.dot(Z1, W2) + B2 In [17]: Z2 = sigmoid(A2)In [18]: Z2
Out[18]: array([0.62624937, 0.7710107 ])In [19]:
最后是第 2 層到輸出層的信號(hào)傳遞(圖 3-20)。輸出層的實(shí)現(xiàn)也和之前的實(shí)現(xiàn)基本相同。不過(guò),最后的激活函數(shù)和之前的隱藏層有所不同。
In [18]: def identity_function(x):...: return x
In [19]:
In [20]: W3 = np.array([[0.1, 0.3], [0.2, 0.4]])In [21]: B3 = np.array([0.1, 0.2])In [22]: Z3 = np.dot(Z2, W3) + B3In [23]: Z3
Out[23]: array([0.31682708, 0.69627909])In [24]: Y = identify_function(Z3)In [25]: Y
Out[25]: array([0.31682708, 0.69627909])In [26]:
這里我們定義了 identity_function() 函數(shù)(也稱(chēng)為“恒等函數(shù)”),并將其作為輸出層的激活函數(shù)。恒等函數(shù)會(huì)將輸入按原樣輸出,因此,這個(gè)例子中沒(méi)有必要特意定義identity_function() 。這里這樣實(shí)現(xiàn)只是為了和之前的流程保持統(tǒng)一。
另外,圖 3-20 中,輸出層的激活函數(shù)用 σ() 表示,不同于隱藏層的激活函數(shù) h() (σ 讀作 sigma )。
輸出層所用的激活函數(shù),要根據(jù)求解問(wèn)題的性質(zhì)決定。一般地,
- 回歸問(wèn)題可以使用恒等函數(shù);
- 二元分類(lèi)問(wèn)題可以使用
sigmoid函數(shù); - 多元分類(lèi)問(wèn)題可以使用
softmax函數(shù);
3. 代碼實(shí)現(xiàn)總結(jié)
import numpy as npnetwork = {}def sigmoid(x):return 1/(1+np.exp(-x))def identity_function(x):return xdef init_work():network["W1"] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])network["b1"] = np.array([0.1, 0.2, 0.3])network["W2"] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])network["b2"] = np.array([0.1, 0.2])network["W3"] = np.array([[0.1, 0.3], [0.2, 0.4]])network["b3"] = np.array([0.1, 0.2])return networkdef forward(nt, x):W1, W2, W3 = nt["W1"], nt["W2"], nt["W3"]b1, b2, b3 = nt["b1"], nt["b2"], nt["b3"]a1 = np.dot(x, W1) + b1z1 = sigmoid(a1)a2 = np.dot(z1, W2) + b2z2 = sigmoid(a2)a3 = np.dot(z2, W3) + b3y = identity_function(a3)return ynetwork = init_work()
x = np.array([1.0, 0.5])
y = forward(network, x)
print("y is {}".format(y)) # y is [0.31682708 0.69627909]
init_network()函數(shù)會(huì)進(jìn)行權(quán)重和偏置的初始化,并將它們保存在字典變量 network中。這個(gè)字典變量 network 中保存了每一層所需的參數(shù)(權(quán)重和偏置)。forward()函數(shù)中則封裝了將輸入信號(hào)轉(zhuǎn)換為輸出信號(hào)的處理過(guò)程。
forward (前向)一詞,它表示的是從輸入到輸出方向的傳遞處理。與之對(duì)應(yīng)的backward 表示從輸出到輸入方向的處理。
參考:《深度學(xué)習(xí)入門(mén):基于Python的理論與實(shí)現(xiàn)》
總結(jié)
以上是生活随笔為你收集整理的机器学习入门(05)— 使用 NumPy 实现 3 层简单神经网络的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 填空题树直用处多的下一句是什么呢?
- 下一篇: 机器学习入门(06)— 输出层多元分类、