



我们通过数值微分成功求出了导数。但是,数值微分在计算成本和精度方面存在问题。反向传播可以解决这两个问题。也就是说,反向传播不仅能高效地求导,还能帮助我们得到误差更小的值。本步骤只介绍反向传播的理论知识,不对其进行实现。从下一个步骤开始,我们再去实现反向传播。
理解反向传播的关键是 链式法则(连锁律) 。链(chain)可以理解为链条、锁链等,在这里表示多个函数连接在一起使用。链式法则意为连接起来的多个函数(复合函数)的导数可以分解为各组成函数的导数的乘积。
下面看一个链式法则的具体例子。假设有一个函数
,这个函数
由3个函数组成:
、
和
。该函数的计算图如
图5-1
所示。
图5-1 复合函数的例子
这时,
对
的导数可以用式子5.1表示。
如
式子5.1
所示,
对
的导数可以表示为各函数的导数的乘积。换言之,复合函数的导数可以分解为各组成函数导数的乘积。这就是链式法则。式子5.1所表示的链式法则也可以像下面这样写成包含
的形式。
是对自身求导,导数值永远为1。计算时通常省略
这种针对自身的导数,但考虑到反向传播的实现,这里特意加上了这一项。
是
对
的导数。即使
变化的幅度很小,
自身也会变化同样大小的值。因此,不管对于什么函数,变化率总是1。
下面仔细观察
式子5.2
。
式子5.2
表示复合函数的导数可以分解为各函数导数的乘积。但是,它并没有规定各导数相乘的顺序。当然,这一点我们可以自由决定。这里,我们按照
式子5.3
的方式以输出到输入的顺序进行计算
。
式子5.3 按照从输出到输入的顺序进行导数的计算,计算方向与平时相反。这时, 式子5.3 的计算流程如 图5-2 所示。
图5-2 从输出端的导数开始依次进行计算的流程
在
图5-2
中,导数是按照从输出
到输入
的方向依次相乘计算得出的。通过这种方法,最终得到
。
图5-3
是相应的计算图。
图5-3 求
的计算图
下面仔细观察
图5-3
。我们先从
(=1) 开始,计算它与
的乘积。这里的
是函数
的导数。因此,如果用
表示函数
的导函数,我们就可以把式子写成
。同样,有
,
。基于以上内容,
图5-3
可以简化成
图5-4
。
的乘法在图中简化表示为节点
)
图5-4
中把导函数和乘号合并表示为一个函数节点。这样导数计算的流程就明确了。从
图5-4
中可以看出,“
对各变量的导数”从右向左传播。这就是反向传播。这里重要的一点是传播的数据都是
的导数。具体来说,就是
、
、
和
这种“
对××变量的导数”在传播。
像式子5.3那样将计算顺序规定为从输出到输入,是为了传播
的导数。换言之,就是把
当作“重要人物”。如果按照从输入到输出的顺序计算,输入
就是“重要人物”。在这种情况下,传播的导数将是
这种形式,也就是对
的导数进行传播。
许多机器学习问题采用了以大量参数作为输入,以损失函数作为最终输出的形式。损失函数的输出(在许多情况下)是一个标量值,它是“重要人物”。这意味着我们需要找到损失函数对每个参数的导数。在这种情况下,如果沿着从输出到输入的方向传播导数,只要传播一次,就能求出对所有参数的导数。因为该方法的计算效率较高,所以我们采用反向传播导数的方式。
下面我们把正向传播的计算图( 图5-1 )和反向传播的计算图( 图5-4 )以上下排列的方式画出来。
图5-5 正向传播和反向传播
从
图5-5
可以看出,正向传播和反向传播之间存在明确的对应关系。例如,正向传播时的变量
对应于反向传播时的导数
。同样,
对应于
,
对应于
。我们也可以看出函数之间存在对应关系。例如,函数
的反向传播对应于
,
对应于
。这样一来,我们可以认为变量有普通值和导数值,函数有普通计算(正向传播)和求导计算(反向传播)。于是,反向传播就设计好了。
最后来关注一下
图5-5
中
的函数节点。它是
的导数,但要注意的是,计算
需要用到
的值。同理,要计算
就得输入
的值。这意味着进行反向传播时需要用到正向传播中使用的数据。因此,在实现反向传播时,需要先进行正向传播,并且存储各函数输入的变量值,也就是前面例子中的
、
和
,之后就能对每个函数进行反向传播的计算了。
以上就是反向传播理论知识的相关内容,这是本书的难点之一。大家现在可能还没完全弄明白,但是实际运行代码后,就会理解得越来越透彻。在下一个步骤,我们将实现反向传播,并通过实际运行代码来验证它。