介绍
反向传播是使训练深度模型在计算上易于处理的关键算法。对于现代神经网络,相对于天真的实现,它可以使梯度下降训练的速度提高一千万倍。这是一个模型需要一周的培训和20万年的差异。
除了在深度学习中的应用之外,反向传播是许多其他领域的强大计算工具,从天气预报到分析数值稳定性 - 它只是用不同的名称。实际上,该算法在不同领域至少被重新发明了几十次。一般的,独立于应用程序,名称是“反向模式区分”。
从根本上说,它是一种快速计算衍生品的技术。这是一个必不可少的技巧,不仅在深度学习中,而且在各种数值计算环境中。
计算图
计算图是思考数学表达式的好方法。例如,考虑表达式e=(a+b)(b+1)e=(a+b)(b+1)。有三个操作:两个加法和一个乘法。为了帮助我们谈论这个,让我们介绍两个中间变量,cC和dd这样每个函数的输出都有一个变量。我们现在有:
c = a + b
d= b + 1
e = c * d
为了创建计算图,我们将这些操作以及输入变量中的每一个都放入节点中。当一个节点的值是另一个节点的输入时,箭头从一个节点到另一个节点。
这些类型的图表一直出现在计算机科学中,特别是在谈论功能程序时。它们与依赖图和调用图的概念密切相关。它们也是流行的深度学习框架Theano背后的核心抽象。
我们可以通过将输入变量设置为特定值并通过图形向上计算节点来评估表达式。例如,让我们设置a=2一个=2和b=1b=1:
image表达式的计算结果为66。
计算图的导数
如果想要理解计算图中的导数,关键是理解边缘上的导数。如果一个一个直接影响cC,那么我们想知道它是如何影响c的C。如果一个一个改变了一点,c怎么样C更改?我们称之为偏导数的C ^C关于a一个。
要评估此图中的偏导数,我们需要求和规则和产品规则:
下面,图表标记了每条边上的导数。
如果我们想了解非直接连接的节点如何相互影响,该怎么办?让我们考虑一下e是受一一个。如果我们改变了一个速度为1,cC也改变在的速度11。反过来,cC在的变速11导致eË以2的速度改变2。所以e以12的速率变化12关于a一个。
一般规则是将从一个节点到另一个节点的所有可能路径相加,将路径的每个边缘上的导数相乘。例如,获得e的衍生物Ë关于bb 我们得到:
这解释了b如何影响e到c以及它如何通过d影响它。
这种一般的“路径总和”规则只是思考多变量链规则的另一种方式。
保理路径
仅仅“对路径求和”的问题在于,很容易在可能路径的数量上发生组合爆炸。
image在上图中,X有三条路径X到Y.,以及Y的另外三条路径到Z。如果我们想得到导数通过对所有路径求和,我们需要求和3*3=9路径:
上面只有九条路径,但随着图形变得更复杂,路径的数量会呈指数增长。
不要只是天真地对路径求和,而是将它们考虑起来要好得多:
这就是“前向模式区分”和“反向模式区分”的用武之地。它们是通过分解路径来有效计算总和的算法。它们不是明确地对所有路径求和,而是通过在每个节点处将路径合并在一起来更有效地计算相同的和。实际上,两种算法都只触摸每个边缘一次!
前向模式区分从图形的输入开始并向末尾移动。在每个节点处,它对所有进入的路径求和。每个路径代表输入影响该节点的一种方式。通过将它们相加,我们得到节点受输入影响的总方式,它是导数。
image虽然您可能没有从图形方面考虑它,但是前向模式区分与您在介绍微积分类时隐含学习要做的非常类似。
另一方面,反向模式区分从图形的输出开始并向开始移动。在每个节点处,它合并源自该节点的所有路径。
图片.png
前向模式区分跟踪一个输入如何影响每个节点。反向模式区分跟踪每个节点如何影响一个输出。也就是说,前向模式区分应用运算符对于每个节点,反向模式区分应用运算符到每个节点。
计算胜利
此时,您可能想知道为什么有人会关心逆模式区分。它看起来像是一种与前进模式做同样事情的奇怪方式。有一些优势吗?
让我们再考虑一下我们原来的例子:
image我们可以使用b的前向模式区分b起来。这给了我们关于b的每个节点的导数b。
我们计算了 图片.png
当我说反向模式区分为我们提供了关于每个节点的e的导数时,我的确意味着每个节点。我们得到两个 和 e的衍生物e关于两个输入。前向模式微分给出了我们输出相对于单个输入的导数,但是反向模式微分给了我们所有这些。
对于此图表,这只是两倍加速的因素,但想象一下具有一百万个输入和一个输出的功能。前向模式的区分需要我们通过图表一百万次来获得衍生物。逆向模式差异化可以一举得到它们!加速百万分之一是非常好的!
在训练神经网络时,我们考虑成本(描述神经网络执行有多糟糕的值)作为参数的函数(描述网络行为的数字)。我们想要计算所有参数的成本导数,用于梯度下降。现在,神经网络中通常有数百万甚至数千万个参数。因此,在神经网络环境中称为反向传播的反向模式差异给我们带来了巨大的加速!
(在任何情况下,前向模式区分更有意义吗?是的,有!反向模式给出了一个输出相对于所有输入的导数,前向模式给出了所有输出相对于一个输入。如果一个具有大量输出的功能,前向模式区分可以更快,更快。)
这不是微不足道的吗?
当我第一次明白反向传播是什么时,我的反应是:“哦,那只是连锁规则!我们怎么花这么长时间才弄明白?“我不是唯一一个有这种反应的人。确实,如果你问“有没有一种聪明的方法来计算前馈神经网络中的导数?”答案并不那么困难。
但我认为这比看起来要困难得多。你看,在反传播发明的时候,人们并没有把注意力集中在我们研究的前馈神经网络上。衍生品是培养它们的正确方法,这一点也不明显。一旦你意识到你可以快速计算衍生品,这些只是显而易见的 存在循环依赖。
更糟糕的是,在随意的思想中,将任何循环依赖关系都写下来是很容易的。用衍生物训练神经网络?当然,你只是陷入局部极小。显然,计算所有这些衍生物会很昂贵。这只是因为我们知道这种方法有效,我们不会立即开始列出它可能没有的原因。
这是后见之明的好处。一旦你构思了问题,最艰难的工作就已经完成了。
结论
衍生品比你想象的要便宜。这是从这篇文章中拿走的主要教训。事实上,它们的价格非常便宜,而我们愚蠢的人类不得不反复重新发现这一事实。在深度学习中要理解这一点很重要。在其他领域中了解它也是一件非常有用的事情,如果不是常识,那就更是如此。
还有其他课程吗?我觉得有。
反向传播也是理解衍生物如何流经模型的有用透镜。这对于推理某些模型难以优化的原因非常有用。这方面的典型例子是递归神经网络中逐渐消失的梯度问题。
最后,我声称有一个广泛的算法课程可以从这些技术中剔除。反向传播和前向模式区分使用一对强大的技巧(线性化和动态编程)来比计算可能的更有效地计算导数。如果您真的了解这些技术,您可以使用它们来有效地计算涉及衍生物的其他几个有趣的表达式。
翻译自克里斯托弗奥拉博客
网友评论