欢迎关注本人的微信公众号AI_Engine(关注的人不算多,盘起来啊同志们)
在说BP之前我们不得不提一下梯度下降,正是因为有这个‘女人’在BP身后默默的付出,才有了BP算法现在的影响力和成就。当然BP也背了很多的锅,比如梯度爆炸和梯度弥散,这都是后话了,我们先说说梯度吧。我们知道在多层前馈网络中,激活函数从简单粗暴的阶跃函数sgn已经演变成了丝滑的sigmoid。同学们会有疑问那就是为什么要换呢?有什么好处呢?因为激活函数还是阶跃函数的话就非常不利于函数的求导,进而难以使用优化算法求得损失函数的最小值。损失函数其实用真实值与预测值之间的距离来指导模型收敛的方向,所以说如果不能正确的使用损失函数,那么就无法训练出正确的模型。
一般比较常用的损失函数就是均值平方差与交叉熵了。如果是分类任务使用交叉熵的比较多,如果是回归任务使用均值平方差(MSE)较多。二者的公式并不复杂,如下所示:
那么我们如何得到损失函数的最小值呢,一般分三步:1.计算损失函数的梯度 2.按照梯度的反方向走,缩小损失 3.重复第一步和第二步。一般的我们会按照负梯度的若干倍(通常小于1)去不断调整函数权值,而这里的‘若干倍’就是学习率,整个调整权值的方法就是梯度下降法。通过梯度下降法我们可以很快的改变每个神经元的连接权重与自身的偏执项,让损失函数的值下降的更快。
刚才我们已经确立了目标:找到损失函数的最小值。所以按照我们预定好的步骤那就是找到损失函数的梯度,所谓梯度我们可以这样理解。如果在单变量的函数中,梯度就可以理解为导数,也就是曲线上某点的斜率。但是在多维变量的函数中,梯度就是一个向量场。别担心,我们不去关心这些晦涩的数学名词,我用一个例子给大家说明一下,在多维变量的函数中梯度(grad)是如何求解与使用的:
1.首先我们已知多维变量函数f,然后我们计算每个变量的偏导数,最终我们求得f的梯度表示为grad(f)
2.接下来,我们针对某一点如A(1,2,3),求得其梯度为(8,7,27)。也就是说对于A点,如果该点向(8,7,27)增长最为迅速。其线性表示可如下所示:
介绍完了梯度的概念与描述,那梯度递减就很容易理解了。梯度递减就是沿着梯度的反方向传播,也就是损失函数下降的最快方向。现在我们书归正传,讲讲BP算法。首先我们要明确的是BP算法是是双向算法,也就是正反向算法,其具体步骤为:1.正向传播输入信息,实现分类功能 2.反向传播误差,调整网络权值。本文主要使用具体的数值与网络结构去描述反向传播的全过程,如果您不了解神经网络的具体结果请看我之前发布的文章,关于前馈神经网络,卷积神经网络和循环神经网络的都有。//www.greatytc.com/p/8c0a63897e60,//www.greatytc.com/p/a757e5642880,//www.greatytc.com/p/83f3b8409b91。
假设,有这样一个网络层与对应的网络参数初始值。第一层是输入层,包含两个神经元i1,i2,和偏置b1;第二层是隐含层,包含两个神经元h1,h2和偏置b2,第三层是输出o1,o2,每条线上标的wi是层与层之间连接的权重,激活函数我们默认为sigmoid函数,损失函数我们使用均值平方差函数。目标就是给出输入数据i1,i2(0.05和0.10),通过与所有的网络参数计算,使输出尽可能与原始输出o1,o2(0.01和0.99)接近。
1.前向传播:分别计算h1,h2,o1,o2
目前为止我们第一epoch的前向传播就结束了,输出的[0.75136079 , 0.772928465],与实际值[0.01 , 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。
2.反向传播:
(1)计算总误差:
(2)隐含层---->输出层的权值更新:
以权重参数w5为例,如果我们想知道w5对整体误差产生了多少影响,可以用整体误差对w5求偏导求出:(链式法则)
下面是具体计算过程:
最后我们更新w5的权值:
(3)输入层---->隐含层的权值更新:
注意:在输入层到隐含层之间的权值更新时,是out(h1)---->net(h1)---->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。
因为:
所以:
且:
所以:
同理:
接下来:
最后,更新w1的权值:
通过上述的例子我们可以把其余所有的权值都进行更新迭代,并且每次重新计算残差,直至达到损失函数的最小值,这样到最后我们得到的就是具有正确权值的最佳模型。好了,这就是BP反向传播大致的流程,可能哪里还是有些瑕疵,欢迎您的指导。如果您喜欢我的文章就请点个赞关注吧~谢谢啦!