神经网络前向传播一般用于搭建整个神经网络的结构框架,形成整个网络的逻辑通路。反向传播用于更新每层之间的权重,减少损失,进而提升预测准确度。 下面是一个神经网络的结构图:
第一层是输入层,包含两个神经元i1,i2,和截距项b1;第二层是隐含层,包含两个神经元h1,h2和截距项b2,第三层是输出o1,o2,每条线上标的wi是层与层之间连接的权重,激活函数我们默认为sigmoid函数。
PS:激活函数的作用:
正如上图所示,每个神经元节点可以分为两部分,第一步是从前面计算而来的neti,但这个net_i不能直接传送给后面。第二步就是利用激活函数计算出out_i,再根据权重传给后面。
初始化神经网络
附上权重以后如下图:
其中,
输入数据 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,i2(0.05和0.10),使输出尽可能与原始输出o1,o2(0.01和0.99)接近。
Step1: 前向传播
1. 输入层 → 隐含层
计算神经元h1的输入加权和(net_h1):
逻辑表达式为:
矩阵表示形式为:
如:
再利用Softmax激活函数计算得到
同理我们可以计算出:
2. 隐含层→ 输出层
逻辑表达式为:
矩阵表示形式为:
如:
再利用Softmax激活函数计算得到
同理我们可以计算出:
我们得到输出值为[0.75136079 , 0.772928465],与实际值[0.01 , 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。
Step 2 :反向传播
1.计算总误差
总误差——使用均方误差(square error):
target表示目标值,即正确的应该是多少。
所以:
2.隐含层 → 输出层的权值更新:
大体思路:
1.利用偏导数大小量化每个参数对结果的影响(后一个对传向前一个的权重w的偏导)。
2.更新:
计算偏导数要用到链式求导法则。
比如我们要**更新w5**:
也就是下图所演示的过程:
所以算出偏导数为:
2.更新
同理:
3.隐含层 →隐含层的权值更新:
方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对w5的偏导时,是从out(o1)---->net(o1)---->w5,但是在隐含层之间的权值更新时,是out(h1)---->net(h1)---->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。
直接放计算结果:
最后更新w1:
同理:
这样误差反向传播法就完成了,最后我们再把更新的权值重新计算,不停地迭代,在这个例子中第一次迭代之后,总误差E(total)由0.298371109下降至0.291027924。迭代10000次后,总误差为0.000035085,输出为[0.015912196,0.984065734] (原输入为[0.01,0.99]),证明效果还是不错的。
总结:
所以反向传播最主要的是要清楚求偏导的那个递推公式:
注意1:从哪开始推?
从最终得到的误差开始,如果输出有多个,应叠加。
注意2:推到哪结束?
利用w计算出了什么(下个节点的net值),就推到net对w求偏导为止。
参考文献:
原始英文出处:A Step by Step Backpropagation Example
Charlotte77的关于上一篇文章的翻译:一文弄懂神经网络中的反向传播法--BackPropagation - Charlotte77 - 博客园