四、自动微分
自动微分研究如何数值计算导数,反向传播算法只是自动微分的一种方法,它是反向模式累加算法的特殊情况。
不同的自动微分算法以不同的顺序计算链式法则的子表达式,找到计算梯度的最优操作序列是
NP
完全问题。事实上,反向传播算法不能化简梯度计算公式,它只会通过计算图来传播梯度。如:
而反向传播算法并不知道可以这样简化。
有些软件如
Theano
和TenserFlow
能够尝试执行某些类型的代数替换来部分地简化梯度计算公式。若前向图 具有单个输出节点,并且每个偏导数 都能够以恒定的计算量来计算时,反向传播保证梯度的计算数量和前向计算的计算数量都在同一个量级。计算量都是 , 为边的数量。
反向传播算法可以扩展到计算
Jacobi
矩阵。矩阵来源可能是图中的 个不同标量节点;也可能来源于某个节点,但是该节点是个张量,张量内部具有 个内部标量。当图的输出数目大于输入数目时,有时倾向于使用另一种形式的自动微分,称作前向模式累加。
前向模式累加可以用于循环神经网络梯度的实时计算。
前向模式累加避免了存储整个图的值和梯度,是计算效率和内存消耗的折中。
前向模式和后向模式(反向传播算法就是后向模式的一种)的关系类似于:左乘、右乘一系列矩阵。如: 。
- 如果从右向左进行,则只需要计算矩阵-向量乘积。这对应着反向模式。
- 如果从左向右进行,则需要计算矩阵-矩阵乘积(只有最后一次计算是矩阵-向量乘积)。这对应着前向模式,这时总的计算量和存储空间更大。
在机器学习以外的领域,传统的编程语言比如
C/Python/C++
直接实现了求导数的库。- 在深度学习中无法使用这些库,而是必须使用专用库创建明确的数据结构来表示求导。
- 深度学习需要深度学习库的开发人员为每个操作定义
bprop
方法,并且限制库的用户只能使用该方法来求导。
一些软件框架支持使用高阶导数(如
Theano/TensorFlow
),这些库需要使用一种数据结构来描述要被微分的原始函数。它们使用相同的数据结构来描述原始函数的导数(导数也是一个函数对象),这意味着符号微分机制可以产生高阶导数。
在深度学习领域很少关注标量函数的单个二阶导数,而是关注海森矩阵的性质。
假设函数 ,则海森矩阵大小为 。在某些深度学习任务中 为模型参数数量,很可能达到十亿,因此完整的海森矩阵无法在内存中表示。
一个解决方案是使用
Krylov
方法。该方法使用矩阵-向量乘法来迭代求解矩阵的逆、矩阵特征值、矩阵特征向量等问题。为了使用
Krylov
方法,需要计算海森矩阵和任意向量 的乘积: 。因为 与 无关,因此 在
[]
里面或者外面没有区别。上式中的两个梯度计算都可以由软件库自动完成。
注意:如果 本身如果已经是计算图产生的一个向量,则需要告诉软件库不要对产生 的节点进行微分。