在深度学习中我们通常会对问题进行建模,由此我们可以得到一个成本函数,我们对成本函数就行最小化即可找到问题的部分解,大部分这类问题我们都可以通过梯度下降算法进行求解
梯度概念是建立在偏导数与方向导数概念基础上的,一般来说,梯度可以定义为一个函数的全部偏导数构成的向量(这一点与偏导数与方向导数不同,两者都为标量)。一般将函数f ff的梯度记为∇ f \nabla f∇f,即:
基于梯度和链式法则的MLP反向传播梯度即为神经网络的基础,
说到神经网络,这张图应该不陌生
这是典型的三层神经网络的基本构成,Layer L1是输入层,Layer L2是隐含层,Layer L3是隐含层,我们现在手里有一堆数据{x1,x2,x3,...,xn},输出也是一堆数据{y1,y2,y3,...,yn},现在要他们在隐含层做某种变换,让你把数据灌进去后得到你期望的输出。我们希望输入的数据跟输出的数据一样,为什么输入数据跟输出数据一样呢?这个有什么意义?
因为神经网络每一层都有参数,我们希望我们训练出来的模型的参数足够正确,通过对输入数据的处理,使它输出的数据尽量接近真实值,而训练参数的算法也就是之前所提到的梯度下降算法。
下面举个例子演示一下反向传播的过程。
一个简单的网络层
第一层是输入层,包含两个神经元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)接近。
前向传播
1.数据从输入层i到隐含层h,
神经元h1的加权和(输入数据)为
神经元h1的输出数据(通过sigmoid函数处理)
注:h1的加权和不能直接传入下一层,必须通过sigmoid函数(激活函数)处理,才能传入下一层
同理哈h2同样求法
2.隐含层到输出层
这样前向传播的过程就结束了,我们得到输出值为[0.75136079 , 0.772928465],与实际值[0.01 , 0.99]相差还很远,现在我们对误差进行反向传播,更新权值,重新计算输出。
反向传播
1.计算总误差
总误差=真实值与目标值的差值的平方,再取均值:
求出总误差
2.反向(输出层到隐含层)
以w5为例,求出w5对总误差的影响(链式法则)
依次计算出链式法则右边三项
三者相乘
这样我们就计算出整体误差E(total)对w5的偏导值。
我们发现
为了表达方便,用来表示输出层的误差:
于是推导出
为负数,将它化为正数
再更新出w5
归纳一下:对w5的反向传播更新就是用梯度下降算法x'=x-Δx(这个公式在前面讲过),Δx就是w5对通过链式法则求出w5对总误差的影响。
2.隐含层到输入层
方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对w5的偏导时,是从out(o1)---->net(o1)---->w5,但是在隐含层之间的权值更新时,是out(h1)---->net(h1)---->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。
运算跟上一层传播一样,我们由此算出全部w
最后一步就是不停的迭代,可以使总误差下降,最后输出会接近[0.01,0.99]。