现在我们来进行神经网络的实现。这里我们以下图的3层神经网络为对象,实现从输入到输出的(前向)处理。在代码实现方面,使用上一节介 绍的NumPy多维数组。巧妙地使用NumPy数组,可以用很少的代码完成 神经网络的前向处理。
导入新符号
如图所示,权重和隐藏层的神经元的右上角有一个“(1)”,它表示权重和神经元的层号(即第1层的权重、第1层的神经元)。此外,权重的右下角有两个数字,它们是后一层的神经元和前一层的神经元的索引号
各层间信号传递的实现
用数学公式表示为:
{
a
1
(
1
)
=
ω
11
(
1
)
x
1
+
ω
12
(
1
)
x
2
+
b
1
(
1
)
a
2
(
1
)
=
ω
21
(
1
)
x
1
+
ω
22
(
1
)
x
2
+
b
2
(
1
)
a
3
(
1
)
=
ω
31
(
1
)
x
1
+
ω
32
(
1
)
x
2
+
b
3
(
1
)
\begin{cases}a_1^{(1)}=\omega_{11}^{(1)}x_1+\omega_{12}^{(1)}x_2+b_1^{(1)}\\a_2^{(1)}=\omega_{21}^{(1)}x_1+\omega_{22}^{(1)}x_2+b_2^{(1)}\\a_3^{(1)}=\omega_{31}^{(1)}x_1+\omega_{32}^{(1)}x_2+b_3^{(1)}\end{cases}
⎩⎪⎨⎪⎧a1(1)=ω11(1)x1+ω12(1)x2+b1(1)a2(1)=ω21(1)x1+ω22(1)x2+b2(1)a3(1)=ω31(1)x1+ω32(1)x2+b3(1)
用矩阵表示为:
[
a
1
(
1
)
a
2
(
1
)
a
3
(
1
)
]
=
[
ω
11
(
1
)
ω
12
(
1
)
ω
21
(
1
)
ω
22
(
1
)
ω
31
(
1
)
ω
32
(
1
)
]
×
[
x
1
x
2
]
+
[
b
1
(
1
)
b
2
(
1
)
b
3
(
1
)
]
\left[\begin{matrix}a_1^{(1)}\\a_2^{(1)}\\a_3^{(1)}\end{matrix}\right]=\left[\begin{matrix}\omega_{11}^{(1)}&\omega_{12}^{(1)}\\\omega_{21}^{(1)}&\omega_{22}^{(1)}\\\omega_{31}^{(1)}&\omega_{32}^{(1)}\end{matrix}\right]\times\left[\begin{matrix}x_1\\x_2\end{matrix}\right]+\left[\begin{matrix}b_1^{(1)}\\b_2^{(1)}\\b_3^{(1)}\end{matrix}\right]
⎣⎢⎡a1(1)a2(1)a3(1)⎦⎥⎤=⎣⎢⎡ω11(1)ω21(1)ω31(1)ω12(1)ω22(1)ω32(1)⎦⎥⎤×[x1x2]+⎣⎢⎡b1(1)b2(1)b3(1)⎦⎥⎤
即:
A
(
1
)
=
W
(
1
)
X
+
B
(
1
)
A^{(1)}=W^{(1)}X+B^{(1)}
A(1)=W(1)X+B(1)
也可以写转置后的表达式:
(
A
(
1
)
)
T
=
X
T
(
W
(
1
)
)
T
+
(
B
(
1
)
)
T
(A^{(1)})^T=X^T (W^{(1)})^T + (B^{(1)})^T
(A(1))T=XT(W(1))T+(B(1))T
即:
[
a
1
(
1
)
a
2
(
1
)
a
3
(
1
)
]
=
[
x
1
x
2
]
×
[
ω
11
(
1
)
ω
21
(
1
)
ω
31
(
1
)
ω
12
(
1
)
ω
22
(
1
)
ω
32
(
1
)
]
+
[
b
1
(
1
)
b
2
(
1
)
b
3
(
1
)
]
\left[\begin{matrix}a_1^{(1)}&a_2^{(1)}&a_3^{(1)}\end{matrix}\right]=\left[\begin{matrix}x_1&x_2\end{matrix}\right]\times\left[\begin{matrix}\omega_{11}^{(1)}&\omega_{21}^{(1)}&\omega_{31}^{(1)}\\\omega_{12}^{(1)}&\omega_{22}^{(1)}&\omega_{32}^{(1)}\end{matrix}\right]+\left[\begin{matrix}b_1^{(1)}&b_2^{(1)}&b_3^{(1)}\end{matrix}\right]
[a1(1)a2(1)a3(1)]=[x1x2]×[ω11(1)ω12(1)ω21(1)ω22(1)ω31(1)ω32(1)]+[b1(1)b2(1)b3(1)]
下面用Numpy计算 A(1), 这里将输入信号、权重、 偏置设置成任意值。
X = np.array([1.0, 0.5])
W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
B1 = np.array([0.1, 0.2, 0.3])
print(W1.shape) # (2, 3)
print(X.shape) # (2,)
print(B1.shape) # (3,)
A1 = np.dot(X, W1) + B1
接下来,将A(1) 代入激活函数 sigmoid()转换成信号 Z(1)
Z1 = sigmoid(A1)
print(A1) # [0.3, 0.7, 1.1]
print(Z1) # [0.57444252, 0.66818777, 0.75026011
同理,可以描述第二第三层信号传递过程。
注意:
输出层所用的激活函数,要根据求解问题的性质决定。
一般地,回归问题可以使用恒等函数(如上图的 σ ( ) \sigma() σ() 函数),二元分类问题可以使用sigmoid函数, 多元分类问题可以使用softmax函数。
最后,总代码如下:
def sigmoid(x): #激活函数
return 1/(1+np.exp(-x))
def identity_function(x): #恒等函数
return x
def init_network(): #初始化参数
network = {}
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 network
def forward(network, x): #信号传递过程计算
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = identity_function(a3)
return y
network = init_network()
x = np.array([1, 0.5])
y = forward(network, x)
print(y) #[0.31682708 0.69627909]
参考书籍:
深度学习入门:基于python的理论与实践 ——作者:斋藤康毅;译者:陆宇杰