3.2_函数的连续调用
3.2 函数的连续调用
Function类的__call__方法的输入和输出都是Variable实例。因此,DeZero函数自然可以连续使用。比如 的计算,我们可以像下面这样编写它的计算代码。
steps/step03.pyA $=$ Square()
B $=$ Exp()
C $=$ Square()
$\begin{array}{rl} & {\mathrm{x} = \mathrm{Variable(np.array(0.5))}}\\ & {\mathrm{a} = \mathrm{A(x)}}\\ & {\mathrm{b} = \mathrm{B(a)}}\\ & {\mathrm{y} = \mathrm{C(b)}}\\ & {\mathrm{print(y.data)}} \end{array}$运行结果
1.648721270700128
上面的代码连续使用了A、B、C这3个函数。这里的关键点是中途出现的4个变量x、a、b、y都是Variable实例。由于Function类的__call__方法的输入和输出都是Variable实例,所以可以像上面的代码一样连续使用多个函数。如图3-1所示,这里进行的计算可以用函数和变量交替排列的计算图来表示。

图3-1 使用多个函数的计算图(圆框代表变量,方框代表函数)

我们可以把图3-1那种依次应用多个函数创建的变换看作一个大的函数。这种由多个函数组成的函数叫作复合函数。值得注意的是,即使组成复合函数的每个函数都是简单的计算,我们也可以依次连续使用它们来执行复杂的计算。
为什么要用计算图来表示一系列的计算呢?答案是这样能高效地求出每个变量的导数(准确来说,是做好了这样的准备)。这个算法就是反向传播(back propagation)。从下一个步骤开始,我们将扩展DeZero,以支持反向传播。
步骤4
数值微分
现在,我们已经实现了Variable类和Function类。实现这些类的目的是自动微分。在本步骤中,我们会先复习导数,并尝试用一种叫作数值微分(numerical differentiation)的方法来求导。从下一个步骤开始,我们将实现一种替代数值微分的更高效的算法——反向传播。

导数不仅仅在机器学习领域,在其他领域也很重要。从流体力学、金融工程到气象模拟、工程设计优化,很多领域需要进行导数计算,而且这些领域实际上都在使用自动微分的功能。