亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

理解“backward()”:如何從頭開始編寫 Pytorch 函數“.backward()”?

理解“backward()”:如何從頭開始編寫 Pytorch 函數“.backward()”?

白豬掌柜的 2023-08-22 16:55:36
我是學習深度學習的新手,我一直試圖理解 Pytorch 中的“.backward()”的作用,因為它幾乎完成了大部分工作。因此,我試圖詳細了解向后函數的作用,因此,我將嘗試逐步編寫該函數的作用。您可以向我推薦任何資源(書籍、視頻、GitHub 存儲庫)來開始編寫該函數嗎?感謝您抽出時間并希望您能提供幫助。
查看完整描述

1 回答

?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

backward()正在計算相對于(wrt)圖葉的梯度。?grad()函數更通用,它可以計算任何輸入(包括葉子)的梯度。

grad()前段時間實現了這個功能,你可以看看。它使用自動微分(AD)的力量。

import math

class 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 # shortcuts

sin = A.sin

exp = A.exp


def 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*x2


print_childs(x2,"x2")

print("\ncalculated gradient for the function f with respect to x2:", f.grad(x2))

出去:


child: x2 -> sin(x2) grad:? 0.8775825618903728

child: sin(x2) -> sin(x2)+1 grad:? 1.0

child: sin(x2)+1 -> sin(x2)+1/x2+exp(x1) grad:? 0.20073512936690338

child: sin(x2)+1/x2+exp(x1) -> sin(x2)+1/x2+exp(x1)+x1*x2 grad:? 1.0

child: x2 -> x2+exp(x1) grad:? 1.0

child: x2+exp(x1) -> sin(x2)+1/x2+exp(x1) grad:? -0.05961284871202578

child: sin(x2)+1/x2+exp(x1) -> sin(x2)+1/x2+exp(x1)+x1*x2 grad:? 1.0

child: x2 -> x1*x2 grad:? 1.5

child: x1*x2 -> sin(x2)+1/x2+exp(x1)+x1*x2 grad:? 1.0


calculated gradient for the function f with respect to x2: 1.6165488003791766


查看完整回答
反對 回復 2023-08-22
  • 1 回答
  • 0 關注
  • 212 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號