后向传播(Backpropagation)是训练神经网络最通用的方法之一,网上有许多文章尝试解释后向传播是如何工作的,但是很少有包括真实数字的例子,这篇博文尝试通过一个简单的例子一步一步向你展示BP神经网络是怎样工作的。
原文网址:https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/
Python源码:https://github.com/mattm/simple-neural-network
登录不了github的可到百度盘下载:链接:https://pan.baidu.com/s/1sJSoufcXBRU7KtHyNY64JQ ;提取码:4vm3
其他资源:如果你想进一步了解神经网络,我建议你看Adrian Rosebrock的教程 Getting Started with Deep Learning and Python
概述
我们将使用2个输入神经元、2个隐含层神经元以及2个输出层神经元组成一个神经网络;另外,隐含层和输出层神经元各包含一个偏差。
这是基本结构:
首先,我们对权重w、偏差b和训练的输入/输出设置一个初始值:
后向传播通过优化权重,从而让神经网络学习怎样得到正确的输出。
我们的输入为:0.05和0.10,我们想要神经网络输出:0.01和0.99。
前向反馈
我们把输入值向前传递,就可以计算得到神经网络的输出结果。
我们知道输入值和权重值,就可以计算得到隐含层中每个神经元的值;同理,也可以计算得到输出层每个神经元的值。
计算h1的输入:
我们利用激活函数(logistic函数),计算得到h1的输出outh1:
同样可以计算得到h2的输出值:
outh2=0.596884378
对输出层神经元重复操作,使用隐含层神经元的输出作为输出层神经元的输入。
这是o1的输出:
o2的输出值:
outo2=0.772928465
计算整体误差
我们能计算每个输出层神经元的误差:
例如,o1的目标输出是0.01,但是神经网络输出是0.75136507,因此误差是:
o2的误差:
Eo2=0.023560026
所以,可知神经网络整体误差:
那么,BP神经网络是如何逐渐调整权重系数,减小总体误差的呢?
后向传播(BP)方法
后向传播的目的是更新网络中每个权重,以便他们的输出值逐渐接近目标输出,从而最小化输出层神经元的误差。
权重系数对输出结果的影响
例如,我们想要知道w5怎样影响整体误差,即:
应用链式规则,可以得到:
下图更清楚地展示了,这个公式是如何得到的,
理解这一步,是理解BP如何工作的关键。
(1),output怎样改变整体误差?
(2),net input怎样改变o1输出?
哈哈,这里需要一点导数的知识:
(3),w5又怎样改变o1的net input?
把它们结合起来,就可以得到:
理解了上一步,我就可以接下来继续看BP是如何调整权重值,从而减小最终的输出误差了
为了减少误差,我们调整当前的权重值,(调整的大小为:误差对权重系数的导数×学习率0.5):
同理,我们可以得到更新后的权重w6,w7和w8:
如何调整输入层和隐含层之间的权重系数
下一步,我们将继续向后计算w1,w2,w3和w4的新值,注意:我们继续使用初始权重,而不是更新过的权重。
首先,我们看下w1是如何影响总体结果误差的:
对应的图解:
首先,计算h1对总体误差的贡献,
h1对总体误差贡献可以分为两部分,即Eo1和Eo2,
这里以Eo1为例,
可知:
也可以计算得到:
因此,可以计算得到Eo1对outh1的偏导:
同理,可以得到Eo2对outh1的偏导:
进而,可得到总体误差对outh1的偏导
结合激活函数,可得到outh1对neth1的导数,
neth1对w1的偏导数如下:
把它们串联起来,可得:
现在我们可以去更新权重值w1了:
同理,可对w2,w3和w4进行更新:
最后,我们统一更新所有权重(即计算完w1-w8后,统一替换原有的权重值)。
效果如何呢?
神经网络的初始误差为0.298371109,在一次权重调整后,整体误差降至0.291027924;看似变化不大,但重复10000次之后,误差就可以下降至0.000035085。这就是BP算法的精髓:找到正确的方向,积跬步以至千里。
最后,神经网络o1和o2输出的值分别为0.015912196和0.984065734,和目标值0.01和0.99十分接近了。