• 欢迎访问web前端中文站,JavaScript,CSS3,HTML5,web前端demo
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏web前端中文站吧

神经网络中反向传播与梯度下降的基本概念

JavaScript web前端中文站 10个月前 (11-13) 395次浏览 已收录 0个评论

反向传播和梯度下降这两个词,第一眼看上去似懂非懂,不明觉厉。这两个概念是整个神经网络中的重要组成部分,是和误差函数/损失函数的概念分不开的。

更多精彩内容请看 web 前端中文站
http://www.lisa33xiaoq.net 可按 Ctrl + D 进行收藏

神经网络训练的最基本的思想就是:先“蒙”一个结果,我们叫预测结果 h,看看这个预测结果和事先标记好的训练集中的真实结果 y 之间的差距,然后调整策略,再试一次,这一次就不是“蒙”了,而是有依据地向正确的方向靠近。如此反复多次,一直到预测结果和真实结果之间相差无几,亦即|h-y|->0,就结束训练。

在神经网络训练中,我们把“蒙”叫做初始化,可以随机,也可以根据以前的经验给定初始值。即使是“蒙”,也是有技术含量的。

通俗地理解反向传播

举个通俗的例子,Bob 拿了一支没有准星的步枪,或者是准星有 bug,或者是 Bob 眼神儿不好看不清靶子,或者是雾很大……反正就是 Bob 很倒霉。第一次试枪后,拉回靶子一看,弹着点偏左了,于是在第二次试枪时,Bob 就会有意识地向右侧偏几毫米,再看靶子上的弹着点,如此反复几次,Bob 就会掌握这支步枪的脾气了。下图显示了 Bob 的 5 次试枪过程:

神经网络中反向传播与梯度下降的基本概念

在这个例子中:

  • 每次试枪弹着点和靶心之间的差距就叫做误差,可以用一个误差函数来表示,比如差距的绝对值,如图中的红色线。
  • 一共试枪 5 次,就是迭代/训练了 5 次的过程 。
  • 每次试枪后,把靶子拉回来看弹着点,然后调整下一次的射击角度的过程,叫做反向传播。注意,把靶子拉回来看和跑到靶子前面去看有本质的区别,后者容易有生命危险,因为还有别的射击者。一个不恰当的比喻是,在数学概念中,人跑到靶子前面去看,叫做正向微分;把靶子拉回来看,叫做反向微分。
  • 每次调整角度的数值和方向,叫做梯度。比如向右侧调整 1 毫米,或者向左下方调整 2 毫米。如图中的绿色矢量线。

上图是每次单发点射,所以每次训练样本的个数是 1。在实际的神经网络训练中,通常需要多个样本,做批量训练,以避免单个样本本身采样时带来的误差。在本例中,多个样本可以描述为连发射击,假设一次可以连打 3 发子弹,每次的离散程度都类似,如下图所示:

神经网络中反向传播与梯度下降的基本概念

  • 如果每次 3 发子弹连发,这 3 发子弹的弹着点和靶心之间的差距之和再除以 3,叫做损失,可以用损失函数来表示。

其实损失就是所有样本的误差的总和,所以有时候损失函数可以和误差函数混用概念。

其实射击还不这么简单,如果是远距离狙击,还要考虑空气阻力和风速,在神经网络里,空气阻力和风速可以对应到隐藏层的概念上。

用数学概念理解反向传播

我们再用一个纯数学的例子来说明反向传播的概念。

假设我们有一个函数 /(z = x * y,其中: x = w * 2 + b, y = b + 1,即: z = (w * 2 + b) * (b + 1)/)

关系如下图:

神经网络中反向传播与梯度下降的基本概念

注意这里 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
所以:

/[/frac{/partial{z}}{/partial{b}}=/frac{/partial{z}}{/partial{x}}*/frac{/partial{x}}{/partial{b}}+/frac{/partial{z}}{/partial{y}}*/frac{/partial{y}}{/partial{b}}=5*1+10*1=15/]

其中:

