逻辑异或门
样本 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
x1 | 0 | 0 | 1 | 1 |
x2 | 0 | 1 | 0 | 1 |
y | 0 | 1 | 1 | 0 |
理想分类结果
实践证明两层神经网络可以解决问题。我们可以模拟这个思路,用两层神经网络搭建如下模型:
- 输入层两个特征值x1, x2 {(0, 0),(0, 1),(1,0),(1, 1)}
- 隐层2x2的权重矩阵和2x1的偏移矩阵
- 隐层由两个神经元构成
- 输出层有一个神经元使用Sigmoid函数进行分类
前向计算
(10)
Z
1
=
W
1
⋅
X
+
B
1
Z1 = W1 \cdot X + B1 \tag{10}
Z1=W1⋅X+B1(10)
(11)
A
1
=
S
i
g
m
o
i
d
(
Z
1
)
A1 = Sigmoid(Z1) \tag{11}
A1=Sigmoid(Z1)(11)
(12)
Z
2
=
W
2
⋅
A
1
+
B
2
Z2 = W2 \cdot A1 + B2 \tag{12}
Z2=W2⋅A1+B2(12)
(13)
A
2
=
S
i
g
m
o
i
d
(
Z
2
)
A2 = Sigmoid(Z2) \tag{13}
A2=Sigmoid(Z2)(13)
注意:公式13的Sigmoid在这里不是激活函数,不是激活函数,不是激活函数(重要的概念说三遍),是用作分类函数。
损失函数
我们把异或问题归类成二分类问题,所以使用二分类交叉熵损失函数:
(14) J ( w , b ) = − 1 m ∑ i = 1 m y i ln ( a i ) + ( 1 − y i ) ln ( 1 − a i ) J(w,b) = -{1 \over m} \sum^m_{i=1}y_i \ln (a_i)+(1-y_i) \ln (1-a_i) \tag{14} J(w,b)=−m1i=1∑myiln(ai)+(1−yi)ln(1−ai)(14)
可以简写为:
(15) J = − Y ln A + ( 1 − Y ) ln ( 1 − A ) J = -Y \ln A + (1-Y) \ln (1-A) \tag{15} J=−YlnA+(1−Y)ln(1−A)(15)
反向传播
梯度生成
对损失函数求导,可以得到损失函数对输出层的梯度值,即上图中的Z2部分。
根据公式15,求A2和Z2的导数:
∂ J ∂ Z 2 = ∂ J ∂ A 2 ⋅ ∂ A 2 ∂ Z 2 {\partial{J} \over \partial{Z2}}={\partial{J} \over \partial{A2}} \cdot {\partial{A2} \over \partial{Z2}} ∂Z2∂J=∂A2∂J⋅∂Z2∂A2 = A 2 − Y A 2 ( 1 − A 2 ) ⋅ A 2 ( 1 − A 2 ) = {A2-Y \over A2(1-A2)} \cdot A2(1-A2) =A2(1−A2)A2−Y⋅A2(1−A2) (15) = A 2 − Y = > d Z 2 =A2-Y \tag{15} => dZ2 =A2−Y=>dZ2(15)
求W2和B2的梯度
(16) ∂ J ∂ W 2 = ∂ J ∂ Z 2 ∂ Z 2 ∂ W 2 = d Z 2 × A 1 T = > d W 2 {\partial{J} \over \partial{W2}}={\partial{J} \over \partial{Z2}}{\partial{Z2} \over \partial{W2}}=dZ2 \times A1^T => dW2\tag{16} ∂W2∂J=∂Z2∂J∂W2∂Z2=dZ2×A1T=>dW2(16)
(17) ∂ J ∂ B 2 = ∂ J ∂ Z 2 ∂ Z 2 ∂ B 2 = d Z 2 = > d B 2 {\partial{J} \over \partial{B2}}={\partial{J} \over \partial{Z2}}{\partial{Z2} \over \partial{B2}}=dZ2 => dB2 \tag{17} ∂B2∂J=∂Z2∂J∂B2∂Z2=dZ2=>dB2(17)
求损失函数对隐层的梯度
∂ J ∂ Z 1 = ∂ J ∂ Z 2 ⋅ ∂ Z 2 ∂ A 1 ⋅ ∂ A 1 ∂ Z 1 \frac{\partial{J}}{\partial{Z1}} = \frac{\partial{J}}{\partial{Z2}} \cdot \frac{\partial{Z2}}{\partial{A1}} \cdot \frac{\partial{A1}}{\partial{Z1}} ∂Z1∂J=∂Z2∂J⋅∂A1∂Z2⋅∂Z1∂A1 (18) = W 2 T × d Z 2 ⊙ A 1 ⊙ ( 1 − A 1 ) = > d Z 1 =W2^T \times dZ2 \odot A1 \odot (1-A1)=>dZ1 \tag{18} =W2T×dZ2⊙A1⊙(1−A1)=>dZ1(18)
求W1和B1的梯度
(19) ∂ J ∂ W 1 = ∂ J ∂ Z 1 ∂ Z 1 ∂ W 1 = d Z 1 × X T = > d W 1 \frac{\partial{J}}{\partial{W1}} = \frac{\partial{J}}{\partial{Z1}} \frac{\partial{Z1}}{\partial{W1}}= dZ1 \times X^T => dW1\tag{19} ∂W1∂J=∂Z1∂J∂W1∂Z1=dZ1×XT=>dW1(19)
(20) ∂ J ∂ B 1 = ∂ J ∂ Z 1 ∂ Z 1 ∂ B 1 = d Z 1 = > d B 1 \frac{\partial{J}}{\partial{B1}} = \frac{\partial{J}}{\partial{Z1}} \frac{\partial{Z1}}{\partial{B1}}= dZ1 => dB1\tag{20} ∂B1∂J=∂Z1∂J∂B1∂Z1=dZ1=>dB1(20)
运行结果
w=[[-7.00777143 -7.01121059]
[ 5.51518649 5.51451102]]
b=[[ 2.86885647]
[-8.53863829]]
隐层神经元数量的选择
一般来说,隐层的神经元数量要大于等于输入特征的数量,在本例中是2。我们从下图可以看到,如果隐层只有一个神经元的话,是不能完成分类任务的。
![]() | ![]() |
1个神经元 | 2个神经元,迭代6040次到达精度要求 |
![]() | ![]() |
3个神经元,迭代5228次到达精度要求 | 4个神经元,迭代4331次到达精度要求 |
![]() | ![]() |
6个神经元,迭代3903次到达精度要求 | 8个神经元,迭代4107次到达精度要求 |
![]() | ![]() |
12个神经元,迭代4667次到达精度要求 | 16个神经元,迭代4402次到达精度要求 |
隐层有两个神经元的工作原理
以下是隐层为两个神经元时的结果输出:
w=[[-7.00777143 -7.01121059]
[ 5.51518649 5.51451102]]
b=[[ 2.86885647]
[-8.53863829]]
我们使用上面的权重矩阵结果,把4个样本数据代入到前向计算公式中,依次求得Z1,A1,Z2,A2的值,并列表如下:
1 | 2 | 3 | 4 | |
---|---|---|---|---|
x1 | 0 | 0 | 1 | 1 |
x2 | 0 | 1 | 0 | 1 |
y | 0 | 1 | 1 | 0 |
Z1 | 2.86885647 | -4.14235412 | -4.13891495 | -11.15012554 |
-8.53863829 | -3.02412727 | -3.0234518 | 2.49105922 | |
A1 | 9.46285253e-01 | 1.56370110e-02 | 1.56900366e-02 | 1.43732759e-05 |
1.95718330e-04 | 4.63477089e-02 | 4.63775738e-02 | 9.23512657e-01 | |
Z2 | -5.45851003 | 5.20347907 | 5.20247396 | -5.3417112 |
A2 | 0.00424183 | 0.99453265 | 0.99452718 | 0.00476486 |
完成了分割任务的二维图示分析
![]() | ![]() |
1) 原始x1做横轴,x2做纵轴的4个点,处于4个角落 | 2) 线性变换结果,用Z1[0,0]做横轴,Z1[1,0]做纵轴的4个点,两个绿点接近重合 |
![]() | ![]() |
3) Z1的Sigmoid结果,用A1[0,0]做横轴,A1[1,0]做纵轴的4个点,两个绿点接近重合 | 4) A1点经过第二次线性变化,4个点归类到横轴上的0点两侧,位置大概是-5.7和+5.7处(Z2的位置)。A2可以匹配到Sigmoid曲线上 |
完成学习的过程
损失函数值的变化与分类效果对比
损失函数值 | |
---|---|
![]() | ![]() |
500次迭代时损失值为0.67 | 500次迭代两种颜色基本平分 |
![]() | ![]() |
800次迭代时损失值为0.53 | 800次迭代粉色区域逐渐向左下方移动 |
![]() | ![]() |
1000次迭代时损失值为0.346 | 1000次迭代右上角出现黄色区域 |
![]() | ![]() |
6000次迭代时损失值为0.005 | 6000次迭代完美分割 |
Z1和A1的演进
Z1为线性变换结果,A1是Z1的Sigmoid压缩结果。
Z1:值域较大 | A1:值域在[0,1]之内 |
---|---|
![]() | ![]() |
500次迭代时两个绿点较为分散 | 500次迭代绿点较散 |
![]() | ![]() |
800次迭代时绿点接近,红点向两侧拉开 | 800次迭代绿点接近 |
![]() | ![]() |
1000次迭代时趋势更明显,但相对位置不变 | 1000次迭代 |
![]() | ![]() |
6000次迭代时绿点重合,红点拉到最远 | 6000次迭代 |
Z2:A2的演进
下图是用Z2做横坐标,A2做纵坐标绘制,因为Z2,A2都是一个标量,或者说是直线上的点。
Z2:A2 | |
---|---|
![]() | ![]() |
500次迭代分类不清 | 800次迭代起色不大,红绿点还没分开 |
![]() | ![]() |
1000次迭代向两极靠拢 | 6000次迭代完美分割 |
隐层有三个神经元的工作原理
最终输出的权重矩阵值:
[[ 6.70984241 -6.82710114]
[ 6.22781451 -5.99280808]
[-2.74806343 2.4870413 ]]
b=[[-3.51362288]
[ 3.15804745]
[-1.4773994 ]]
w=[[12.31224597 -9.738143 3.80483026]]
b=[[3.05151459]]
迭代5000次到达精度要求的各层的网络输出:
1 | 2 | 3 | 4 | |
---|---|---|---|---|
x1 | 0 | 0 | 1 | 1 |
x2 | 0 | 1 | 0 | 1 |
y | 0 | 1 | 1 | 0 |
Z1 | 3.51362288 | -10.34072402 | 3.19621952 | -3.63088162 |
3.15804745 | -2.83476063 | 9.38586196 | 3.39305388 | |
-1.4773994 | 1.00964189 | -4.22546284 | -1.73842154 | |
A1 | 2.89270940e-02 | 3.22898922e-05 | 9.60691763e-01 | 2.58090628e-02 |
9.59224645e-01 | 5.54744264e-02 | 9.99916105e-01 | 9.67486745e-01 | |
1.85820545e-01 | 7.32950061e-01 | 1.44079436e-02 | 1.49513539e-01 | |
Z2 | -5.22637905 | 5.30044483 | 5.19728163 | -5.48336852 |
A2 | 0.00534423 | 0.9950354 | 0.99449885 | 0.00413811 |
我们可以把Z1,A1看作是一个三维的坐标点,并比较迭代200次与迭代5000次的结果,从而了解神经网络的工作过程:
迭代200次 | 迭代5000次 | |
---|---|---|
初始x1:x2 | ![]() | ![]() |
Z1:观察角度1 | ![]() | ![]() |
两个红色点距离较远 | 两个红色点距离很近 | |
Z1:观察角度2 | ![]() | ![]() |
绿色点从一开始就已经分得很开 | 绿色点的距离越来越远 | |
A1:观察角度1 | ![]() | ![]() |
红点较散 | 红点聚集到了一个角落里,绿点拉开距离 | |
A1:观察角度2 | ![]() | ![]() |
Z2:A2 | ![]() | ![]() |
两种颜色的点没有分开 | 彻底分开了 | |
结果 | ![]() | ![]() |
到底是把两个红点变换到一起去,还是变换绿点,取决于随机初始化结果。
https://github.com/microsoft/ai-edu/blob/master/B-教学案例与实践/B6-神经网络基本原理简明教程/10.2-理解二分类的工作原理.md#隐层神经元数量的选择
https://github.com/microsoft/ai-edu/blob/master/B-教学案例与实践/B6-神经网络基本原理简明教程/10.1-实现逻辑异或门.md