



目前已经创建了DeZero的变量和函数。我们还在上一个步骤实现了一个名为 Square 的用于计算平方的函数类。在本步骤中,我们会实现一个新的函数,并将多个函数连结起来进行计算。
首先在DeZero中实现一个新函数。这里我们要实现的是
的计算(其中,e是自然对数,具体值为e=2.718...)。代码如下所示。
steps/step03.py
class Exp(Function):
def forward(self, x):
return np.exp(x)
与 Square 类的实现过程一样,继承 Function 类,并在 forward 方法中实现要计算的内容。与 Square 类唯一不同的是, forward 方法的内容由 x ** 2 变成了 np.exp(x) 。
Function
类的
__call__
方法的输入和输出都是
Variable
实例。因此,DeZero函数自然可以连续使用。比如
的计算,我们可以像下面这样编写它的计算代码。
steps/step03.py
A=Square() B=Exp() C=Square() x=Variable(np.array(0.5)) a=A(x) b=B(a) y=C(b) print(y.data)
1.648721270700128
上面的代码连续使用了 A 、 B 、 C 这3个函数。这里的关键点是中途出现的4个变量 x 、 a 、 b 、 y 都是 Variable 实例。由于 Function 类的 __call__ 方法的输入和输出都是 Variable 实例,所以可以像上面的代码一样连续使用多个函数。如 图3-1 所示,这里进行的计算可以用函数和变量交替排列的计算图来表示。
图3-1 使用多个函数的计算图(圆框代表变量,方框代表函数)
我们可以把
图3-1
那种依次应用多个函数创建的变换看作一个大的函数。这种由多个函数组成的函数叫作复合函数。值得注意的是,即使组成复合函数的每个函数都是简单的计算,我们也可以依次连续使用它们来执行复杂的计算。
为什么要用计算图来表示一系列的计算呢?答案是这样能高效地求出每个变量的导数(准确来说,是做好了这样的准备)。这个算法就是 反向传播(backpropagation) 。从下一个步骤开始,我们将扩展DeZero,以支持反向传播。