反向传播算法

第一层是输入层,包含两个神经元i1、i2,和截距项b1;第二层是隐含层,包含两个神经元h1、h2和截距项b2,第三层是输出o1、o2,每条线上标的wi是层与层之间连接的权重,激活函数默认为sigmoid函数。
为了更好的进行计算,这里初始化权重weights、偏置项biases和神经网络的输入/输出:

输入数据 i1=0.05,i2=0.10;
输出数据 o1=0.01,o2=0.99;
初始权重 w1=0.15, w2=0.20, w3=0.25, w4=0.30; w5=0.40, w6=0.45, w7=0.50, w8=0.55;
反向传播的目标是优化权重,以便神经网络可以学习如何正确地将任意输入映射到输出。
目标:给定输入数据i1(0.05)和i2(0.10),使输出尽可能与原始输出o1(0.01)和o2(0.99)接近。
前向传播
首先,让我们看一下在给定的权重和偏差以及输入为0.05和0.10的情况下,神经网络当前的输出。
输入层—>隐含层
计算神经元$h_1$的输入加权和:
使用Sigmoid函数计算神经元$h_1$的输出:
同理,可以计算出神经元$h_2$的输出:
隐含层—>输出层
计算输出层神经元o1的值:
同理,可计算输出层神经元o2的值:
计算总误差
使用平方误差函数计算每个输出神经元的误差,并对它们求和以得出总误差:
因为有两个输出,所以分别计算o1的误差:
和计算o2的误差:
总误差为两者之和:
反向传播
输出层—>隐含层
反向传播的目标是更新网络中的每个权重,以便它们使实际输出更接近目标输出,从而将每个输出神经元和整个网络的误差降到最低。
对于$w_5$来讲,如果我们想知道$w5$对整体误差产生了多少影响,可以用整体误差对$w5$求偏导求出,由求导的链式法则可得:
下图可以直观上理解误差是如何反向传播的:

我们需要找出这个方程式中的每一部分:首先,计算总误差相对于输出的梯度$\frac{\partial E_{total}}{\partial out_{o1}}$:
在上图神经元中,输出$out_{o1}$与输入$net_{01}$存在以下函数关系:
由于逻辑函数的偏导数是输出乘以1减去本身,可得:
继续计算$\frac{\partial net_{o1}}{\partial w_{5}}$:
最后,相乘计算$\frac{\partial E_{\text {total}}}{\partial w_{5}}$:
由上面可以得知,整体误差的偏导常常以以下形式组合在一起:
为了表达方便,用$\delta_{o1}$来表示输出层的误差:
因此,整体误差$E(total)$对$w5$的偏导公式可以写成:
最后使用梯度下降来更新$w_5$:
有些地方使用$\alpha$表示学习率,这里使用$\eta$来表示。
我们可以重复这个过程来更新其他权重:
隐含层—>输入层
下面接着向后传递通过计算$w_1、w_2、w_3、w_4$,首先计算$\frac{\partial E_{\text {total }}}{\partial w_{1}}$:
我使用与输出层类似的过程,但略有不同,因为每个隐藏层神经元的输出会影响多个输出神经元的输出($out_{h_1}$会影响$out_{o1}$和$out_{o2}$)。直观上理解:

在隐含层之间的权值更新时,$out(h1)—>net(h1)—>w1$,而$out(h1)$会接受$E(o1)$和$E(o2)$两个地方传来的误差,所以这个地方两个都要计算。
计算$\frac{\partial E_{o1}}{\partial \text {out}_{h1}}$:
按照此过程,同样求出:
得到总值:
现在,我们求出了$\frac{\partial E_{total}}{\partial out_{h1}}$,,还需要弄清楚$\frac{\partial out_{h 1}}{\partial net_{h1}}$以及$ \frac{\partial net_{h1}}{\partial w_{1}}$,其中:
计算$h_1$相对于$w_1$输出神经元的总输入的偏导数:
最后可得:
>
>
简化公式,使用$\delta_{h_1}$表示隐含层单元$h1$的误差
更新$w_1$的值:
同理,可得:
这样误差反向传播法就完成了,最后我们再把更新的权值重新计算,不停地迭代,在这个例子中第一次迭代之后,总误差E(total)由0.298371109下降至0.291027924。迭代10000次后,总误差为0.000035085,输出为0.015912196,0.984065734(原输出为[0.01,0.99]),
最初以0.05和0.1作为输入时,网络上的误差为0.298371109。经过第一轮反向传播后,总误差现在降至0.291027924。看起来似乎不多,但是在重复此过程10,000次之后,总误差降至0.0000351085。最终,当我们以0.05和0.1作为输入进行前向传播时,两个输出神经元生成0.015912196(相对于0.01)和0.984065734(相对于0.99),证明误差传播算法还是有效的。
1 | import random |
Summary



