Apache MXNet - Python 包



在本章中,我們將學習 Apache MXNet 中可用的 Python 包。

重要的 MXNet Python 包

MXNet 具有以下重要的 Python 包,我們將逐一討論:

  • Autograd(自動微分)

  • NDArray

  • KVStore

  • Gluon

  • 視覺化

首先讓我們從 Apache MXNet 的Autograd Python 包開始。

Autograd

Autograd 代表自動微分,用於將梯度從損失度量反向傳播回每個引數。除了反向傳播之外,它還使用動態規劃方法來有效地計算梯度。它也稱為反向模式自動微分。此技術在“扇入”情況下非常有效,在“扇入”情況下,許多引數會影響單個損失度量。

什麼是梯度?

梯度是神經網路訓練過程的基礎。它們基本上告訴我們如何改變網路的引數以提高其效能。

眾所周知,神經網路 (NN) 由運算元組成,例如求和、乘積、卷積等。這些運算元在其計算中使用引數,例如卷積核中的權重。我們必須找到這些引數的最優值,而梯度則向我們展示了方法,並引導我們找到解決方案。

Graph_of_Gradients

我們對改變引數對網路效能的影響感興趣,梯度告訴我們,當我們改變一個變數時,給定變數增加或減少多少,它取決於。效能通常使用我們嘗試最小化的損失度量來定義。例如,對於迴歸,我們可能會嘗試最小化預測值和精確值之間的L2損失,而對於分類,我們可能會最小化交叉熵損失

一旦我們計算出每個引數相對於損失的梯度,我們就可以使用最佳化器(例如隨機梯度下降)。

如何計算梯度?

我們有以下選項來計算梯度:

  • 符號微分 - 第一個選項是符號微分,它計算每個梯度的公式。此方法的缺點是,隨著網路變得更深以及運算元變得更復雜,它將很快導致難以置信的長公式。

  • 有限差分 - 另一個選項是使用有限差分,它嘗試對每個引數進行輕微的差異,並觀察損失度量如何響應。此方法的缺點是,它在計算上會很昂貴,並且可能具有較差的數值精度。

  • 自動微分 - 上述方法缺點的解決方案是使用自動微分將梯度從損失度量反向傳播回每個引數。傳播允許我們使用動態規劃方法來有效地計算梯度。此方法也稱為反向模式自動微分。

自動微分 (autograd)

在這裡,我們將詳細瞭解 autograd 的工作原理。它基本上分以下兩個階段工作:

階段 1 - 此階段稱為訓練的“前向傳遞”。顧名思義,在此階段,它會建立網路用於進行預測和計算損失度量的運算元的記錄。

階段 2 - 此階段稱為訓練的“後向傳遞”。顧名思義,在此階段,它會透過此記錄向後工作。向後移動,它會評估每個運算元的偏導數,一直回到網路引數。

Automatic Differentiation

autograd 的優勢

以下是使用自動微分 (autograd) 的優勢:

  • 靈活 - 在定義網路時提供的靈活性是使用 autograd 的巨大好處之一。我們可以在每次迭代中更改操作。這些被稱為動態圖,在需要靜態圖的框架中實現起來要複雜得多。即使在這種情況下,autograd 仍然能夠正確地反向傳播梯度。

  • 自動 - Autograd 是自動的,即反向傳播過程的複雜性由它為您處理。我們只需要指定我們感興趣計算哪些梯度。

  • 高效 - Autogard 高效地計算梯度。

  • 可以使用原生 Python 控制流運算子 - 我們可以使用原生的 Python 控制流運算子,例如 if 條件和 while 迴圈。autograd 仍然能夠高效且正確地反向傳播梯度。

在 MXNet Gluon 中使用 autograd

在這裡,我們將透過一個示例瞭解如何在 MXNet Gluon 中使用autograd

實現示例

在以下示例中,我們將實現一個具有兩層的神經網路。實現後,我們將使用 autograd 自動計算損失相對於每個權重引數的梯度:

首先匯入 autogrard 和其他所需的包,如下所示:

from mxnet import autograd
import mxnet as mx
from mxnet.gluon.nn import HybridSequential, Dense
from mxnet.gluon.loss import L2Loss

現在,我們需要定義網路,如下所示:

N_net = HybridSequential()
N_net.add(Dense(units=3))
N_net.add(Dense(units=1))
N_net.initialize()

現在我們需要定義損失,如下所示:

loss_function = L2Loss()

接下來,我們需要建立虛擬資料,如下所示:

x = mx.nd.array([[0.5, 0.9]])
y = mx.nd.array([[1.5]])

現在,我們準備進行第一次透過網路的前向傳遞。我們希望 autograd 記錄計算圖,以便我們可以計算梯度。為此,我們需要在autograd.record上下文中執行網路程式碼,如下所示:

with autograd.record():
   y_hat = N_net(x)
   loss = loss_function(y_hat, y)

現在,我們準備進行反向傳遞,我們透過對感興趣的數量呼叫 backward 方法來啟動它。在我們示例中,感興趣的數量是損失,因為我們試圖計算損失相對於引數的梯度:

loss.backward()

現在,我們有了網路中每個引數的梯度,最佳化器將使用這些梯度來更新引數值以提高效能。讓我們檢查第一層的梯度,如下所示:

N_net[0].weight.grad()

輸出

輸出如下:

[[-0.00470527 -0.00846948]
[-0.03640365 -0.06552657]
[ 0.00800354 0.01440637]]
<NDArray 3x2 @cpu(0)>

完整的實現示例

下面是完整的實現示例。

from mxnet import autograd
import mxnet as mx
from mxnet.gluon.nn import HybridSequential, Dense
from mxnet.gluon.loss import L2Loss
N_net = HybridSequential()
N_net.add(Dense(units=3))
N_net.add(Dense(units=1))
N_net.initialize()
loss_function = L2Loss()
x = mx.nd.array([[0.5, 0.9]])
y = mx.nd.array([[1.5]])
with autograd.record():
y_hat = N_net(x)
loss = loss_function(y_hat, y)
loss.backward()
N_net[0].weight.grad()
廣告