/[/frac{/partial{z}}{/partial{x}}=/frac{/partial{}}{/partial{x}}(x*y)=y=5/]
/[/frac{/partial{z}}{/partial{y}}=/frac{/partial{}}{/partial{y}}(x*y)=x=10/]
/[/frac{/partial{x}}{/partial{b}}=/frac{/partial{}}{/partial{b}}(w*2+b)=1/]
/[/frac{/partial{y}}{/partial{b}}=/frac{/partial{}}{/partial{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 的贡献比较大,这个从

/[/frac{/partial{z}}{/partial{x}}=/frac{/partial{}}{/partial{x}}(x*y)=5 < /frac{/partial{z}}{/partial{y}}=/frac{/partial{}}{/partial{y}}(x*y)=10/]

和这两个值的比较来看也可以证明。而△x 和△y 就可以理解为梯度值。

同理,我们也可以得到图中各变量对 w 的偏导值:

神经网络中反向传播与梯度下降的基本概念

从以上两图可以看出,反向微分保留了所有变量(包括中间变量)对结果 z 的影响。若 z 为误差函数,则对图进行一次计算,可以得到所有节点对 z 的影响,即梯度值,下一步就可以利用这些梯度值来更新 w 和 b 的权重。

w 的变化和 b 的变化,哪一个对 z 的变化贡献大?从图中还可以注意到:

/[/frac{/partial{z}}{/partial{b}}=15/]
/[/frac{/partial{z}}{/partial{w}}=10/]

所以每次 w 和 b 的变化值是不相同的,b 的变化会比 w 大一些,也就是每一步的跨度大一些,这个是与 z = xy = (w2+b)*(b+1)这个算式相关的,并不代表神经网络中实际情况。

反向传播的实际计算过程(单变量)

还是用上面的例子,目前:

  • /(w = 3/)
  • /(b=4/)
  • /(x = w*2+b = 10/)
  • /(y = b+1 = 5/)
  • /(z = x*y=50/)

假设我们最终的目的想让 z = 60,只改变 b 的值,如何实现?
答案就是偏导数:

/[/frac{/partial{z}}{/partial{b}}=/frac{/Delta{z}}{/Delta{b}}=15/]

目前 z=50, 距离 60 相差 10,所以我们令/(/Delta{z}=60-50=10/),则:

/[ /frac{/Delta{z}}{/Delta{b}}=15=/frac{10}{/Delta{b}} // /]

所以:

/[/Delta{b} = 0.66667/]

再带入式子中(顺便说一句,下面这个计算过程就叫做前向计算

  • /(w = 3/)
  • /(b=4+0.66667=4.66667/)
  • /(x = w*2+b = 10.66667/)
  • /(y = b+1 = 5.66667/)
  • /(z = x*y=10.66667*5.66667=60.4445/)

一下子超过 60 了,咋办?再来一次(下面的过程就叫做反向传播):

我们令/(/Delta{z}=60-60.4445=-0.4445/),则:

/[ /frac{/Delta{z}}{/Delta{b}}=15=/frac{-0.4445}{/Delta{b}} // /]

所以:

/[/Delta{b} = -0.02963/]

再带入式子中:

  • /(w = 3/)
  • /(b=4.666667-0.02963=4.63704/)
  • /(x = w*2+b = 10.63704/)
  • /(y = b+1 = 5.63704/)
  • /(z = x*y =10.63704*5.63704=59.96/)

咦哈!十分接近 59.96 了!再迭代几次,应该可以近似等于 60 了,直到误差不大于 0.00001 时,我们就可以结束迭代了,对于计算机来说,这些运算的执行速度很快。

有的同学会说了:这个问题不是用数学公式倒推求解一个二次方程,就能直接得到准确的 b 值吗?是的!但是我们是要说明机器学习的方法,机器并不会解二次方程,而且很多时候不是用二次方程就能解决实际问题的。而上例所示,是用机器所擅长的迭代计算的方法来不断逼近真实解,这就是机器学习的真谛!而且这种方法是普遍适用的。

用二维平面函数说明梯度下降原理

很多资料中会用下面这个图来说明梯度下降,但是都没有说清楚以下几个问题:

1) 为啥用这个看上去像/(y = x^2/)族的函数来说明梯度下降?
2) 在最低点的左侧,梯度值是负数;在最低点的右侧,梯度值是正数。为什么说是“下降”?
3) 为什么 1—>2,2—>3 等等的连线不是这条曲线的切线呢,而好像是弦线?

神经网络中反向传播与梯度下降的基本概念

为何用/(y = x^2/)函数?

这是因为有一种损失函数的形式就是均方差,亦即:

/[loss = /sum_{i}(a_i – y_i) ^ 2/]

其中 a 是本次迭代的预测结果,y 是样本中的真实结果。我们的目的就是在这个函数上求最小值,使 loss 最小,这样样本值和预测值就会非常非常接近,以便于我们以后预测不在样本中的真实数据。

为什么说是“梯度下降”?

“梯度下降”,刚接触这个词时,我总是往“降低难度”或“降低维度”方面去理解,因为有个“下降”的动词在里面。而实际上,“下降”在这里面的含义是“与导数相反的方向”的意思。

我们假设上面这个图形的函数是/(y = (x-1)^2+0.001/),则/(y’_x = 2(x-1)/)

  • 在点 B 上,这个函数的切线(绿色)是指向下方的(Y 轴方向),所以是个负数:假设/(X_B/) = 0.1, 则/(y’ = 2*(0.1-1) = -1.8/)
  • 在 F 点上,切线(绿色)向上:假设/(X_F/) = 1.5, 则/(y’ = 2*(1.5-1) = 1/),是个正数。

而在标准的权重更新公式里:

/[w = w – η*/Delta{w}/]
/[b = b – η*/Delta{b}/]

可以看到无论是 w 还是 b,都是用上一次的权重值减去步长/(/times/)梯度。

  • 当梯度(y’)是正数时,即点 F 的位置,/(x = x – η*1/),切线向上,x 值会变小,权重值会从右侧向 x=1 靠近;
  • 当梯度(y’)是负数时,亦即点 B 的位置,切线向下,x 值会变大/(x = x – η*(-1.8) = x + η*1.8/),最终运算结果变成了加法,与切线方向相反,权重值会从左侧向 x=1 靠近。

所以总体上看,无论 x 在极值的左侧还是右侧,都会向中间(坡底)靠拢,确实是“下降”了。

不知不觉中,我们已经接触到了第一个神经网络中的超参η,即步长值,这个值对于神经网络训练非常重要,决定了训练时间的长短。

曲线和弦线的关系?

神经网络中反向传播与梯度下降的基本概念

  1. 我们先知道了 A 点的切线的方向,亦即黄色的线,但是不知道长度
  2. 我们有步长值η,以及梯度下降公式/(X_1 = X_0 – η * dx/)
  3. 因为/(y'_x 的导数 dx = 2(X-1), η = 0.1, X_0 = 0.2, 于是有 X_1 = X_0–0.1*2(X_0-1) = 0.36/),这就等同于我们知道了切线的长度,亦即绿色的线的长度和方向都确定了
  4. 然后我们可以画出红色的线(亦即弦线)

所以,弦线在这里面没啥用途,只是表示一个迭代跳跃的动作而已。实际的变化值已经由绿色的线定义好了。

【注:本文源自网络文章资源,由站长整理发布】

参考资料


web 前端中文站 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:神经网络中反向传播与梯度下降的基本概念
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址