9.2_简化backward方法
9.2 简化backward方法
第2项要改进的地方是减少用户在反向传播方面所做的工作。具体来说,就是省略前面代码中的y.grad = np.array(1.0)。每次反向传播时我们都要重新编写这行代码,为了省略它,我们需要在Variable的backward方法中添加阴影部分的两行代码。
steps/step09.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() x,y $=$ f-input,f.output x.grad $=$ f.backup(y.grad) ifx creatorisnotNone: funcs.append(x creator)如上所示,如果变量grad为None,则自动生成导数。代码中通过np.ones_
like(self.data)创建了一个ndarray实例,该实例的形状和数据类型与self.data的相同,元素为1。如果self.data是标量,那么self.grad也是标量。

之前的代码中输出的导数是np.array(1.0),而上面的代码使用了np.ones_like()。这么编写的原因是Variable中的data和grad的数据类型是一样的。如果data的数据类型是32位浮点数,那么grad的数据类型也是32位浮点数。顺带一提,如果编写的是np.array(1.0),它的数据类型就是64位的浮点数。
之后如果再做某个计算,只需对最终输出的变量调用backward方法就能求得导数。下面是示例代码。
steps/step09.py$\mathbf{x} =$ Variable(np.array(0.5))
y $=$ square(exp(square(x)))
y.backup()
print(x.grad)运行结果
3.297442541400256