16.1_增加“辈分”变量

16.1 增加“辈分”变量

首先在Variable类和Function类中增加实例变量generation。generation表示函数(或变量)属于哪一代。下面先来看看Variable类的代码,类中增加的代码如下所示。

steps/step16.py

class Variable: def__init__(self,data): ifdataisnotNone: ifnotisinstance(data,np.ndarray): raiseTypeError('{}isnotsupported'.format(type(data))) self.data  $=$  data self.grad  $\equiv$  None self creator  $=$  None self_generation  $= 0$  defsetCreator(self,func): self creator  $=$  func self_generation  $=$  func_generation  $+1$

Variable类将generation初始化为0。之后,当set creator方法被调用时,它将generation的值设置为父函数的generation值加1。如图16-1所示,由f_generation的值为2的函数创建的变量,其y_generation的值为3。以上就是对Variable类所做的修改。


图16-1 变量的generation的关系图(generation的值显示在节点上方)

接下来是Function类。Function类的generation被设置为与输入变量的generation相同的值。如图16-2的左图所示,输入变量只有一个,它的generation的值为4,这时函数的generation的值也为4。


图16-2 函数的generation的关系图

在有多个输入变量的情况下,要采用其中最大的generation的值。如图16-2的右图所示,输入变量有两个,它们的generation的值分别为3和4,此时要将函数的generation设为4。为了满足以上几点,我们在Function类中添加以下代码。

steps/step16.py

class Function(object): def__call__(self,\*inputs): xs  $=$  [x.data for x in inputs] ys  $=$  self.forward(\*xs) if not isinstance(ys,tuple): ys  $=$  (ys,) outputs  $=$  [Variable(as_array(y)) for y in ys] self_generation  $=$  max([x_generation for x in inputs]) for output in outputs: output.set creator(self) self.Inputs  $\equiv$  inputs self.outputs  $\equiv$  outputs return outputs if len(output)  $>1$  else outputs[0]

上面阴影部分的代码用来设置Function的generation。