猿问

理解“backward()”:如何从头开始编写 Pytorch 函数“.backward()”?

我是学习深度学习的新手,我一直试图理解 Pytorch 中的“.backward()”的作用,因为它几乎完成了大部分工作。因此,我试图详细了解向后函数的作用,因此,我将尝试逐步编写该函数的作用。您可以向我推荐任何资源(书籍、视频、GitHub 存储库)来开始编写该函数吗?感谢您抽出时间并希望您能提供帮助。



白猪掌柜的
浏览 175回答 1
1回答

翻阅古今

backward()正在计算相对于(wrt)图叶的梯度。 grad()函数更通用,它可以计算任何输入(包括叶子)的梯度。我grad()前段时间实现了这个功能,你可以看看。它使用自动微分(AD)的力量。import mathclass ADNumber:        def __init__(self,val, name=""):        self.name=name        self._val=val        self._children=[]                     def __truediv__(self,other):        new = ADNumber(self._val / other._val, name=f"{self.name}/{other.name}")        self._children.append((1.0/other._val,new))        other._children.append((-self._val/other._val**2,new)) # first derivation of 1/x is -1/x^2        return new    def __mul__(self,other):        new = ADNumber(self._val*other._val, name=f"{self.name}*{other.name}")        self._children.append((other._val,new))        other._children.append((self._val,new))        return new    def __add__(self,other):        if isinstance(other, (int, float)):            other = ADNumber(other, str(other))        new = ADNumber(self._val+other._val, name=f"{self.name}+{other.name}")        self._children.append((1.0,new))        other._children.append((1.0,new))        return new    def __sub__(self,other):        new = ADNumber(self._val-other._val, name=f"{self.name}-{other.name}")        self._children.append((1.0,new))        other._children.append((-1.0,new))        return new                    @staticmethod    def exp(self):        new = ADNumber(math.exp(self._val), name=f"exp({self.name})")        self._children.append((self._val,new))        return new    @staticmethod    def sin(self):        new = ADNumber(math.sin(self._val), name=f"sin({self.name})")              self._children.append((math.cos(self._val),new)) # first derivative is cos        return new        def grad(self,other):        if self==other:                        return 1.0        else:            result=0.0            for child in other._children:                                 result+=child[0]*self.grad(child[1])                            return result        A = ADNumber # shortcutssin = A.sinexp = A.expdef print_childs(f, wrt): # with respect to    for e in f._children:        print("child:", wrt, "->" , e[1].name, "grad: ", e[0])        print_child(e[1], e[1].name)            x1 = A(1.5, name="x1")x2 = A(0.5, name="x2")f=(sin(x2)+1)/(x2+exp(x1))+x1*x2print_childs(x2,"x2")print("\ncalculated gradient for the function f with respect to x2:", f.grad(x2))出去:child: x2 -> sin(x2) grad:  0.8775825618903728child: sin(x2) -> sin(x2)+1 grad:  1.0child: sin(x2)+1 -> sin(x2)+1/x2+exp(x1) grad:  0.20073512936690338child: sin(x2)+1/x2+exp(x1) -> sin(x2)+1/x2+exp(x1)+x1*x2 grad:  1.0child: x2 -> x2+exp(x1) grad:  1.0child: x2+exp(x1) -> sin(x2)+1/x2+exp(x1) grad:  -0.05961284871202578child: sin(x2)+1/x2+exp(x1) -> sin(x2)+1/x2+exp(x1)+x1*x2 grad:  1.0child: x2 -> x1*x2 grad:  1.5child: x1*x2 -> sin(x2)+1/x2+exp(x1)+x1*x2 grad:  1.0calculated gradient for the function f with respect to x2: 1.6165488003791766
随时随地看视频慕课网APP

相关分类

Python
我要回答