论文地址:机器学习中的自动微分

    名词:AD-可微编程

    一。介绍
    在计算机程序中计算导数的方法可分为四类:(1)手工求导数并对其进行编码;(2)用有限差分近似进行数值微分;(3)用表达式进行符号微分计算机代数系统中的操作,如Mathematica、Maxima和Maple;和(4)自动微分,也称为算法微分,这是本文的主题。
    传统上,机器学习中的许多方法都需要对导数进行评估,而大多数传统的学习算法都依赖于梯度的计算和目标函数的hessian(Sra等人,2011)。介绍时新的模型,机器学习的研究人员已经花费了相当大的精力在手动推导分析导数,然后将其插入到标准优化中程序,如L-BFGS(Zhu等人,1997)或随机梯度下降(Bottou,1998)。
    手工区分很费时而且容易出错。在其他选择中,数值微分很容易实现,但由于舍入和截断错误,它可能非常不准确(Jerrell,1997);更重要的是,它对梯度的缩放效果很差,ren 认为它不适合机器学习,其中梯度相对于数百万通常需要参数。符号微分法解决了手工方法和数值方法的弱点,但常常导致复杂和神秘的表达式,并受到“表达式膨胀”问题的困扰(Corliss,1988)。此外,手动和符号方法要求将模型定义为闭式表达式,排除或严格限制算法控制流和表达式。
    我们关注强大的第四种技术,自动微分(AD),AD通过替换变量的域来包含导数值,并重新定义算子的语义来按照微分学的链式规则传播导数,从而对给定的计算机程序执行非标准解释。尽管通用AD其他领域有着广泛的应用,但直到最近,它才被机器学习界所低估。1随着深度学习的出现(LeCun等人。2015年;Goodfellow等人,2016年)作为许多机器学习任务和基于快速原型和代码重用的现代工作流在诸如Theano(Bastien等人,2012年)、Torch(Collobert等人,2011年)和TensorFlow(Abadi等人,2016年)等框架中的最新技术,在autograd2(Maclaurin,2016年),Chainer3(Tokui et al.,2015)和PyTorch4(Paszke et al.,2017)引领通用AD走向主流。AD中的“自动”一词可能会引起混淆,导致机器学习实践者在不涉及手动区分的任何方法或工具上贴上“自动区分”的标签,或仅仅贴上“自动区分”的标签,而没有适当注意潜在的机制。我们要强调的是,作为一个技术术语,AD指的是通过价值累积计算衍生品的一系列特定技术在代码执行过程中生成数值求导而不是求导表达式。这使得仅需销和理想渐近效率的一个小常数因子。与在符号微分的句法和语义约束下将代码安排为闭式表达式的工作不同,AD可以应用于变化最小的正则代码,允许分支、循环和递归。由于这种普遍性,AD应用于工业和学术界的计算机模拟,并在工程设计优化(Forth and Evans,2002;Casanova et al.,2002)、计算流体力学(Muller and Cusdin,2005;Thomas et al.,2006;Bischof et al.,2006)、物理建模(Ekstr–om et al.,2010)、最优控制(Walther,2007年),结构自然力学(Haase et al.,2002)、大气科学(Carmichael and Sandu,1997;Charpentier and Ghemires,2000)和计算金融(Bischof et al.,2002;Capriotti,2011)。
    在机器学习中,一种被称为反向传播算法(backpropagation algo  rithm)的AD的专门对应物一直是训练神经网络的支柱,独立研究人员在不同时期对其进行了丰富多彩的改造(Griewank,2012;Schmidhuber,
    2015年)。自从主要通过Rumelhart等人的工作流行以来,它一直是研究和使用最多的训练算法之一。(1986年)。简单地说,反向传播模型在神经网络权值空间中学习为梯度下降,寻找目标函数的极小值。所需的梯度是通过输出处目标值灵敏度的反向传播获得的(图1),利用链式规则计算目标相对于各权重的偏导数。所得到的算法实质上等价于在反向模式AD下,将由目标函数构成的网络评价函数进行变换,这实际上是对反向传播思想的推广。因此,对反向传播的数学基础为掌握AD技术提供了充分的背景。
    本文从机器学习的角度综述了AD的起源、在机器学习中的应用和实现方法。在此过程中,我们也致力于消除一些误解,我们认为这些误解阻碍了机器学习社区对AD的更广泛认识。在第2节中,我们首先解释了AD与数字和符号微分的区别。第三节介绍AD技术以及它的正向和反向积累模式。第4节讨论了衍生工具在机器学习中的作用,并考察了AD相关的案例。第5节介绍了各种实现方法和通用的AD工具,接下来是第6节,我们将讨论未来的发展方向。

    2。什么是AD所不能的
    如果没有适当的介绍,人们可能会认为AD是一种数字或符号分化的类型。可能会出现混淆,因为AD实际上提供了导数的数值(与导数表达式相反),并且它是通过使用符号微分规则来实现的(但是跟踪导数值而不是结果表达式),给它一个两面性,一部分是象征性的,一部分是数字性的(Griewank,2003)。我们首先强调AD与这两种常见的计算衍生工具的技术有什么不同,并且在几个方面优于这两种技术。
    屏幕快照 2020-04-14 下午1.08.23.png
    2.1 AD不是数值微分
    数值微分是使用在某些采样点上评估的原始函数值对导数进行的有限差分近似(Baund and Faires,2001)(图2,右下角)。它的最简单形式是基于导数的极限定义。例如,对于多元函数f:Rn→R,可以近似于梯度∇f=屏幕快照 2020-04-14 下午1.09.50.png 使用 屏幕快照 2020-04-14 下午1.10.32.png

    其中ei是第i个单位向量,h>0是一个小步长。这具有易于实现的优点,但是对于n维的梯度执行f的O(n)评估以及在选择步长h时需要仔细考虑的缺点。
    导数的数值逼近本质上是病态和不稳定的,5除了适用于有限全纯函数集的复变量方法(Fornberg,1981)。这是由于引入了截断和
    屏幕快照 2020-04-14 下午1.11.59.png

    图2:区分数学表达式和计算机代码的方法范围,查看截断的逻辑图(左上角)。符号微分(右中)给出了精确的结果,但需要在 put中以闭合形式表示,并且受到表达式膨胀的影响;数值微分(右下)由于舍入和截断误差而存在精度问题;自动微分(左下角)与符号微分一样精确,只需恒定的开销因子和对控制流的支持。
    屏幕快照 2020-04-14 下午1.13.53.png
    由于计算精度的限制和步长h的选定值而产生的舍入误差。截断误差随着h→0而趋于零。然而,随着h的减小,舍入误差增大并成为主导(图3)。已经开发了各种技术来减少数值微分中的近似误差,例如使用中心差分近似
    屏幕快照 2020-04-14 下午1.15.21.png
    其中一阶误差抵消,并且一个有效地将h中的截断误差从一阶移到二阶。
    对于一维情况,计算前向差(公式1)和中心差(公式2),只需要两次评估。然而,随着维数的增加,在计算函数屏幕快照 2020-04-14 下午1.16.25.png的Jacobian矩阵时,精度和性能之间面临一个折衷。

    改进数值微分的其他技术,包括高阶有限差分、理查森极限外推(Brezinski和Zaglia,1991)和使用加权和的差分求积方法(Bert和Malik,1996),都增加了计算复杂性,不能完全消除近似误差,并且仍然非常容易受到浮点截断的影响。
    n维梯度的数值微分的O(n)复杂性是其在机器学习中有用性的主要障碍,其中n在最先进的深度学习模型中可能高达数百万或数十亿(Shazeer等人,2017)。相比之下,由于神经网络体系结构的良好的错误恢复能力,在深度学习环境中可以容忍大约的图像错误(Gupta等人,2015)。
    2.2AD不是象征性的区别
    符号微分是通过应用表示微分规则的变换(如
    屏幕快照 2020-04-14 下午1.18.31.png
    当公式被表示为数据结构时,符号化地区分表达式树是一个完美的机械过程,即使在微积分的最初阶段也被认为是机械自动化的(Leibniz,1685)。这是在现代计算机代数系统(如Mathematica、Maxima、Maple)和机器学习框架(如Theano)中实现的。
    在优化中,符号导数可以提供对问题域结构的有价值的见解,并且在某些情况下,可以产生极值的解析解(例如,屏幕快照 2020-04-14 下午1.20.51.png的解),这可以完全消除对导数计算的需要。另外,符号派生不适合于高效的运行时计算导数值,因为它们可以得到比它们所表示的导数表达式大的指数。
    考虑函数h(x)=f(x)g(x)和等式3中的乘法规则。由于h是一个乘积,h(x)将对屏幕快照 2020-04-14 下午1.25.40.png和符号表达式之间出现的任何计算进行嵌套复制有一些共同的成分,即f(x)和g(x)。另请注意,在右侧,f(x)和屏幕快照 2020-04-14 下午1.25.40.png分别显示。如果我们只是用符号来区分f(x)并把它的导数插入适当的位置,我们就可以对f(x)和屏幕快照 2020-04-14 下午1.25.40.png符号表达式之间出现的任何计算进行嵌套式的重复。因此,粗心大意的符号微分很容易产生指数级的大符号表达式,而这些表达式需要相应的时间来计算。这个问题称为表达式膨胀(表1)。
    当我们关心导数的精确数值计算,而不是它们的实际符号形式时,原则上可以通过只在内存中存储中间子表达式的值来显著简化计算。更重要的是,为了进一步提高效率,我们可以尽可能地交错微分和简化步骤。这种交错的思想构成了AD的基础,并提供了一个它最简单的形式是:在基本运算层应用符号微分,并保持中间的数值结果,与主函数的计算保持一致。
    这是一种前向积累模式,我们将在下一节介绍。
    屏幕快照 2020-04-14 下午1.36.14.png

    三。AD及其主要模式
    **
    AD可以被认为是对计算机程序进行非标准解释,这种解释包括用各种导数的计算来增加标准计算。所有的数值计算最终都是一组已知导数的有限元运算的组合(Verma,2000;Griewank和Walther,2008),并结合组成运算的导数通过链式规则给出了整体组成的导数。通常,这些基本运算包括二进制算术运算、一元符号转换和超越函数,如指数、对数和三角函数。
    在表2的左边,我们看到计算y=f(x1,x2)=ln(x1)+x1x2-sin(x2)的表示,作为基本运算的计算轨迹,也称为Wengert列表(Wengert,1964)。我们采用Griewank和Walther(2008)使用的三部分符号,其中函数屏幕快照 2020-04-14 下午6.44.23.png是使用中间变量vi构造的,这样

    • 变量屏幕快照 2020-04-14 下午6.45.23.png是输入变量,

    •变量vi i=1。,l是工作(中间)变量,并且
    •变量屏幕快照 2020-04-14 下午6.46.01.png是输出变量。
    图4显示了用计算图表示的基本操作的给定追溯(Bauer,1974),这在可视化中间变量之间的依赖关系时非常有用。评估追溯是AD技术的基础。这里需要注意的一点是,AD不仅可以区分经典意义上的闭式表达式,
    屏幕快照 2020-04-14 下午6.48.21.png
    用控制流(如分支、循环、递归和过程调用)的算法,使其比严重限制这种表示性的符号微分具有重要优势。这要归功于这样一个事实:任何数字代码最终都会产生一个带有输入、中间和输出变量的特定值的数值计算跟踪,这是使用
    链规则组合,而不考虑在执行期间采用的特定控制流路径。另一种表达方式是,AD对任何操作都是盲的,包括控制流语句,这些语句不会直接改变数值。

    3.1前向模式
    前向累积模式中的AD是概念上最简单的类型。考虑函数f(x1,x2)=ln(x1)+x1x2-sin(x2)的计算轨迹,在表2的左侧给出,在图4中以图形形式给出。为了计算f相对于x1的导数,我们首先将每个中间变量vi a导数关联起来
    屏幕快照 2020-04-14 下午6.50.10.png
    将链式规则应用于前向原始迹中的每个基本运算,生成相应的切线(导数)迹,如表2右侧所示。用原函数的切线来计算原函数vi,得到最终变量所需的导数屏幕快照 2020-04-14 下午6.50.36.png
    这自然地推广了用n个独立(输入)变量Xi和m计算Jacobian函数f:屏幕快照 2020-04-14 下午6.44.23.png。独立(输入)变量席和M依赖(输出)变量YJ。在这种情况下,通过仅设置一个变量˙xi=1并将其余变量设置为0(换句话说,设置x)来初始化AD的每个前向传递x=ei,其中ei是第i个单位向量)。使用特定输入值x=A运行代码,然后计算
    屏幕快照 2020-04-14 下午6.56.50.png

    屏幕快照 2020-04-14 下午6.57.37.png
    给我们一列雅可比矩阵
    屏幕快照 2020-04-14 下午6.58.30.png
    在点a处求值。因此,可以在n个求值中计算出完整的雅可比。
    此外,前向模式AD提供了一种非常有效且无矩阵的计算雅可比矢量积的方法
    屏幕快照 2020-04-14 下午6.59.18.png
    只需用xx=r初始化,就可以在一次前向传递中计算出雅可比矢量积。作为特殊情况,当屏幕快照 2020-04-14 下午7.01.07.png,我们可以得到沿给定向量R的方向导数,作为偏导数的线性组合
    屏幕快照 2020-04-14 下午7.01.15.png
    通过使用值x==r开始AD计算。对于函数屏幕快照 2020-04-14 下午7.01.07.png,前向模式AD是有效和直接的.导数屏幕快照 2020-04-14 下午7.01.31.png只需一次前向传递即可计算。相反,在另一个屏幕快照 2020-04-14 下午7.01.07.png前进模式AD需要n个计算值来计算梯度
    屏幕快照 2020-04-14 下午7.01.41.png
    它也对应于一个1×n的雅可比矩阵,该矩阵在n个求值中与前向模式一次建立一列。一般来说,对于屏幕快照 2020-04-14 下午7.01.07.png的情况m其中n≫m,通常首选不同的技术。我们将在第3.2节中描述反向累积模式下的AD。

    3.1.1双重编号
    从数学上讲,前向模AD(由表2中的左右两边表示)可以看作是使用对偶数来计算函数,可以定义为形式的截断泰勒级数
    屏幕快照 2020-04-14 下午7.08.53.png
    其中v,v˙∈R和ǫ是幂零数,使得ǫ2=0和ǫ6=0。例如,请注意
    屏幕快照 2020-04-14 下午7.10.37.png
    其中ǫ的系数方便地反映符号微分规则(例如,等式3)。
    我们可以通过建立一个
    屏幕快照 2020-04-14 下午7.11.18.png
    以及使用对偶数作为数据结构来携带正切值和原始值。链式规则在这个表示上的工作与预期一样:Eq.5的两个应用给出了
    屏幕快照 2020-04-14 下午7.12.09.png

    右边的系数ǫ正好是f和g的组成的导数。这意味着,由于我们实现了关于不变等式5的基本运算,所以它们的所有组成也将这样做。这反过来意味着,我们可以通过将任何非对偶数v解释为v+0ǫ并计算.以这种非标准方式对初始输入的函数,系数为1:
    屏幕快照 2020-04-14 下午7.13.21.png
    这也扩展到任意程序构造,因为作为数据类型的双数,可以包含在任何数据结构中。只要在数据结构中保留一个双数
    没有对它执行任何算术运算,它将保持一个对偶数;并且如果将其从数据结构中取出并再次操作,则差异将继续。
    实际上,用所选编程语言编写的函数f将被输入一个AD工具,然后用相应的额外代码扩充它来处理同时计算函数及其导数的运算。这个可以通过调用特定库以源代码转换的形式实现如果给定的源代码将被自动修改,或者通过运算符重载,使进程对用户透明。我们讨论这些实现技术在第5节。

    3.2反向模式
    反向累积模式12中的AD对应于广义反向传播算法,因为它从给定输出反向传播导数。这是由用伴随词补足每个中间变量vi屏幕快照 2020-04-16 下午5.12.56.png
    表示考虑的输出yj对vi变化的灵敏度. 在反向传播的情况下,y是与错误E相对应的标量(图1)。
    在逆模AD中,在两相过程的第二阶段计算导数。在第一阶段,原始函数代码被向前运行,填充中间变量vi和通过书本记录计算图中的依赖关系保存程序。在第二阶段,导数vi是通过传播伴随点来计算的相反,从输出到输入。
    回到例子y=f(x1,x2)=ln(x1)+x1x2-sin(x2),在表3中,我们看到右边的伴随语句,对应于每个原始元素
    左侧操作。简单地说,我们对计算贡献率感兴趣屏幕快照 2020-04-16 下午5.12.56.png将每个变量vi的变化转化为输出y的变化。取影响v2和v3的v,其对y变化的贡献如下
    屏幕快照 2020-04-16 下午5.19.29.png
    在表3中,这个贡献是按两个增量步骤计算的
    屏幕快照 2020-04-16 下午5.20.19.png
    与这些表达式源于的前向跟踪中的行对齐。
    在左手边的前向传播之后,我们在右手边的邻接处进行反向传播,从屏幕快照 2020-04-16 下午5.20.52.png最终我们得到了导数屏幕快照 2020-04-16 下午5.21.04.png通过一次反向传播。
    一开始,AD会显得有些“神秘”(丹尼斯和施纳贝尔,1996)。格里万克和沃尔特(2008)辩称,这部分是因为大家都知道链式法则是一种将导数向前传播的机械过程。
    反向模式的一个重要优点是,对于具有大量输入数。在屏幕快照 2020-04-16 下午5.21.18.png的极端情况下,只有一个逆模应用足以计算全梯度屏幕快照 2020-04-16 下午5.21.28.png,与填充前向模式所需的n个过程相比。因为机器学习实践主要涉及标量值目标相对于大量参数的梯度,这建立了反向模式,而不是正向模式,作为反向传播算法形式的主要技术。
    屏幕快照 2020-04-16 下午5.27.15.png

    一般来说,对于函数屏幕快照 2020-04-16 下午5.21.18.png,如果我们表示要计算的操作计数ops(f)的原始函数,用前向模式计算m×n Jacobian所需的时间是n c ops(f),而在m c ops(f)中,同样的计算可以通过反向模式进行,其中c是保证c<6的常数,通常是c∼[2,3](Griewank and Walther,2008)。也就是说,反向模式AD运行的更好当m≪n.。
    与正向模式雅可比矢量积的无矩阵计算(式4)类似,反向模式可用于计算转置雅可比矢量积
    屏幕快照 2020-04-16 下午5.29.54.png
    用初始化反向相位y =r。
    然而,反向模式AD的优点在于存储容量的增加需求增长(在最坏的情况下)与评估的功能。提高使用检查点策略和数据流等高级方法实现分析(Dauvergne和Hasco–et,2006;Siskind和Pearlmutter,2017)。

    3.3AD和反向传播的起源
    AD背后的思想可以追溯到20世纪50年代(Nolan,1953;Beda等人,1959)。正演模式AD作为评价偏导数的一般方法,基本上是由Wengert(1964)发现的。随后是一段相对较低的活动期,直到1980年代主要通过Griewank(1989年)的工作恢复了对这一领域的兴趣,同时也得到了现代编程语言的改进和高效反向模式AD可行性的支持。
    反向模式AD和反向传播有着错综复杂的历史。在连续时间形式主义中,反向模式的本质是庞特里亚金最大值原理(Rozoner,1959;Boltyanskii等人,1960)。这种方法在控制理论界(Bryson和Denham,1962;Bryson和Ho,1969)中得到了理解,并用更为正式的术语对离散时间变量进行了形式化的转换,这些变量按照依赖关系进行了拓扑排序Werbos(1974年)。在Werbos之前,linnainma(1970,1976)的工作经常被引用为第一次出版的反向模式描述。Speelpenning(1980)随后引入了我们所知的反向模式AD,在某种意义上,他给出了第一个实现
    它实际上是自动的,接受用通用编程语言编写的计算过程规范,并自动执行相反的模式转变。
    顺便说一句,Hecht Nielsen(1989)引用了Bryson和Ho(1969)以及Werbos(1974)的工作作为已知的两个最早的反向传播实例。在机器学习社区中,这种方法已经被重新发明了好几次,例如帕克(1985),直到它最终被鲁梅尔哈特等人(Rumelhart et al.)成名。(1986)和并行分布式处理(PDP)组。Parker小组在自己的发现;同样地,直到帕克发现了维尔博斯的作品,他才被欣赏(赫赫特·尼尔森,1989)。这告诉我们一个有趣的故事,两个高度互联的研究社区在这个基础时期也设法保持了独立。

    我们建议读者参考Rall(2006)对AD的发展进行全面的回顾。强烈建议感兴趣的读者阅读Griewank(2012)以调查反向模式的起源,并阅读Schmidhuber(2015)以进行反向传播。

    四。可微编程与机器学习
    在接下来的文章中,我们考察了衍生工具在机器学习中的主要用途,并报告了一系列的作品,其中通用AD,而不仅仅是反向传播,已经成功地应用于机器学习环境中。AD使用的领域包括优化、神经网络、计算机视觉、自然语言处理和概率推理。

    4.1基于梯度的优化
    基于梯度的优化是机器学习的支柱之一(Bottou等人,2016),一个目标函数屏幕快照 2020-04-16 下午5.21.18.png经典梯度下降的目标是通过更新形式屏幕快照 2020-04-16 下午8.13.26.png来找到(局部)最小值,其中η>0是屏幕快照 2020-04-16 下午8.13.36.png步长。基于梯度的方法利用了f降低最陡if的事实。

    表4:亥姆霍兹自由能函数及其梯度的计算次数(图5)。时间是相对于原始函数给出的,其中(1)n=1和(2)n都对应于每列。(例如,n=43的反向模式AD需要大约两倍于n=43的原始函数的计算时间。)通过使用DiffSharp 0.5.7在Intel Core i7-4785T 2.20 GHz CPU和16 GB RAM的计算机上平均运行1000次来测量次数。n=1的原始函数的计算时间为0.0023ms。
    屏幕快照 2020-04-16 下午8.18.18.png

    一个沿着负梯度的方向。基于梯度的方法的收敛速度通常通过在每次迭代时调整步长η的自适应步长技术来提高(Duchi等人,2011;Schaul等人,2013;Kingma和Ba,2015)。如我们所见,对于大n,反向模式AD提供了一种高效的梯度计算方法。13图5和表4展示了梯度计算的规模对于正向和反向模式AD和数值微分,不同的是,查看用于基准gra-dient计算的AD文献中使用的亥姆霍兹自由能函数(Griewank,1989;Griewank and Walther,2008;Griewank et al.,2012)。基于牛顿法的二阶方法利用了梯度f和Hessian-Hf,通过更新屏幕快照 2020-04-16 下午8.19.14.png的形式进行工作-1显著加快收敛速度(Press等人,2007)。AD提供了一种自动计算精确Hessian的方法,使通用实现简洁方便。14牛顿法收敛于较少的迭代次数,但这需要在每次迭代中计算Hf。在大规模问题中,Hessian通常被一个数值近似所代替,该近似使用梯度计算的一阶更新,
    屏幕快照 2020-04-16 下午8.20.58.png

    图5:基于彭-罗宾逊状态方程的混合流体的亥姆霍兹自由能函数的计算时间(彭-罗宾逊,1976),屏幕快照 2020-04-16 下午8.22.09.png
    ,其中R是普遍气体常数,T是绝对温度,屏幕快照 2020-04-16 下午8.22.29.png是常数的向量,屏幕快照 2020-04-16 下午8.22.41.png是常数的对称矩阵,x∈Rn是描述系统的自变量向量。图中显示了f和梯度f的计算时间,其中f和梯度f的数值微分(中心差分)、正向模式AD和反向模式AD是变量的数目n。报告的次数与评估有关f的时间n=1。下面的图表使用对数比例作为插图小n的行为。数值结果如表4所示。(代码:http://DiffSharp.github.io/DiffSharp/misc/Benchmarks-h-grad-v0.5.7.fsx

    产生了拟牛顿方法。一种非常流行的方法是BFGS15算法,以及它的有限内存变体L-BFGS(Dennis and Schnabel,1996)。另一方面,在大规模应用中出现的hessian通常是稀疏的。这种稀疏性和对称性很容易被AD技术利用,如计算图消去(Dixon,1991)、部分可分性(Gay,1996)、矩阵着色和压缩(Gebremedhin等人,2009)。
    在许多情况下,不需要完整的Hessian,而只需要一个Hessian矢量积Hv,该Hv可以使用AD的反向正向配置通过应用反转模式来获取由正向模式产生的代码梯度。给定函数屏幕快照 2020-04-16 下午8.28.07.png、评估点x和向量v,可以通过设置xx=v来计算通过正向模式的方向导数f·v,然后对该结果应用反转模式来获得屏幕快照 2020-04-16 下午8.27.54.pngPearlmutter,1994年)。即使H是一个n×n矩阵,也可以用O(n)复杂度计算Hv。健壮的AD工具的可用性可以使更复杂的优化方法适用于大规模机器学习问题。例如,当快速随机Hessian矢量积可用时,这些可作为随机牛顿方法的基础(Agarwal等人,2016),这些方法有可能赋予随机优化二次收敛。另一种提高基于梯度方法收敛速度的方法是使用增益自适应方法,如随机meta-descent(Schraudolph,1999),其中引入随机抽样以避免局部极小值并降低计算复杂度
    计算费用。Vishwanathan等人给出了一个将SMD与AD-Hessian矢量积结合使用的例子。(2006)关于条件随机场(CRF)。类似地,Schraudolph和Graepel(2003)在他们的模型中使用了Hessian矢量积,将共轭梯度技术与随机梯度下降相结合。

    4.2神经网络,深度学习,可微编程
    神经网络的训练是一个关于其权值集的优化问题,原则上可以使用从进化算法(例如,2017)到基于梯度的方法(例如,BFGS(Apostolopoulou等人,2009)或主要随机梯度下降(Bottou,2010年)及其许多变体(Kingma和Ba,2015年;Tieleman和Hinton,2012年;Duchi等人,2011年)。正如我们所看到的,
    反向传播算法只是AD的一个特例:通过将反向模式AD应用于评估网络误差与其权值函数的目标函数,我们可以方便地计算执行权值更新所需的偏导数。LUSH系统(Bottou和LeCun,2002)及其前身SN(Bottou和LeCun,1988),是第一个以高效神经网络模拟为目标,同时结合通用编程语言和AD的生产系统。现代深度学习框架以某种方式提供差异化能力,但其内在机制并不总是很清楚,关于“autodiff”、“automatic differention”和“symbolic differention”等术语的使用也存在很多混乱,这些术语有时甚至可以互换使用。在主流框架中,包括Theano18
    (Bastien等人,2012年)、TensorFlow(Abadi等人,2016年)、Caffe(Jia等人,2014年)和CNTK(Seide和Agarwal,2016年)用户首先使用特定于域的迷你语言将模型构造为计算图,然后在执行过程中由框架进行解释。这种方法的优点是能够优化计算图形结构(例如,在ano中),但其缺点是控制流有限且不直观,并且难以调试。相比之下,autograd(Maclaurin,2016)、Chainer(Tokui et al.,2015)和Pythorch(Paszke et al.,2017)领导的最新框架谱系提供了我们在第3节中概述的类型的真正通用的反向模式AD,
    其中,用户直接使用宿主编程语言将模型定义为正向计算的常规程序。这消除了对解释器的需求,允许任意的控制流语句,并使调试简单直观。
    可微程序设计是另一个新兴术语,指的是认识到深度学习实践实质上相当于为一个问题编写潜在解决方案的程序模板,由函数块组装而成的可微有向图,其参数通过基于梯度的优化从实例中学习。在这种范式中,神经网络只是一类参数化的可微程序,由前馈、卷积和递归元素组成。我们越来越多地看到这些传统的构建块使用控制流自由地组成任意算法结构,以及引入了新的可微结构,如神经图灵机(Graves等人。2014年),一系列控制器-接口抽象(Graves等人,2016年;Zaremba等人,2016年;Joulin和Mikolov,2015年;Sukhbatar等人,2015年),以及数据结构的不同版本,如堆栈、队列、数据包(Grefenstette等人,2015年)。GeneralPurposeAD的可用性通过使这些体系结构的表达式成为依赖于差异化基础设施的正则程序,极大地简化了这些体系结构的实现。虽然
    可微程序设计的深度学习视角是一个新的课题,我们注意到,具有可微功能和作为语言基础设施的可微程序设计,几十年来一直是AD界的主要研究课题,并在很大程度上得到了实现我们将在第5节中看到的系统和语言的范围。
    在神经网络文献中有一些例子,尽管很少有人明确提到用AD来计算误差梯度,例如Eriksson等人。(1998)将AD用于大规模的前馈网络,以及杨等人的工作。2008年,作者使用AD来训练基于神经网络的比例积分微分(PID)控制器。类似地,Rollins(2009)将反向模式AD与神经网络结合用于最优反馈控制问题。另一个例子是Al-Seyab和Cao(2008)提出的连续时间递归神经网络(CTRNN),作者将AD应用于实时预测非线性过程动态行为的连续时间递归神经网络(CTRNN)的训练,并报告与其他方法相比,训练时间显著缩短。

    4.3计算机视觉
    自从克里热夫斯基等人的影响工作。(2012年),计算机视觉一直以深度学习为主,特别是卷积神经网络的变化(LeCun等人,1998年)。这些模型是端到端训练的,这意味着学习从原始输入数据到相应输出的映射,自动发现所需的表示用于称为表示学习的过程中的特征检测(Bengio等人,2013)。
    除了深度学习,AD可应用于计算机视觉问题的一个有趣领域是逆向图形(Horn,1977;Hinton and Ghahramani,1997)-或综合分析(Yildirim等人,2015)-其中视觉被视为场景生成模型参数的推断。在反求图形中使用基于梯度的优化需要通过包括渲染器在内的整个图像合成管道传播导数。Eslami等人。(2016)为此使用数值微分法。Loper和Black(2014)实现了Open-Differentiable Renderer(OpenDR),OpenDR是一种场景渲染器,它还提供图像像素相对于场景参数的导数,并演示它的任务是将人体的关节和可变形的三维模型与来自Kinect设备的图像和范围数据进行拟合。同样,Kulkarni等人。(2015)为描述场景的概率程序中的推理任务实现可微近似渲染器。Srajer等人。(2016)调查AD在计算机视觉和机器学习中的三个任务,即束调整(Triggs等人,1999年)、高斯混合模型拟合和手跟踪(Taylor等人,2014年)中的应用,并为这些任务中的导数计算提供各种AD工具的综合基准。

    Pock等人。(2007)利用AD解决从立体图像对中去噪、分段和信息恢复的问题,并注意到AD在识别大Jacobian矩阵和Hessian矩阵中的稀疏模式方面的有用性。在另一项研究中,Grabner等人。(2008)将反向模式AD用于GPU加速医疗二维/三维注册,这项任务涉及来自不同来源(如X射线图像)的数据对齐或者电脑断层扫描。作者报告,与使用中心差分的数值微分相比,速度提高了6倍(参见我们的Helmholtz函数基准,图5和表4)。
    Barrett和Siskind(2013年)提出了一种使用通用AD进行视频事件检测的方法,该方法使用了隐马尔可夫模型(HMMs)和Dalal和Triggs(2005年)的目标检测器,在一个预先跟踪的视频语料库上进行训练,使用带有反向模式AD的自适应步长梯度下降。最初使用R6RS-AD包实现,该包在方案中提供正向和反向模式AD,生成的梯度代码随后移植到C并高度优化。

    4.4自然语言处理
    自然语言处理(NLP)是应用深度学习技术取得快速进展的领域之一(Goldberg,2016),其应用领域包括机器翻译(Bahdanau等人,2014)、语言建模(Mikolov等人。2010年),依赖分析(Chen和Manning,2014年),和问题回答(Kumar等人,2016年)。除了深度学习方法外,NLP中的统计模型通常使用通用的或专门的基于梯度的方法进行训练,而且大多仍然很昂贵的资源去训练。使用在线或分布式训练算法可以提高训练时间(Gimpel等人,2010)。Finkel等人给出了一个用随机梯度下降法求解非线性规划的例子。(2008)通过目标函数。Yu和Siskind(2013)结合上一节关于视频事件检测的工作,报告了他们在句子跟踪方面的工作,这是一个与计算机视觉相结合的基础语言学习实例,该系统从与描述性句子相结合的短视频剪辑中学习词义。该方法利用HMMs表示视频帧的变化和不同词类的意义。这项工作是在C语言中实现的,并通过ADOL-C工具使用AD计算所需的梯度。

    4.5概率建模与推理
    概率模型中的推理可以是静态的,例如将给定的模型编译成贝叶斯网络,并使用信念传播等算法进行推理;也可以是动态的,多次向前执行模型并计算观察到的统计数据用于推断后验分布的值。马尔可夫链蒙特卡罗(MCMC)(Neal,1993)方法通常用于动态推理,例如基于随机抽样的Metropolis-Hastings算法(Chib和Greenberg,1995)。Meyer等人。(2003)考试利用AD加速MCMC的贝叶斯后验推理,并将其应用于随机波动率。摊余推理(Gershman and Goodman,2014;Stuhlm–uller et al.,2013)基于深度学习的技术(Le et al.,2017;Ritchie et al.,2016)通过训练神经网络在定义为概率程序的生成模型中执行近似推理而工作(Gordon et al.,2014)。

    当模型参数是连续的时,哈密顿或混合蒙特卡罗(HMC)算法通过辅助的“动量变量”模拟哈密顿动力学,提供了改进的收敛特性,避免了随机抽样的缓慢爆炸率(Duane等人,1987)。HMC的优点在于需要对复杂概率模型进行梯度评估。AD在这里非常适合于补充概率建模,因为它免除了用户对每个模型梯度的人工推导。24例如,概率编程Stan语言(Carpenter等人,2016)实现了基于HMC和不掉头取样器(NUTS)的自动贝叶斯推断(Hoffman和Gelman,2014),并使用反向模式AD计算HMC和NUTS的梯度(Carpenter等人,2015)。
    同样,Wingate等人。(2011)演示将AD用作概率程序的非标准解释,从而实现高效的推理算法。Kucukelbir等人。(2017)提出了一种基于AD的变分推理(VI)算法的推导方法。PyMC3(Salvatier等人,2016)允许使用MCMC和VI拟合贝叶斯模型,该模型使用了Theano提供的梯度。Edward(Tran et al.,2016)是一个用于深入概率建模、推理和批评的库(Tran et al.,2017),它支持使用TensorFlow的虚拟仪器。在这方面,通用AD的可用性使新的图书馆成为可能如Pyro25和Probthorch(Siddharth等人,2017年),用于支持递归和控制流的深层通用概率编程,在这两种情况下,都依赖于使用Pythorch的反向模式AD基础设施提供的梯度的VI。
    在处理概率模型时,为了实现模型参数的随机优化,常常需要通过随机变量的抽样操作来反向传播导数。分数函数估计,或称强化(Williams,1992),方法提供了一个普遍适用的无偏梯度估计,尽管具有高方差。当使用连续随机变量时,可以通过简单随机变量的确定和可微变换来替代随机变量,这种方法被称为“重新参数化技巧”(Williams,1992;Kingma and Welling,2014;Rezende et al.,2014)。对于离散变量,REBAR(Tucker等人,2017)方法通过使用连续松弛提供了低方差无偏梯度估计。一个REBAR的泛化称为RELAX(Grathwohl等人,2017年)通过学习由神经网络参数化的自由形式控制变量而工作,适用于离散和连续设置。

    5实现
    了解实现AD的不同方法是有用的。在这里,我们将介绍主要的实施策略,并对现有的工具进行概述。
    任何AD实现中的一个主要考虑因素是由AD算法和簿记引入的性能开销。在计算复杂度方面,AD保证运算量的增加不超过一个小的常数因子(Griewank和Walther,2008)。另一方面,管理这个算法可以引入。如果不小心的话,会有很大的开销。例如,天真地分配数据结构以保存双数将涉及到对每一个算术运算的内存访问和分配,这通常比现代计算机上的算术运算更昂贵。同样,使用运算符重载可能会引入具有伴随成本的方法调度,这,与原函数的原始数值计算相比,可以方便地求出一个数量级的减速。另一个主要的问题是有可能碰到一类叫做“扰动混淆”的错误
    (Siskind和Pearlmutter,2005年;Manzyuk等人,2012年)。这本质上意味着,如果两个正在进行的差异影响到同一段代码,那么它们引入的两个形式epsilon(第3.1.1节)需要保持不同。很容易有虫子特别是在以性能为导向的AD实现中,以各种方式混淆了这些。当AD被嵌套时,也会出现这种情况,即,对内部计算导数的函数计算导数。
    把数学翻译成计算机代码通常需要注意数字问题。例如,数学表达式屏幕快照 2020-04-17 下午5.51.42.png不应该是自然翻译,而是用log1p(x)、hypot(x、hypot(y、z))和atan2(y、x)表示。在机器学习中,最突出的例子可能是所谓的log和Exp技巧,以提高表格log pi Exp席的计算的数值。AD不能不考虑这些数字因素。例如 代码计算E=屏幕快照 2020-04-17 下午5.51.56.png由可微编程处理,将计算屏幕快照 2020-04-17 下午5.52.08.png 如果系统正在寻求E的局部最小值,则屏幕快照 2020-04-17 下午5.52.19.png自然地加上一组和接近于零的大数,在数值上是很麻烦的。这就是说AD对浮点运算的危险,有时会引入原始计算中不存在的数值问题。数值分析的问题超出了我们目前的范围,但是有一篇关于AD数值的可靠文献(例如Griewank等人。(2012年)包括使用子梯度以允许在目标不可微的情况下进行优化,适当的子梯度和近似函数,如|.·k·k2和√··接近零,以及大量相关问题。
    对近似函数和AD也应谨慎(Sirkes和Tziperman,1997)。在这种情况下,如果有一个近似理想函数的过程,AD总是给出实际编程的程序的导数,它可能不是程序所逼近的理想函数的导数的良好逼近。
    例如,考虑由分段有理逼近例程执行ex。在这个程序中使用AD将产生一个近似的导数,在这个导数中,每个部分的公式将被区分。即使这仍然是ex 的导数会得到不同的求导,我们知道屏幕快照 2020-04-17 下午5.59.01.png而原始的近似本身已经是对ex的导数更好的近似。因而AD实施的用户必须谨慎地估计导数,而不是区分近似值。这会要求显式地近似已知的导数,在数学函数只能近似计算但具有定义良好的数学导数的情况下。我们注意到机器学习工作负载与传统AD文献中研究的工作负载既有相似之处,也有不同之处(Baydin等人,2016b)。深度学习系统通常是计算界的,并且在矩阵运算的高度优化数值核中花费相当多的计算时间(Hadjis等人。2015年;Chetlur等人,2014年)。这是一种可以被证明对基于操作员重载的高级操作的AD实现是可行的情况,这在当前的机器学习框架中是常见的。相比之下,传统的AD应用程序中的数值模拟工作负载可能是带宽受限的,这使得源代码转换和编译器优化方法更加相关。另一个值得注意的区别是,尽管在AD的传统应用领域中需要高的数值精度,但是作为计算流体力学(Cohen and Molemaker,2009),由于神经网络的误差弹性,在深度学习中,较低的精度在提高计算效率方面是足够的,甚至是可取的(Gupta et al.,2015;Courbariaux et al.,2015)。

    在最近的文献中,有一些例子表明,来自AD领域的与实现相关的经验已经用于机器学习设置中。最近一个特别感兴趣的领域是隐式和迭代式AD技术(Griewank和Walther,2008),该技术已被用于将约束优化融入深度学习的工作中(Amos和Kolter,以及概率图形模型和神经网络(Johnson等人,2016)。另一个例子是检查点策略(Dauvergne and Hasco–et,2006;Siskind and Pearlmutter,2017),通过不在内存中存储中间变量的完整Tape,允许在反向模式AD的时间和空间复杂度之间平衡特定于应用程序的取舍并根据需要通过从中间检查点重新运行正向计算的一部分来重建它们。这与在内存预算有限的gpu上运行的深度学习工作负载高度相关。最近这方面的一个例子是Gruslys等人(2016)的工作,作者在其中构造了一个检查点,通过用于递归神经网络的时间(BPTT)算法,并在一个实例中以计算时间增加33%为代价,证明它节省了高达95%的内存使用。
    在表5中,我们对著名的通用AD实现进行了回顾。29 Juedes(1991)引入了实现技术的彻底分类,Bischof等人随后重新讨论了该分类。(2008)并简化为基本的、运算符重载的、基于编译器的和混合的方法。我们采用类似的分类本节的一部分。

    5.1元素库
    这些实现构成了最基本的类别,并通过调用启用了AD的库来替换数学操作。然后,库公开的方法将用于函数定义,这意味着在编写代码时手动将任何函数分解为基本操作。
    这种方法从AD早期就开始使用,典型的例子是劳森(1971)的WCOMP和UCOMP包,奈丁格的APL包
    屏幕快照 2020-04-20 下午8.08.30.png
    (1989)和辛金斯的著作(1994)。同样,Rich和Hill(1992)使用基本方法在MATLAB中实现了AD。
    元素库仍然是在不重载运算符的情况下为语言实现AD的最简单策略。

    5.2编译器和源代码转换
    这些实现为编程语言提供了扩展,这些语言可以自动将算法分解为支持AD的基本操作。它们通常作为预处理器30执行,以将扩展语言中的输入转换为原始的经典源代码转换实例,包括Fortran预处理器GRESS(Horwedel等人,1988年)和PADRE2(Kubo和Iri,1990年),它们在编译之前将启用AD的Fortran变体转换为标准的Fortran 77。类似地,adif工具(Bischof et al.,1996)给出一个Fortran源代码,生成一个扩充代码,其中除了原始结果之外,还计算所有指定的偏导数。对于用ANSI C编码的过程,ADIC工具(Bischof等人,1997)在指定了依赖和独立变量之后,将AD作为源代码转换来实现。
    最近也使用这种方法的流行工具是Tapenade(Pascual和Hasco¨et,2008;Hasco¨et和Pascual,2013),它为Fortran和C程序实现正向和反向模式AD。Tapenade本身是用Java实现的,可以在本地运行,也可以作为在线服务运行。
    除了通过源代码转换进行语言扩展外,还有一些im实现通过专用编译器或解释器引入具有紧密集成的AD功能的新语言。一些最早的可微工具,如俚语(Adamson and Winant,1969)和散文(Pfeiffer,1987)都属于这一类。NAGWare Fortran 95编译器(Naumann和Riehme,2005)是一个更新的例子,使用与AD相关的扩展会在编译时触发派生代码的自动生成。
    作为基于解释器的实现的一个例子,代数建模语言AMPL(Fourer等人,2002)使目标和约束能够用数学符号表示,系统从中推断活动变量并安排必要的计算。这一类的其他例子包括FM/FAD包(Mazourik,1991),它基于类似于Algol的DIFALG语言,以及面向对象的COSY语言(Berz等人,1996)类似于Pascal语。
    斯大林格勒编译器(Pearlmutter和Siskind,2008;Siskind和Pearlmutter,2008a)也属于这一类,它致力于开发基于方案的可微感知VLAD语言。较新的DVL编译器32基于斯大林格勒,使用VLAD语。
    受机器学习应用程序的推动,Tangent库(van Merri¨enboer et al.,2017)使用源代码转换实现AD,并接受用Python和Numpy的语法子集编写的数值函数。

    5.3运算符重载
    在具有多态特性的现代编程语言中,运算符重载pro提供了实现AD的最直接方法,利用了重新定义基本操作语义的能力。C++中操作符重载实现的一个流行工具是ADOR-C(瓦尔特和GrayWink,2012)。ADOL-C要求对变量使用启用AD的类型,并在磁带数据结构中记录对变量的算术操作,这些操作随后可以在反向模式AD计算期间“回放”。Mxyzptlk包(Michelotti,1990)是另一个C++的例子,能够通过正向支持计算任意阶偏导数。FADBAS++库(Bendtsen和Stunung,1996)使用模板和操作符重载实现C++的AD。对于Python,ad包33使用operator over  loading计算一阶和二阶导数,而较新的autograd包提供支持高阶导数的正向和反向模式AD。对于函数式语言,示例包括R6RS-AD35和Scmutils库中的AD例程36(用于Scheme)、AD库37(用于Haskell)和DiffSharp38(用于F#和C#)。

    6。结论
    反向传播和基于梯度的优化实际上是机器学习最近所有成功的背后,它在计算机视觉、语音识别和合成以及机器翻译方面产生了最新的成果。我们期望在可预见的未来,这些技术仍然是机器学习的核心。该领域的研究涉及一个快速原型和开发周期,用于测试新的模型和想法,使用越来越高质量的机器学习框架。这些框架正在从粗粒度(模块级)反向传播过渡到细粒度的通用AD,允许模型以通用编程语言的常规程序实现,而差异化是基础结构的一个组成部分。我们坚信通用AD是梯度基机器学习的未来,并期望它成为机器学习工具箱中不可或缺的工具。
    这是一个在AD和机器学习交叉点工作的激动人心的时刻,并且有许多机会从AD界带来先进的技术和专业知识来解决机器学习问题。AD界开发的技术,如Tape缩减和消除(Naumann,2004)、定点迭代(Christianson,1994)、利用矩阵着色稀疏性(Gebremedhin等人,20092013)和反向AD检查点(Dauvergne和Hasco¨等人,2006)只是一些考试,可以发现在机器学习中的潜在用途,以提高性能,改进优化的收敛性,更有效地使用硬件,甚至实现新型的机器学习模型。同样,令人兴奋的新AD模式逆Jacobian的直接传播(Srinivasan和Todorov,2015)已经从机器学习社区中出现,但是还没有被AD社区检验和正式化。
    未来工作的一个重要方向是在机器学习中使用嵌套AD技术,允许分化与参照翻译任意深度嵌套(Siskind and Pearlmutter,2008b;Pearlmutter and Siskind,2008)。嵌套AD在超参数优化中具有很高的相关性,因为它可以毫不费力地提供精确的超参数,即训练目标相对于超参数的导数优化程序(Maclaurin等人,2015年;Baydin等人,2018年)。在贝叶斯模型选择(Rasmussen和Williams,2006)和基于梯度的哈密顿蒙特卡罗步长和质量矩阵调整(Salimans等人,2015)中的潜在应用。除了超参数外,内部使用高阶导数的模型构成了嵌套AD的直接使用情形。黎曼流形Langevin和Hamiltonian Monte Carlo方法(Girolami和Calderhead,2011)使用高阶导数信息更紧密地跟踪更快的收敛性和探索性。在神经网络中,使用嵌套导数是很自然的在定义考虑输入变换的目标函数时,例如用于在一组选定变换下施加不变性的切线投影法(Simard等人,1998)。