本文將介紹Autograd基礎。
PyTorch的Autograd特性是PyTorch靈活和快速構建機器學習項目的一部分。它允許在一個復雜的計算中快速而簡單地計算多個偏導數(也稱為梯度)。這個操作是基于反向傳播的神經網絡學習的核心。
autograd的強大之處在于它在運行時動態地跟蹤你的計算,這意味著如果你的模型有決策分支,或者循環的長度直到運行時才知道,計算仍然會被正確地跟蹤,你會得到正確的梯度來驅動學習。這一點,再加上模型是用Python構建的這一事實,提供了比依賴于靜態分析更嚴格的結構模型來計算梯度的框架更大的靈活性。
我們需要Autograd做什么?
機器學習模型是一個函數,有輸入和輸出。在這個討論中,我們將把輸入作為一個i維向量 x ? \vec{x} x,帶有元素 x i x_i xi?. 然后我們可以將模型M表示為輸入的向量值函數: y ? = M ? ( x ? ) \vec{y}=\vec{M}(\vec{x}) y?=M(x)(我們把M的輸出值當作一個向量,因為一般來說,一個模型可以有任意數量的輸出。)
由于我們將主要在訓練的背景下討論自梯度,我們感興趣的輸出將是模型的損失。損失函數 L ( y ? ) = L ( M ? ( x ? ) ) L(\vec{y})=L(\vec{M}(\vec{x})) L(y?)=L(M(x))是模型輸出的單值標量函數。該函數表示我們的模型預測與特定輸入的理想輸出之間的距離。注意:在這一點之后,我們通常會在上下文清楚的地方省略向量符號-例如: y y y而不是 y ? \vec{y} y?。
在訓練模型時,我們希望將損失最小化。在一個完美模型的理想情況下,這意味著調整它的學習權值——也就是函數的可調參數——使得所有輸入的損失為零。在現實世界中,這意味著一個不斷調整學習權重的迭代過程,直到我們看到對于各種各樣的輸入,我們得到了一個可以容忍的損失。
我們如何決定將重物推多遠,朝哪個方向?我們想要最小化損失,這意味著使它對輸入的一階導數等于0。即 ? L ? x = 0 \frac{\partial{L}}{\partial{x}}=0 ?x?L?=0
但是,回想一下,損失不是直接來自輸入,而是模型輸出的函數(直接是輸入的函數), ? L ? x = ? L ( y ? ) ? x \frac{\partial{L}}{\partial{x}}=\frac{\partial{L(\vec{y})}}{\partial{x}} ?x?L?=?x?L(y?)?. 根據微分的鏈式法則,我們有 ? L ( y ? ) ? x = ? L ( y ? ) ? y ? ? M ( x ) ? x \frac{\partial{L(\vec{y})}}{\partial{x}}=\frac{\partial{L(\vec{y})}}{\partial{y}}*\frac{\partial{M(x)}}{\partial{x}} ?x?L(y?)?=?y?L(y?)???x?M(x)?。在這個式子中, ? M ( x ) ? x \frac{\partial{M(x)}}{\partial{x}} ?x?M(x)?就是事情變得復雜的地方。模型輸出相對于其輸入的偏導數,如果我們再次使用鏈式法則展開表達式,將涉及對模型中每個乘法學習權值、每個激活函數和每個其他數學變換的許多局部偏導數。每個這樣的偏導數的完整表達式是通過計算圖的每個可能路徑的局部梯度的乘積的和,該計算圖以我們試圖測量的梯度的變量結束。
特別是,我們對學習權值上的梯度很感興趣——它們告訴我們改變每個權值的方向,以使損失函數更接近于零。
由于這種局部導數的數量(每個對應于模型計算圖中的單獨路徑)將隨著神經網絡的深度呈指數增長,計算它們的復雜性也會呈指數增長。這就是autograd的用武之地:它跟蹤每一次計算的歷史。PyTorch模型中的每個計算張量都攜帶其輸入張量和用于創建它的函數的歷史記錄。結合PyTorch函數意味著作用于張量的事實,每個函數都有一個內置的實現來計算它們自己的導數,這大大加快了學習所需的局部導數的計算速度。
一個簡單的例子
這是很多的理論——但是在實踐中使用自動光柵是什么樣子的呢?
讓我們從一個簡單的例子開始。首先,我們將做一些導入來繪制結果:
# %matplotlib inlineimport torchimport matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import math
接下來,我們將創建一個輸入張量,它在區間上充滿了均勻間隔的值[0,2π],并指定requires_grad=True。(像大多數創建張量的函數一樣,torch.linspace()接受一個可選的requires_grad選項。)設置此標志意味著在接下來的每個計算中,autograd將在該計算的輸出張量中積累計算的歷史。
a = torch.linspace(0., 2. * math.pi, steps=25