BP神经网络
- 概念
首先从名称中可以看出,BP是 Back Propagation 的简写 ,意思是反向传播。
BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。
其主要的特点是:信号是正向传播的,而误差是反向传播的。
例子
- 某厂商生产一种产品(信号),投放到市场之后得到了(反向)消费者的反馈(误差),根据消费者的反馈,厂商对产品进一步升级,优化,一直循环往复,直到实现最终目的——生产出让消费者更满意的产品。产品投放就是“信号前向传播”,消费者的反馈就是“误差反向传播”。这就是BP神经网络的核心。
正向传播
输入层的神经元负责接受外界发来的各种信息,并将信息传递给中间层神经元,中间隐含层神经元负责将接收到的信息进行处理变换,根据需求处理信息,实际应用中可将中间隐含层设置为一层或者多层隐含层结构,并通过最后一层的隐含层将信息传递到输出层,这个过程就是BP神经网络的正向传播过程。反向传播(不能一次计算就让结果满足期望,需要迭代)
- 当实际输出与理想输出之间的误差超过期望时,就需要进入误差的反向传播过程。它首先从输出层开始,误差按照梯度下降的方法对各层权值进行修正,并依次向隐含层、输入层传播。通过不断的信息正向传播和误差反向传播,各层权值会不断进行调整,这就是神经网络的学习训练。当输出的误差减小到期望程度或者预先设定的学习迭代次数时,训练结束,BP神经网络完成学习。
算法流程

隐藏层
- 设置
- 如果隐含层中的神经元节点设置过少,结果可能造成神经网络的训练过程收敛变慢或者不收敛。如果隐层中节点过多,模型的预测精度会提高,但同时网络拓扑结构过大,收敛速度慢,普遍性会减弱。
- 如果BP神经网络中输入层节点数为m个,输出层节点是为n个,则由下式式可推出隐藏层节点数为s 个。其中b一般为1-9的整数。(matlab工具箱可以算)
- 设置
- 概念
推导(核心思想:反向传播思想)
- 输入层有几个数据就有几个神经元
- 列出加权和,通过加权求和后经过激活函数
- 求偏导,用梯度下降计算更新权重
- 设置最大迭代次数(常用),比如使用数据集迭代100次后停止训练 / 计算训练集在网络上的预测准确率,达到一定门限值后停止训练
计算推导例子

第一层是输入层,包含两个神经元i1,i2,和截距项b1;第二层是隐含层,包含两个
神经元h1,h2和截距项(偏置系数)b2,用于控制神经元被激活的容易程度,第三层
是输出o1,o2,每条线上标的wi是层与层之间连接的权重,激活函数默认为sigmoid函数sigmoid函数:1 1 + e − x \frac {1}{1+e^{-x}}1+e−x1
根据函数图像可知,sigmoid函数可以在保持数据大小关系不变的情况下使特别大或特别小的数变得普通,这一特性很适用于分类问题和bp网络数据的处理。

