14.1_问题的原因

14.1 问题的原因

为什么会出现错误的结果呢?原因在于下面Variable类中阴影部分的代码。

steps/step13.py

class Variable:   
def backward(self): if self.grad is None: self.grad  $=$  np.ones_like(self.data) funcs  $=$  [self creator] while funcs: f  $=$  funcs.pop() gys  $=$  [output.grad for output in f.outputs] gxs  $=$  f.backup(\*gys) if not isinstance(gxs, tuple): gxs  $=$  (gxs,) for x,gx in zip(finputs,gxs): x.grad  $=$  gx #这里有错误!! if x creator is not None: funcs.append(x creator)

如上所示,当前代码是直接用从输出端传播的导数进行赋值的。因此,在计算中重复使用同一个变量时,传播的导数的值会被替换。拿上面的加法运算来说,导数的传播如图14-2所示。


图14-2 y=add(x,x)y = \operatorname{add}(x, x) 的反向传播(箭头上方和下方显示了传播的导数的值)

图14-2显示了传播的导数的值。在这个例子中, xx 的导数的正确结果是 1+1=21 + 1 = 2 。也就是说,我们要求出传播的导数的和,但是,目前的实现方式是覆盖这个值。