反向传播和梯度降低这两个词,第一眼看上去似懂非懂,不明觉厉。这两个概念是整个神经网络中的重要组成部分,是和偏差函数/损失函数的概念分不开的。git
神经网络训练的最基本的思想就是:先“蒙”一个结果,咱们叫预测结果h,看看这个预测结果和事先标记好的训练集中的真实结果y之间的差距,而后调整策略,再试一次,这一次就不是“蒙”了,而是有依据地向正确的方向靠近。如此反复屡次,一直到预测结果和真实结果之间相差无几,亦即|h-y|->0,就结束训练。github
在神经网络训练中,咱们把“蒙”叫作初始化,能够随机,也能够根据之前的经验给定初始值。即便是“蒙”,也是有技术含量的。网络
举个通俗的例子,Bob拿了一支没有准星的步枪,或者是准星有bug,或者是Bob眼神儿很差看不清靶子,或者是雾很大......反正就是Bob很倒霉。第一次试枪后,拉回靶子一看,弹着点偏左了,因而在第二次试枪时,Bob就会有意识地向右侧偏几毫米,再看靶子上的弹着点,如此反复几回,Bob就会掌握这支步枪的脾气了。下图显示了Bob的5次试枪过程:机器学习
在这个例子中:函数
上图是每次单发点射,因此每次训练样本的个数是1。在实际的神经网络训练中,一般须要多个样本,作批量训练,以免单个样本自己采样时带来的偏差。在本例中,多个样本能够描述为连发射击,假设一次能够连打3发子弹,每次的离散程度都相似,以下图所示:post
其实损失就是全部样本的偏差的总和,因此有时候损失函数能够和偏差函数混用概念。学习
其实射击还不这么简单,若是是远距离狙击,还要考虑空气阻力和风速,在神经网络里,空气阻力和风速能够对应到隐藏层的概念上。spa
咱们再用一个纯数学的例子来讲明反向传播的概念。.net
假设咱们有一个函数 z=x∗y,其中:x=w∗2+b,y=b+1,即:z=(w∗2+b)∗(b+1)z=x∗y,其中:x=w∗2+b,y=b+1,即:z=(w∗2+b)∗(b+1)3d
关系以下图:
注意这里x, y, z不是变量,w, b是才变量,由于在神经网络中,咱们要最终求解的是w和b的值,x,y,z只是样本值。
当w = 3, b = 4时,会获得以下结果
最终的z值,受到了前面不少因素的影响:变量w,变量b,计算式x,计算式y。常数是个定值,不考虑。目前的z=50,若是咱们想让z变大一些,w和b应该如何变化呢?
咱们从z开始一层一层向回看,图中各节点关于变量b的偏导计算结果以下图:
由于z = x * y,其中x = w * 2 + b,y = b + 1
因此:
∂z∂b=∂z∂x∗∂x∂b+∂z∂y∗∂y∂b=5∗1+10∗1=15∂z∂b=∂z∂x∗∂x∂b+∂z∂y∗∂y∂b=5∗1+10∗1=15
其中:
∂z∂x=∂∂x(x∗y)=y=5∂z∂x=∂∂x(x∗y)=y=5
∂z∂y=∂∂y(x∗y)=x=10∂z∂y=∂∂y(x∗y)=x=10
∂x∂b=∂∂b(w∗2+b)=1∂x∂b=∂∂b(w∗2+b)=1
∂y∂b=∂∂b(b+1)=1∂y∂b=∂∂b(b+1)=1
有一个颇有趣的问题是:z = x * y = 10 * 5 = 50,表面看起来x=10,y=5,彷佛x对z的贡献较大。那么x的微小变化和y的微小变化对z来讲,哪个贡献大呢?
咱们假设只有x变化时,△x = 0.1, 则z = (x + △x) * y = 10.1 * 5 = 50.5
咱们再假设只有y变化时,△y = 0.1, 则z = x * (y +△y) = 10 * 5.1 = 51
50.5 < 51,说明y的微小变化对z的贡献比较大,这个从
∂z∂x=∂∂x(x∗y)=5<∂z∂y=∂∂y(x∗y)=10∂z∂x=∂∂x(x∗y)=5<∂z∂y=∂∂y(x∗y)=10
和这两个值的比较来看也能够证实。而△x和△y就能够理解为梯度值。
同理,咱们也能够获得图中各变量对w的偏导值:
从以上两图能够看出,反向微分保留了全部变量(包括中间变量)对结果z的影响。若z为偏差函数,则对图进行一次计算,能够获得全部节点对z的影响,即梯度值,下一步就能够利用这些梯度值来更新w和b的权重。
w的变化和b的变化,哪个对z的变化贡献大?从图中还能够注意到:
∂z∂b=15∂z∂b=15
∂z∂w=10∂z∂w=10
因此每次w和b的变化值是不相同的,b的变化会比w大一些,也就是每一步的跨度大一些,这个是与z = xy = (w2+b)*(b+1)这个算式相关的,并不表明神经网络中实际状况。
仍是用上面的例子,目前:
假设咱们最终的目的想让z = 60,只改变b的值,如何实现?
答案就是偏导数:
∂z∂b=ΔzΔb=15∂z∂b=ΔzΔb=15
目前z=50, 距离60相差10,因此咱们令Δz=60−50=10Δz=60−50=10,则:
ΔzΔb=15=10ΔbΔzΔb=15=10Δb
因此:
Δb=0.66667Δb=0.66667
再带入式子中(顺便说一句,下面这个计算过程就叫作前向计算)
一会儿超过60了,咋办?再来一次(下面的过程就叫作反向传播):
咱们令Δz=60−60.4445=−0.4445Δz=60−60.4445=−0.4445,则:
ΔzΔb=15=−0.4445ΔbΔzΔb=15=−0.4445Δb
因此:
Δb=−0.02963Δb=−0.02963
再带入式子中:
咦哈!十分接近59.96了!再迭代几回,应该能够近似等于60了,直到偏差不大于0.00001时,咱们就能够结束迭代了,对于计算机来讲,这些运算的执行速度很快。
有的同窗会说了:这个问题不是用数学公式倒推求解一个二次方程,就能直接获得准确的b值吗?是的!可是咱们是要说明机器学习的方法,机器并不会解二次方程,并且不少时候不是用二次方程就能解决实际问题的。而上例所示,是用机器所擅长的迭代计算的方法来不断逼近真实解,这就是机器学习的真谛!并且这种方法是广泛适用的。
不少资料中会用下面这个图来讲明梯度降低,可是都没有说清楚如下几个问题:
1) 为啥用这个看上去像y=x2y=x2族的函数来讲明梯度降低?
2) 在最低点的左侧,梯度值是负数;在最低点的右侧,梯度值是正数。为何说是“降低”?
3) 为何1—>2,2—>3等等的连线不是这条曲线的切线呢,而好像是弦线?
这是由于有一种损失函数的形式就是均方差,亦即:
loss=∑i(ai−yi)2loss=∑i(ai−yi)2
其中a是本次迭代的预测结果,y是样本中的真实结果。咱们的目的就是在这个函数上求最小值,使loss最小,这样样本值和预测值就会很是很是接近,以便于咱们之后预测不在样本中的真实数据。
“梯度降低”,刚接触这个词时,我老是往“下降难度”或“下降维度”方面去理解,由于有个“降低”的动词在里面。而实际上,“降低”在这里面的含义是“与导数相反的方向”的意思。
咱们假设上面这个图形的函数是y=(x−1)2+0.001y=(x−1)2+0.001,则y′x=2(x−1)yx′=2(x−1)。
而在标准的权重更新公式里:
w=w–η∗Δww=w–η∗Δw
b=b–η∗Δbb=b–η∗Δb
能够看到不管是w仍是b,都是用上一次的权重值减去步长××梯度。
因此整体上看,不管x在极值的左侧仍是右侧,都会向中间(坡底)靠拢,确实是“降低”了。
不知不觉中,咱们已经接触到了第一个神经网络中的超参η,即步长值,这个值对于神经网络训练很是重要,决定了训练时间的长短。
因此,弦线在这里面没啥用途,只是表示一个迭代跳跃的动做而已。实际的变化值已经由绿色的线定义好了。