- 前向传播
- 输入层–>隐含层
- 计算神经元h1的输入加权和:n e t h 1 = w 1 ∗ i 1 + w 2 ∗ i 2 + b 1 ∗ 1 neth1= w1* i1+ w2* i2+ b1* 1neth1=w1∗i1+w2∗i2+b1∗1
- 代入得 n e t h 1 = 0.15 ∗ 0.05 + 0.2 ∗ 0.1 + 0.35 ∗ 1 = 0.3775 net_{h1}=0.15* 0.05+0.2*0.1+0.35* 1 = 0.3775neth1=0.15∗0.05+0.2∗0.1+0.35∗1=0.3775
- 神经元h1的输出o1:(此处用到激活函数为sigmoid函数):
- o u t h 1 = 1 1 + e − n e t h 1 = 1 1 + e − 0.3775 = 0.593269992 out_{h1} = \frac {1}{1+e^{-net_{h1}}} =\frac {1}{1+e^{-0.3775}}=0.593269992outh1=1+e−neth11=1+e−0.37751=0.593269992
- 同理,可计算出神经元h2的输出o2
- o u t h 2 = 0.596884378 out_{h2} = 0.596884378outh2=0.596884378
- 隐含层–>输出层
计算输出层神经元o1和o2的值
n e t o 1 = w 5 ∗ o u t n 1 + w 6 ∗ o u t h 2 + b 2 ∗ 1 net_{o1}= w5 * out_{n1} + w6 * out_{h2} + b2 * 1neto1=w5∗outn1+w6∗outh2+b2∗1
n e t o 1 = 0.4 ∗ 0.593269992 + 0.45 ∗ 0.596884378 + 0.6 ∗ 1 = 1.105905967 net_{o1} =0.4 * 0.593269992+0.45 * 0.596884378+0.6* 1 = 1.105905967neto1=0.4∗0.593269992+0.45∗0.596884378+0.6∗1=1.105905967
o u t o 1 = 1 1 + e − n e t o 1 = 1 1 + e − 1.105905967 = 0.75136507 out_{o1}= \frac {1}{1+e^{-net_{o1}}} = \frac {1}{1+e^{-1.105905967}}= 0.75136507outo1=1+e−neto11=1+e−1.1059059671=0.75136507
o u t o 2 = 0.772928465 out_{o2} = 0.772928465outo2=0.772928465
- 这样前向传播的过程就结束了,我们得到输出值为[0.75136079 ,0.772928465],与实际值[0.01 , 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。
- 输入层–>隐含层
- 反向计算
计算总误差
- 公式 E t o t a l = 1 2 ∑ ( t a r g e t − o u t p u t ) 2 E_{total} = \frac{1}{2}\sum(target - output)^2Etotal=21∑(target−output)2
- 两个输出,所以计算o1和o2的误差,再相加
- E o 1 = 1 2 ( 0.01 − 0.75136507 ) 2 = 0.274811083 E_{o1} = \frac{1}{2}(0.01 - 0.75136507)^2= 0.274811083Eo1=21(0.01−0.75136507)2=0.274811083
E o 2 = 0.023560026 E_{o2} = 0.023560026Eo2=0.023560026
E t o t a l = E o 1 + E o 2 = 0.274811083 + 0.023560026 = 0.298371109 E_{total} = E_{o1} + E_{o2} = 0.274811083+0.023560026 =0.298371109Etotal=Eo1+Eo2=0.274811083+0.023560026=0.298371109
隐含层–>输入层的权值更新(反向传播)
以权重参数w5为例,如果我们想知道w5对整体误差产生了多少影响,可以用整体误差对w5求偏导求出:(链式法则)
误差反向传播的图解

∂ E t o t a l ∂ w 5 = ∂ E t o t a l ∂ o u t o 1 ∗ ∂ o u t o 1 ∂ n e t o 1 ∗ ∂ n e t o 1 ∂ w 5 \frac {\partial E_{total}}{\partial w5} = \frac {\partial E_{total}}{\partial out_{o1}} * \frac {\partial out_{o1}}{\partial net_{o1}} * \frac {\partial net_{o1}}{\partial w5}∂w5∂Etotal=∂outo1∂Etotal∗∂neto1∂outo1∗∂w5∂neto1
分别计算三个偏导数 :找出包含分母的表示分子的式子,然后求偏导代值

该偏导即为导数,前面的两个式子分别是sigmoid及其对x的导数,注意隐藏层的输出结果并非最后的输出结果,它的输出是对前一个隐藏层(输入层)加权求和后求sigmoid激活函数得到的。


最后将上方三个结果相乘即得到最终结果

更新w5的值:

- 为学习率,η \etaη设置为0.5,可以调整更新的步伐,合适的学习率能够使目标函数在合适的时间内收敛到局部最小值。学习率设置太小,结果收敛非常缓慢 ; 学习率设置太大,结果在最优值附近徘徊,难以收敛,一般选取为0.01-0.8
同理更新其他三个权重
w 6 + = 0.408666186 w_6^+ = 0.408666186w6+=0.408666186w 7 + = 0.511301270 w_7^+ = 0.511301270w7+=0.511301270
w 8 + = 0.561370121 w_8^+ =0.561370121w8+=0.561370121
隐含层---->隐含层的权值更新:
方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对w5的偏导时,是从out(o1)---->net(o1)---->w5,但是在隐含层之间的权值更新时,是out(h1)---->net(h1)---->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。

公式:

分别计算∂ E o 1 ∂ o u t h 1 \frac {\partial E_{o1}}{\partial out_{h1}}∂outh1∂Eo1和∂ E o 2 ∂ o u t h 1 \frac {\partial E_{o2}}{\partial out_{h1}}∂outh1∂Eo2

- 分别求偏导相乘

同理,计算出 ∂ E o 2 ∂ o u t h 1 = − 0.019049119 \frac {\partial E_{o2}}{\partial out_{h1}} = - 0.019049119∂outh1∂Eo2=−0.019049119
两者相加得到总值,即为链式偏导的第一式

然后计算∂ h 1 ∂ n e t h 1 \frac {\partial h_{1}}{\partial net_{h1}}∂neth1∂h1
计算∂ n e t h 1 ∂ w 1 \frac {\partial net_{h1}}{\partial w_{1}}∂w1∂neth1
计算∂ E t o t a l ∂ w 1 \frac {\partial E_{total}}{\partial w_{1}}∂w1∂Etotal
最后更新w1的权重:

同理,更新w2\w3\w4权重
w 2 + = 0.19956143 w_2^+ = 0.19956143w2+=0.19956143
w 3 + = 0.24975114 w_3^+ = 0.24975114w3+=0.24975114
w 4 + = 0.29950229 w_4^+ = 0.29950229w4+=0.29950229这样误差反向传播法就完成了,最后再把更新的权值重新计算,不停地迭代,在这个例子中第一次迭代之后,总误差E(total)由0.298371109下降至0.291027924。迭代10000次后,总误差为0.000035085,输出为[0.015912196,0.984065734] (原输入为[0.01,0.99]),证明效果还是不错的。|


