王小新 编译自 Medium
量子位 出品 | 公众号 QbitAI
当前,训练机器学习模型的唯一方式是反向传播算法。
深度学习框架越来越容易上手,训练一个模型也只需简单几行代码。但是,在机器学习面试中,也会考量面试者对机器学习原理的掌握程度。反向传播问题经常出现,不少人碰到时仍觉得十分棘手。
最近,Medium上的一位机器学习初学者Ryan Gotesman,在学习吴恩达老师广受欢迎的Machine Learning课程时,遇到一些困难。
Ryan眼中的学习过程是这样的:线性回归,检查,逻辑回归,检查,梯度下降,检查,检查,再检查……
接着,Ryan又学习了神经网络和模型训练的相应算法,即反向传播。尽管吴老师花了很多时间来解释它,但他还是无法理解这个技术的原理。
吴老师也在视频中提到了,即使没有深入理解这个算法,也可以在神经网络中使用它,而且他也这么做了很多年,但是Ryan想找资料来更好地理解这个概念。
因此,Ryan找到了Geoffrey Hinton等人在1986年发表在Nature上的关于反向传播原始论文“Learning representations by back-propagating errors”,这篇论文到现在已经有近15000次引用。
论文地址:
http://www.iro.umontreal.ca/~pift6266/A06/refs/backprop_old.pdf
这篇文章十分值得认真阅读,且只有短短的四页。Ryan在详细研读后,对反向传播有了新的认识并做了一些笔记。
量子位搬运过来帮助大家更好地理解反向传播,以下为他博客的译文:
反向传播的本质只是对链式法则的巧妙运用。
链式法则是在本科课程中导数的一个基本属性。它指出,假设有三个函数f、g和h,其中f是g的函数,g是h的函数,那么f相对于h的导数等于f相对于g的导数和g相对于h的导数的乘积,用公式表示如下:
链式法则
我们要用这个法则来解释反向传播的工作原理。
下面,我们使用最简单的神经网络来说明。这个网络只有3层,分别是蓝色的输入层、绿色的隐藏层和红色的输出层。上一层中的每个单元都连接到下一层中的每个单元,而且每个连接都具有一个权重,当某个单元向另一个单元传递信息时,会乘以该连接的权重得到更新信息。某个单元会把连接到它的上一层所有单元的输入值相加,并对这个总和执行Logistic函数并向下一层网络传递该值。
三层神经网络,单元数分别为3、4和3
假设给了m个训练样本,第i个输入输出对表示为:
其中,x和y是3维向量。对于输入x,我们把g称作神经网络的预测(输出)值,它也是一个3维向量,每个向量元素对应一个输出单元。所以,对于每个训练样本来说,有:
网络中输入值、输出值和预测值的向量形式
给定输入x,我们要找到使得预测值g与输出值y相等或比较相近的一组网络权重。因此,我们加入了误差函数,定义如下:
神经网络的误差函数
为了计算总误差,我们使用了训练集中的所有样本,并对红色输出层中的每个单元计算该单元预测值与真实输出间的平方误差。对每个样本分别计算并求和,得到总误差。
由于g为网络的预测值,取决于网络的权重,可以看到总误差会随权重变化而变化,网络的训练目标就是找到一组误差最小的权重。
我们可以使用梯度下降来做到这一点,但梯度下降方法要求算出总误差E对每个权重的导数,这也是结合反向传播要实现的目标。
现在,我们推广到一般情况,而不是之前的3个输出单元。假设输出层有任意数量的输出单元,设为n,对于这种情况此时的总误差为:
计算误差
这里为了简洁,删去了上标i,因为它是不变的。
大家可能有个疑问,这个误差值是怎么随着某个输出单元的预测值变化而变化的?导数在这里起了作用:
总误差相对每个输出单元的导数,这里使用链式法则得到平方项的导数
我们还可以发现,随着输出单元预测值的变化,该误差会根据预测值与真值间的差值,以同样速率在变化。
这里你可能还有疑问,当某个输出单元的总输入变化时,误差会如何变化。这里只使用了导数。用z来代表某个输出单元的总输入,求出下面公式的值:
误差E相对于第j个输出单元总输入的导数
但是,g是关于z的函数,应用链式法则,把它重写为:
应用链式法则后的公式
要记住,在每个单元中,先使用Logistic函数处理输入后再把它向前传递。这意味着,g作为Logistic函数,z是它的输入,所以可以表示为:
Logistic函数及其导数
进而得到:
总误差相对于第j个输出单元总输入的导数
这里已经计算出,总误差与某个输出单元总输入的变化规律。
现在,我们已经得到误差相对于某个权重的导数,这就是所求的梯度下降法。
设绿色单元的预测值为g’,绿色层中的单元k与红色层(输出层)中的单元j之间的连接权重设为:
绿色层中的单元k与红色层中的单元j之间的连接权重
考虑下图中,黄色输出单元对应的总输入z。为了计算这个总输入,先获得每个绿色单元的输出值,在把其与连接绿色单元和黄色单元的红色箭头权重相乘,并将它们全部相加。
红色箭头表示为获得黄色单元的总输入在节点间添加的连接
进行推广,假如有任意数量的绿色单元,设为n,这个n与上面定义的不同,可以表示为:
从总输入到输出j
所以,我们不仅可以把z看作是自变量为连接权重的函数,也可以看作是自变量为连接单元输出值的函数。
下面轮到链式法则发挥了。
当与输出单元的连接权重变化时,误差该如何变化,这表示为:
总误差相对于输出单元连接权重的导数
上面已经计算出误差相对于输出单元连接权重的导数,这正是梯度下降所需的公式。
但是推导还没有完成,我们仍需要计算误差相对于第一层和第二层连接权重的导数,这里还需要用到链式法则。
接下来,计算误差与第k个绿色单元输出值的变化关系:
总误差相对于绿色层中第k个单元输出值的导数
由于第k个单元有j个连接权重,我们也考虑在内:
总误差相对于绿色层中第k个单元输出值的导数
推导到这里结束,我们得到了总误差相对于某个单元输出值的导数。现在,我们可以忽略红色输出层,把绿色层作为网络的最后一层,并重复上述所有步骤来计算总误差E相对于输入权重的导数。
你会注意到,我们计算出的第一个导数与预测值和真实值之间的“误差”相等。同样地,最终的导数中也是这个误差项与其他项的乘积。
这种算法叫做反向传播,因为我们把这种形式的误差进行反向传播,从最后一层反馈到第一层,并被用来计算误差E相对于网络中每个单元权重的导数。
只要计算出这些导数后,可在梯度下降过程中使用它们来最小化误差E并训练神经网络。
希望这篇文章能让你更好地理解反向传播的工作原理~
— 完 —
“