参考博文:
https://blog.csdn.net/tostq/article/details/51788093
https://www.cnblogs.com/charlotte77/p/5629865.html
https://www.cnblogs.com/ooon/p/5418555.html
http://www.cnblogs.com/maybe2030/p/5597716.html
上面的博客应该是翻译的这个博客:
https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/
上一篇文章中,我们进行了LeNet-5(C实现)前向传播的解析
现在我们解析LeNet-5(C实现)后向传播
在解析之前,看一下,
1学习方法的分类
关于在线学习和批量学习
批量学习方法:突触权值的调整在训练样本集合的所有N个例子都出现后进行,这个N个例子构成训练的一个回合,每个回合的训练样本的样例都是随机选择的,而权值的调整是靠所有N个例子的总体平均来实现。
批量学习方法的优点在于能够精确估计当前梯度向量(即代价函数对权值向量W的导数),因此,保证能最快下降到局部极小点的收敛性,另外能满足并行计算的要求,当前也增加存储压力。
在线学习方法:即样例是一个接一个输入网络中,只有当前一样本输入完成权值调整后,后一样本才能进入网络。在线学习方法相比于批量学习方法,其更容易执行,而且也不易陷入局部极值点,另外比批量学习需要更少的存储空间。
本文这个版本的CNN采用是在线学习方法,DeepLearnToolbox的版本默认是采用的是批量学习,可以将批量数改为1也就成了在线学习方法。
卷积神经网络的后向传播比较复杂,为了理解卷积神经网络的后向传播,我们先来学习一下,以下是前文中提到的参考博客原文
2梯度下降法(粗略看下即可)
2.1感知器
2.2线性单元
2.3误差准则
当然,实际情况下的loss损失函数可能更为复杂,比如鞍面,这样我们使用梯度下降就有可能取到局部极值,从而引出梯度下降的很多优化算法,在另外的博客中我们再行具体论述:
2.4梯度下降法的推导
2.5增量梯度下降
2.6关于寻优方法的比较
3BP神经网络的后向传播
这是典型的三层神经网络的基本构成,Layer L1是输入层,Layer L2是隐含层,Layer L3是隐含层,我们现在手里有一堆数据{x1,x2,x3,...,xn},输出也是一堆数据{y1,y2,y3,...,yn},现在要他们在隐含层做某种变换,让你把数据灌进去后得到你期望的输出。如果你希望你的输出和原始输入一样,那么就是最常见的自编码模型(Auto-Encoder)。
本文直接举一个例子,带入数值演示反向传播法的过程,公式的推导等到下次写Auto-Encoder的时候再写,其实也很简单,感兴趣的同学可以自己推导下试试:)(注:本文假设你已经懂得基本的神经网络构成,如果完全不懂,可以参考Poll写的笔记:[Mechine Learning & Algorithm] 神经网络基础)http://www.cnblogs.com/maybe2030/p/5597716.html
假设,你有这样一个网络层:
第一层是输入层,包含两个神经元i1,i2,和截距项b1;第二层是隐含层,包含两个神经元h1,h2和截距项b2,第三层是输出o1,o2,每条线上标的wi是层与层之间连接的权重,激活函数我们默认为sigmoid函数。
现在对他们赋上初值,如下图:
其中,输入数据 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)接近。
Step 1 前向传播
1.输入层---->隐含层:
计算神经元h1的输入加权和:
神经元h1的输出o1:(此处用到激活函数为sigmoid函数):
同理,可计算出神经元h2的输出o2:
2.隐含层---->输出层:
计算输出层神经元o1和o2的值:
这样前向传播的过程就结束了,我们得到输出值为[0.75136079 , 0.772928465],与实际值[0.01 , 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。
Step 2 反向传播
1.计算总误差
总误差:(square error)
但是有两个输出,所以分别计算o1和o2的误差,总误差为两者之和:
2.隐含层---->输出层的权值更新:
以权重参数w5为例,如果我们想知道w5对整体误差产生了多少影响,可以用整体误差对w5求偏导求出:(链式法则)
下面的图可以更直观的看清楚误差是怎样反向传播的:
现在我们来分别计算每个式子的值:
计算式子:
计算式子:
(这一步实际上就是对sigmoid函数求导,比较简单,可以自己推导一下)
这里我们给出sigmoid函数的导数:
计算式子:
最后三者相乘:
这样我们就计算出整体误差E(total)对w5的偏导值。
回过头来再看看上面的公式,我们发现:
为了表达方便,用来表示输出层的误差:
因此,整体误差E(total)对w5的偏导公式可以写成:
如果输出层误差计为负的话,也可以写成:
最后我们来更新w5的值:
(其中,是学习速率,这里我们取0.5)
同理,可更新w6,w7,w8:
3.隐含层---->隐含层的权值更新:
方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对w5的偏导时,是从out(o1)---->net(o1)---->w5,但是在隐含层之间的权值更新时,是out(h1)---->net(h1)---->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。
现在我们来分别计算每个式子的值:
计算式子:
先计算式子:
同理,计算出:
两者相加得到总值:
再计算式子:
再计算式子:
最后,三者相乘:
为了简化公式,用sigma(h1)表示隐含层单元h1的误差:
最后,更新w1的权值:
同理,可更新w2,w3,w4的权值:
这样误差反向传播法就完成了,最后我们再把更新的权值重新计算,不停地迭代。
在这个例子中第一次迭代之后,
总误差E(total)由0.298371109下降至0.291027924。
迭代10000次后,总误差为0.000035085,
输出为[0.015912196,0.984065734]
(原输入为[0.01,0.99]),证明效果还是不错的。
4BP后向传播的总结
1)为什么要求导数?
2)为什么要求链式导数?
因为我们本质是想改变权重,但是权重和输出之间会参与其他运算比如,加减乘除,sigmod,ReLu,L2欧式距离等
5卷积神经网络的后向传播
梯度下降法更新权重公式:
使用在线学习方法: