反向模式自動微分的逐步示例
不確定這個問題是否屬於這裡,但它與優化中的梯度方法密切相關,這似乎是這裡的主題。無論如何,如果您認為其他社區在該主題上有更好的專業知識,請隨時遷移。
簡而言之,我正在尋找反向模式自動微分的逐步示例。沒有太多關於該主題的文獻,現有的實現(如TensorFlow中的實現)在不了解其背後的理論的情況下很難理解。因此,如果有人能詳細說明我們傳入了什麼、我們如何處理它以及我們從計算圖中得到了什麼,我將非常感激。
我最難解決的幾個問題:
假設我們有表達 $ z = x_1x_2 + \sin(x_1) $ 並想找到衍生品 $ \frac{dz}{dx_1} $ 和 $ \frac{dz}{dx_2} $ . 反向模式 AD 將此任務分為兩部分,即正向和反向傳遞。
前傳
首先,我們將復雜表達式分解為一組原始表達式,即最多包含單個函數調用的表達式。請注意,我還重命名了輸入和輸出變量以保持一致性,儘管這不是必需的:
$$ w_1 = x_1 $$ $$ w_2 = x_2 $$ $$ w_3 = w_1w_2 $$ $$ w_4 = \sin(w_1) $$ $$ w_5 = w_3 + w_4 $$ $$ z = w_5 $$
這種表示的優點是每個單獨的表達式的微分規則是已知的。例如,我們知道 $ \sin $ 是 $ \cos $ , 所以 $ \frac{dw_4}{dw_1} = \cos(w_1) $ . 我們將在下面的反向傳遞中使用這個事實。
本質上,前向傳遞包括評估每個表達式並保存結果。比如說,我們的輸入是: $ x_1 = 2 $ 和 $ x_2 = 3 $ . 然後我們有:
$$ w_1 = x_1 = 2 $$ $$ w_2 = x_2 = 3 $$ $$ w_3 = w_1w_2 = 6 $$ $$ w_4 = \sin(w_1) ~= 0.9 $$ $$ w_5 = w_3 + w_4 = 6.9 $$ $$ z = w_5 = 6.9 $$
反向傳球
這是神奇的開始,它從鍊式法則開始。鍊式法則的基本形式是,如果你有變量 $ t(u(v)) $ 這取決於 $ u $ 而這又取決於 $ v $ , 然後:
$$ \frac{dt}{dv} = \frac{dt}{du}\frac{du}{dv} $$
或者如果 $ t $ 依賴於取決於 $ v $ 通過多個路徑/變量 $ u_i $ ,例如:
$$ u_1 = f(v) $$ $$ u_2 = g(v) $$ $$ t = h(u_1, u_2) $$
然後(參見此處的證明):
$$ \frac{dt}{dv} = \sum_i \frac{dt}{du_i}\frac{du_i}{dv} $$
就表達式圖而言,如果我們有一個最終節點 $ z $ 和輸入節點 $ w_i $ , 和路徑 $ z $ 到 $ w_i $ 通過中間節點 $ w_p $ (IE $ z = g(w_p) $ 在哪裡 $ w_p = f(w_i) $ ),我們可以求導 $ \frac{dz}{dw_i} $ 作為
$$ \frac{dz}{dw_i} = \sum_{p \in parents(i)} \frac{dz}{dw_p} \frac{dw_p}{dw_i} $$
換句話說,計算輸出變量的導數 $ z $ wrt任何中間或輸入變量 $ w_i $ ,我們只需要知道它的雙親的導數和計算原始表達式導數的公式 $ w_p = f(w_i) $ .
反向傳球從最後開始(即 $ \frac{dz}{dz} $ ) 並向後傳播到所有依賴項。這裡我們有(“種子”的表達):
$$ \frac{dz}{dz} = 1 $$
這可以理解為“改變 $ z $ 導致完全相同的變化 $ z $ “,這是很明顯的。
然後我們知道 $ z = w_5 $ 所以:
$$ \frac{dz}{dw_5} = 1 $$
$ w_5 $ 線性依賴於 $ w_3 $ 和 $ w_4 $ , 所以 $ \frac{dw_5}{dw_3} = 1 $ 和 $ \frac{dw_5}{dw_4} = 1 $ . 使用鍊式法則我們發現:
$$ \frac{dz}{dw_3} = \frac{dz}{dw_5} \frac{dw_5}{dw_3} = 1 \times 1 = 1 $$ $$ \frac{dz}{dw_4} = \frac{dz}{dw_5} \frac{dw_5}{dw_4} = 1 \times 1 = 1 $$
從定義 $ w_3 = w_1w_2 $ 和偏導數規則,我們發現 $ \frac{dw_3}{dw_2} = w_1 $ . 因此:
$$ \frac{dz}{dw_2} = \frac{dz}{dw_3} \frac{dw_3}{dw_2} = 1 \times w_1 = w_1 $$
正如我們從前向傳球中已經知道的那樣,它是:
$$ \frac{dz}{dw_2} = w_1 = 2 $$
最後, $ w_1 $ 有助於 $ z $ 通過 $ w_3 $ 和 $ w_4 $ . 再一次,從偏導數的規則我們知道 $ \frac{dw_3}{dw_1} = w_2 $ 和 $ \frac{dw_4}{dw_1} = \cos(w_1) $ . 因此:
$$ \frac{dz}{dw_1} = \frac{dz}{dw_3} \frac{dw_3}{dw_1} + \frac{dz}{dw_4} \frac{dw_4}{dw_1} = w_2 + \cos(w_1) $$
同樣,給定已知的輸入,我們可以計算它:
$$ \frac{dz}{dw_1} = w_2 + \cos(w_1) = 3 + \cos(2) ~= 2.58 $$
自從 $ w_1 $ 和 $ w_2 $ 只是別名 $ x_1 $ 和 $ x_2 $ ,我們得到答案:
$$ \frac{dz}{dx_1} = 2.58 $$ $$ \frac{dz}{dx_2} = 2 $$
就是這樣!
此描述僅涉及標量輸入,即數字,但實際上它也可以應用於多維數組,例如向量和矩陣。在用此類對象區分錶達式時應牢記兩件事:
- 導數可能比輸入或輸出具有更高的維度,例如向量 wrt 的導數是一個矩陣,而矩陣 wrt 的導數是一個 4 維數組(有時稱為張量)。在許多情況下,此類導數非常稀疏。
- 輸出數組中的每個分量都是輸入數組的一個或多個分量的獨立函數。例如,如果 $ y = f(x) $ 和兩者 $ x $ 和 $ y $ 是向量, $ y_i $ 從不依賴 $ y_j $ ,但僅在 $ x_k $ . 特別是,這意味著找到導數 $ \frac{dy_i}{dx_j} $ 歸結為跟踪如何 $ y_i $ 依賴於取決於 $ x_j $ .
自動微分的強大之處在於它可以處理來自編程語言的複雜結構,例如條件和循環。但是,如果您只需要代數表達式,並且您有足夠好的框架來處理符號表示,那麼構建完全符號表達式是可能的。事實上,在這個例子中,我們可以產生表達式 $ \frac{dz}{dw_1} = w_2 + \cos(w_1) = x_2 + \cos(x_1) $ 並為我們想要的任何輸入計算這個導數。