7.3_增加backward方法

7.3 增加backward方法

从前面这些反向传播的代码可以看出,它们有着相同的处理流程。准确来说,是从一个变量到前一个变量的反向传播逻辑相同。为了自动完成这些重复的处理,我们在Variable类中添加一个新的方法——backward。

steps/step07.py

class Variable: def__init__(self,data): self.data  $\equiv$  data self.grad  $=$  None self.birth  $\equiv$  None def setCreator(self,func): self.birth  $\equiv$  func   
def backward(self): f  $\equiv$  self creator #1.获取函数 iffisnotNone: x=f-input#2.获取函数的输入 x.grad  $\equiv$  f.backup(self.grad)#3.调用函数的backward方法 x.backup() #调用自己前面那个变量的backward方法(递归)

backward方法和此前反复出现的流程基本相同。具体来说,它从Variable的creator获取函数,并取出该函数的输入变量,然后调用函数的backward方法。最后,它会针对自己前面的变量,调用它的backward方法。这样每个变量的backward方法就会被递归调用。

如果Variable实例的creator是None,那么反向传播就此结束。这种情况意味着Variable实例是由非函数创造的,主要来自用户提供的变量。

下面使用这个新的Variable自动进行反向传播。

steps/step07.py

A  $=$  Square()   
B  $=$  Exp()   
C  $=$  Square()   
 $\begin{array}{rl} & {\mathrm{x} = \mathrm{Variable}(\mathrm{np.array}(0.5))}\\ & {\mathrm{a} = \mathrm{A}(\mathrm{x})}\\ & {\mathrm{b} = \mathrm{B}(\mathrm{a})}\\ & {\mathrm{y} = \mathrm{C}(\mathrm{b})} \end{array}$

#反向传播

y.grad  $=$  np.array(1.0)   
y.backup()   
print(x.grad)

运行结果

3.297442541400256

只要像上面那样调用变量y的backward方法,反向传播就会自动进行。运行结果和之前的一样。这样我们就打好了对DeZero来说最重要的自动微分的基础。

步骤8

从递归到循环

在上一个步骤中,我们向Variable类添加了backward方法。考虑到处理效率的改善和今后的功能扩展,本步骤将改进backward方法的实现方式。

7.3_增加backward方法 - 深度学习自制框架 | OpenTech