4.5 自动梯度计算
- 神经网络的参数主要通过梯度下降来进行优化.当确定了风险函数以及网络结构后,我们就可以手动用链式法则来计算风险函数对每个参数的梯度,并用 代码进行实现.但是手动求导并转换为计算机程序的过程非常琐碎并容易出错,导致实现神经网络变得十分低效.实际上,参数的梯度可以让计算机来自动计 算.目前,主流的深度学习框架都包含了自动梯度计算的功能,即我们可以只考 虑网络结构并用代码实现,其梯度可以自动进行计算,无须人工干预,这样可以 大幅提高开发效率。
自动计算梯度的方法可以分为以下三类:数值微分、符号微分和自动微分.
4.5.1 数值微分
数值微分的另外一个问题是计算复杂度.假设参数数量为𝑁,则每个参数都需要单独施加扰动,并计算梯度.假设每次正向传播的计算复杂度为𝑂(𝑁),则计 算数值微分的总体时间复杂度为𝑂(𝑁2)。
4.5.2 符号微分
- 符号微分(Symbolic Differentiation)是一种基于符号计算的自动求导方法. 符号计算也叫代数计算,是指用计算机来处理带有变量的数学表达式.这里的变量被看作符号(Symbols),一般不需要代入具体的值.符号计算的输入和输 出都是数学表达式,一般包括对数学表达式的化简、因式分解、微分、积分、解代数方程、求解常微分方程等运算。
- 符号微分可以在编译时就计算梯度的数学表示,并进一步利用符号计算方法进行优化.此外,符号计算的一个优点是符号计算和平台无关,可以在CPU或 GPU上运行.
符号微分也有一些不足之处:
1)编译时间较长,特别是对于循环, 需要很长时间进行编译;
2)为了进行符号微分,一般需要设计一种专门的语言 来表示数学表达式,并且要对变量(符号)进行预先声明;
3)很难对程序进行调试.
4.5.3 自动微分
自动微分(Automatic Differentiation,AD)是一种可以对一个(程序)函数进行计算导数的方法.符号微分的处理对象是数学表达式,而自动微分的处理对象是一个函数或一段程序.
自动微分的基本原理是所有的数值计算可以分解为一些基本操作,包含+, −, ×, /和一些初等函数exp, log, sin, cos等,然后利用链式法则来自动计算一个复合函数的梯度。
按照计算导数的顺序,自动微分可以分为两种模式:前向模式和反向模式
- 前向模式是按计算图中计算方向的相同方向来递归地计算梯度。
- 反向模式是按计算图中计算方向的相反方向来递归地计算梯度。