8.3_代码验证

8.3 代码验证

接下来使用前面的Variable类来求导。这里运行的是和上一个步骤相同的代码。

steps/step08.py

A = Square()
B = Exp()
C = Square()
x = Variable(np.array(0.5))
a = A(x)
b = B(a)
y = C(b)

#反向传播

y.grad = np.array(1.0)  
y_backward()  
print(x.grad)

运行结果

3.297442541400256

和上一个步骤得到的结果一样。这样实现方式就从递归变成了循环。在步骤15,我们将感受到循环带来的好处。届时要处理的是复杂的计算图,不过在使用循环的情况下,代码实现很容易扩展到复杂的计算图的处理,而且循环的执行效率也会变高。

每次递归调用函数时,函数都会将处理过程中的结果保留在内存中(或者说保留在栈中),然后继续处理。因此一般来说,循环的效率更高。不过,对现代计算机来说,使用少量的内存是没有问题的。有时可以通过尾递归的技巧,使递归处理能够按照循环的方式执行。

这样就完成了反向传播的基础实现。接下来,我们将扩展当前版本的DeZero,以执行更复杂的计算。下一个步骤要做的是提高DeZero的易用性。

步骤9

让函数更易用

DeZero现在可以通过反向传播进行计算了。它还拥有一项名为Define-by-Run的能力,可以在运行时在计算之间建立“连接”。为了使DeZero更加易用,本步骤将对DeZero的函数进行3项改进。