- Apache MXNet 教程
- Apache MXNet - 首頁
- Apache MXNet - 簡介
- Apache MXNet - 安裝 MXNet
- Apache MXNet - 工具包和生態系統
- Apache MXNet - 系統架構
- Apache MXNet - 系統元件
- Apache MXNet - 統一運算元 API
- Apache MXNet - 分散式訓練
- Apache MXNet - Python 包
- Apache MXNet - NDArray
- Apache MXNet - Gluon
- Apache MXNet - KVStore 和視覺化
- Apache MXNet - Python API ndarray
- Apache MXNet - Python API gluon
- Apache MXNet - Python API autograd 和初始化器
- Apache MXNet - Python API 符號
- Apache MXNet - Python API Module
- Apache MXNet 有用資源
- Apache MXNet - 快速指南
- Apache MXNet - 有用資源
- Apache MXNet - 討論
Apache MXNet - Python API 符號
本章我們將學習 MXNet 中一個稱為符號 (Symbol) 的介面。
Mxnet.ndarray
Apache MXNet 的符號 API 是一個用於符號程式設計的介面。符號 API 的特點包括:
計算圖
減少記憶體使用
預用函式最佳化
以下示例展示瞭如何使用 MXNet 的符號 API 建立簡單的表示式:
使用來自普通 Python 列表的 1-D 和 2-D '陣列' 建立 NDArray:
import mxnet as mx
# Two placeholders namely x and y will be created with mx.sym.variable
x = mx.sym.Variable('x')
y = mx.sym.Variable('y')
# The symbol here is constructed using the plus ‘+’ operator.
z = x + y
輸出
您將看到以下輸出:
<Symbol _plus0>
示例
(x, y, z)
輸出
輸出如下:
(<Symbol x>, <Symbol y>, <Symbol _plus0>)
現在讓我們詳細討論 MXNet 的 ndarray API 的類、函式和引數。
類
下表包含 MXNet 符號 API 的類:
| 類 | 定義 |
|---|---|
| Symbol(handle) | 這個名為 symbol 的類是 Apache MXNet 的符號圖。 |
函式及其引數
以下是 mxnet.Symbol API 中涵蓋的一些重要函式及其引數:
| 函式及其引數 | 定義 |
|---|---|
| Activation([data, act_type, out, name]) | 它對輸入應用逐元素啟用函式。它支援 **relu、sigmoid、tanh、softrelu、softsign** 啟用函式。 |
| BatchNorm([data, gamma, beta, moving_mean, …]) | 用於批次歸一化。此函式透過均值和方差對資料批進行歸一化。它應用比例因子 **gamma** 和偏移量 **beta**。 |
| BilinearSampler([data, grid, cudnn_off, …]) | 此函式將雙線性取樣應用於輸入特徵圖。實際上它是“空間變換網路”的關鍵。如果您熟悉 OpenCV 中的重對映函式,則此函式的用法與之非常相似。唯一的區別是它具有反向傳播。 |
| BlockGrad([data, out, name]) | 顧名思義,此函式停止梯度計算。它基本上阻止輸入的累積梯度在反向傳播中透過此運算子。 |
| cast([data, dtype, out, name]) | 此函式會將輸入的所有元素轉換為新型別。 |
| 此函式會將輸入的所有元素轉換為新型別。 | 此函式顧名思義,返回具有給定形狀和型別的新的符號,並填充零。 |
| ones(shape[, dtype]) | 此函式顧名思義,返回具有給定形狀和型別的新的符號,並填充一。 |
| full(shape, val[, dtype]) | 此函式顧名思義,返回具有給定形狀和型別的新的陣列,並填充給定的值 **val**。 |
| arange(start[, stop, step, repeat, …]) | 它將返回給定區間內的均勻間隔的值。這些值在半開區間 [start, stop) 內生成,這意味著該區間包含 **start** 但不包含 **stop**。 |
| linspace(start, stop, num[, endpoint, name, …]) | 它將返回指定區間內的均勻間隔的數字。與函式 arrange() 類似,這些值在半開區間 [start, stop) 內生成,這意味著該區間包含 **start** 但不包含 **stop**。 |
| histogram(a[, bins, range]) | 顧名思義,此函式將計算輸入資料的直方圖。 |
| power(base, exp) | 顧名思義,此函式將返回 **base** 元素的逐元素結果,其冪來自 **exp** 元素。兩個輸入(即 base 和 exp)都可以是符號或標量。這裡需要注意的是不允許廣播。如果要使用廣播功能,可以使用 **broadcast_pow**。 |
| SoftmaxActivation([data, mode, name, attr, out]) | 此函式將 softmax 啟用應用於輸入。它適用於內部層。它實際上已棄用,我們可以使用 **softmax()** 代替。 |
實現示例
在下面的示例中,我們將使用函式 **power()**,它將返回 base 元素的逐元素結果,其冪來自 exp 元素。
import mxnet as mx mx.sym.power(3, 5)
輸出
您將看到以下輸出:
243
示例
x = mx.sym.Variable('x')
y = mx.sym.Variable('y')
z = mx.sym.power(x, 3)
z.eval(x=mx.nd.array([1,2]))[0].asnumpy()
輸出
這將產生以下輸出:
array([1., 8.], dtype=float32)
示例
z = mx.sym.power(4, y) z.eval(y=mx.nd.array([2,3]))[0].asnumpy()
輸出
執行上述程式碼時,您應該看到以下輸出:
array([16., 64.], dtype=float32)
示例
z = mx.sym.power(x, y) z.eval(x=mx.nd.array([4,5]), y=mx.nd.array([2,3]))[0].asnumpy()
輸出
輸出如下:
array([ 16., 125.], dtype=float32)
在下面的示例中,我們將使用函式 **SoftmaxActivation()(或 softmax())**,它將應用於輸入,並適用於內部層。
input_data = mx.nd.array([[2., 0.9, -0.5, 4., 8.], [4., -.7, 9., 2., 0.9]]) soft_max_act = mx.nd.softmax(input_data) print (soft_max_act.asnumpy())
輸出
您將看到以下輸出:
[[2.4258138e-03 8.0748333e-04 1.9912292e-04 1.7924475e-02 9.7864312e-01] [6.6843745e-03 6.0796250e-05 9.9204916e-01 9.0463174e-04 3.0112563e-04]]
symbol.contrib
Contrib NDArray API 定義在 symbol.contrib 包中。它通常為新功能提供許多有用的實驗性 API。此 API 作為社群嘗試新功能的地方。功能貢獻者也將獲得反饋。
函式及其引數
以下是 **mxnet.symbol.contrib API** 中涵蓋的一些重要函式及其引數:
| 函式及其引數 | 定義 |
|---|---|
| rand_zipfian(true_classes, num_sampled, …) | 此函式從近似齊夫分佈中抽取隨機樣本。此函式的基本分佈是齊夫分佈。此函式隨機取樣 num_sampled 個候選樣本,並且 sampled_candidates 的元素是從上面給出的基本分佈中抽取的。 |
| foreach(body, data, init_states) | 顧名思義,此函式在維度 0 上對 NDArray 執行具有使用者定義計算的迴圈。此函式模擬 for 迴圈,body 具有 for 迴圈迭代的計算。 |
| while_loop(cond, func, loop_vars[, …]) | 顧名思義,此函式執行具有使用者定義計算和迴圈條件的 while 迴圈。此函式模擬一個 while 迴圈,如果滿足條件,則逐字進行自定義計算。 |
| cond(pred, then_func, else_func) | 顧名思義,此函式使用使用者定義的條件和計算執行 if-then-else。此函式模擬一個 if 式分支,根據指定的條件選擇執行兩種自定義計算之一。 |
| getnnz([data, axis, out, name]) | 此函式為我們提供稀疏張量的儲存值的數量。它還包括顯式零。它僅支援 CPU 上的 CSR 矩陣。 |
| requantize([data, min_range, max_range, …]) | 此函式使用在執行時計算或來自校準的最小和最大閾值,將以 int32 量化的給定資料及其相應的閾值重新量化為 int8。 |
| index_copy([old_tensor, index_vector, …]) | 此函式透過按 index 中給出的順序選擇索引,將 **new_tensor** 的元素複製到 **old_tensor** 中。此運算子的輸出將是一個新的張量,其中包含 old_tensor 的其餘元素和 new_tensor 的複製元素。 |
| interleaved_matmul_encdec_qk([queries, …]) | 此運算子計算多頭注意力中查詢和鍵的投影之間的矩陣乘法,用作編碼器-解碼器。條件是輸入應該是查詢投影的張量,其佈局如下:(seq_length,batch_size,num_heads*,head_dim)。 |
實現示例
在下面的示例中,我們將使用 rand_zipfian 函式從近似齊夫分佈中抽取隨機樣本:
import mxnet as mx
true_cls = mx.sym.Variable('true_cls')
samples, exp_count_true, exp_count_sample = mx.sym.contrib.rand_zipfian(true_cls, 5, 6)
samples.eval(true_cls=mx.nd.array([3]))[0].asnumpy()
輸出
您將看到以下輸出:
array([4, 0, 2, 1, 5], dtype=int64)
示例
exp_count_true.eval(true_cls=mx.nd.array([3]))[0].asnumpy()
輸出
輸出如下:
array([0.57336551])
示例
exp_count_sample.eval(true_cls=mx.nd.array([3]))[0].asnumpy()
輸出
您將看到以下輸出:
array([1.78103594, 0.46847373, 1.04183923, 0.57336551, 1.04183923])
在下面的示例中,我們將使用 **while_loop** 函式執行使用者定義計算和迴圈條件的 while 迴圈:
cond = lambda i, s: i <= 7
func = lambda i, s: ([i + s], [i + 1, s + i])
loop_vars = (mx.sym.var('i'), mx.sym.var('s'))
outputs, states = mx.sym.contrib.while_loop(cond, func, loop_vars, max_iterations=10)
print(outputs)
輸出
輸出如下
[<Symbol _while_loop0>]
示例
Print(States)
輸出
這將產生以下輸出:
[<Symbol _while_loop0>, <Symbol _while_loop0>]
在下面的示例中,我們將使用 **index_copy** 函式將 new_tensor 的元素複製到 old_tensor 中。
import mxnet as mx a = mx.nd.zeros((6,3)) b = mx.nd.array([[1,2,3],[4,5,6],[7,8,9]]) index = mx.nd.array([0,4,2]) mx.nd.contrib.index_copy(a, index, b)
輸出
執行上述程式碼時,您應該看到以下輸出:
[[1. 2. 3.] [0. 0. 0.] [7. 8. 9.] [0. 0. 0.] [4. 5. 6.] [0. 0. 0.]] <NDArray 6x3 @cpu(0)>
symbol.image
影像符號 API 定義在 symbol.image 包中。顧名思義,它通常用於影像及其特徵。
函式及其引數
以下是 **mxnet.symbol.image API** 中涵蓋的一些重要函式及其引數:
| 函式及其引數 | 定義 |
|---|---|
| adjust_lighting([data, alpha, out, name]) | 顧名思義,此函式調整輸入的亮度級別。它遵循 AlexNet 風格。 |
| crop([data, x, y, width, height, out, name]) | 藉助此函式,我們可以將形狀為 (H x W x C) 或 (N x H x W x C) 的影像 NDArray 裁剪為使用者給定的尺寸。 |
| normalize([data, mean, std, out, name]) | 它將使用 **均值** 和 **標準差 (SD)** 對形狀為 (C x H x W) 或 (N x C x H x W) 的張量進行歸一化。 |
| random_crop([data, xrange, yrange, width, …]) | 與 crop() 類似,它將形狀為 (H x W x C) 或 (N x H x W x C) 的影像 NDArray 隨機裁剪為使用者給定的尺寸。如果 **src** 小於 **size**,它將對結果進行上取樣。 |
| **random_lighting**([data, alpha_std, out, name]) | 顧名思義,此函式隨機新增 PCA 噪聲。它也遵循 AlexNet 風格。 |
| random_resized_crop([data, xrange, yrange, …]) | 它還將形狀為 (H x W x C) 或 (N x H x W x C) 的影像 NDArray 隨機裁剪為給定尺寸。如果 src 小於 size,它將對結果進行上取樣。它還將隨機化區域和縱橫比。 |
| resize([data, size, keep_ratio, interp, …]) | 顧名思義,此函式將形狀為 (H x W x C) 或 (N x H x W x C) 的影像 NDArray 調整為使用者給定的尺寸。 |
| to_tensor([data, out, name]) | 它將形狀為 (H x W x C) 或 (N x H x W x C) 且值在 [0, 255] 範圍內的影像 NDArray 轉換為形狀為 (C x H x W) 或 (N x C x H x W) 且值在 [0, 1] 範圍內的張量 NDArray。 |
實現示例
在下面的示例中,我們將使用 to_tensor 函式將形狀為 (H x W x C) 或 (N x H x W x C) 且值在 [0, 255] 範圍內的影像 NDArray 轉換為形狀為 (C x H x W) 或 (N x C x H x W) 且值在 [0, 1] 範圍內的張量 NDArray。
import numpy as np img = mx.sym.random.uniform(0, 255, (4, 2, 3)).astype(dtype=np.uint8) mx.sym.image.to_tensor(img)
輸出
輸出如下所示:
<Symbol to_tensor4>
示例
img = mx.sym.random.uniform(0, 255, (2, 4, 2, 3)).astype(dtype=np.uint8) mx.sym.image.to_tensor(img)
輸出
輸出如下所示
<Symbol to_tensor5>
在下面的示例中,我們將使用函式normalize()來歸一化形狀為(C x H x W)或(N x C x H x W)的張量,並使用均值和標準差(SD)。
img = mx.sym.random.uniform(0, 1, (3, 4, 2)) mx.sym.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))
輸出
程式碼輸出如下:
<Symbol normalize0>
示例
img = mx.sym.random.uniform(0, 1, (2, 3, 4, 2)) mx.sym.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))
輸出
輸出如下所示:
<Symbol normalize1>
symbol.random
隨機符號API定義在symbol.random包中。顧名思義,它是MXNet的隨機分佈生成器符號API。
函式及其引數
以下是mxnet.symbol.random API涵蓋的一些重要函式及其引數:
| 函式及其引數 | 定義 |
|---|---|
| uniform([low, high, shape, dtype, ctx, out]) | 它從均勻分佈中生成隨機樣本。 |
| normal([loc, scale, shape, dtype, ctx, out]) | 它從正態(高斯)分佈中生成隨機樣本。 |
| randn(*shape, **kwargs) | 它從正態(高斯)分佈中生成隨機樣本。 |
| poisson([lam, shape, dtype, ctx, out]) | 它從泊松分佈中生成隨機樣本。 |
| exponential([scale, shape, dtype, ctx, out]) | 它從指數分佈中生成樣本。 |
| gamma([alpha, beta, shape, dtype, ctx, out]) | 它從伽馬分佈中生成隨機樣本。 |
| multinomial(data[, shape, get_prob, out, dtype]) | 它從多個多項分佈中生成併發取樣。 |
| negative_binomial([k, p, shape, dtype, ctx, out]) | 它從負二項分佈中生成隨機樣本。 |
| generalized_negative_binomial([mu, alpha, …]) | 它從廣義負二項分佈中生成隨機樣本。 |
| shuffle(data, **kwargs) | 它隨機打亂元素。 |
| randint(low, high[, shape, dtype, ctx, out]) | 它從離散均勻分佈中生成隨機樣本。 |
| exponential_like([data, lam, out, name]) | 它根據輸入陣列形狀從指數分佈中生成隨機樣本。 |
| gamma_like([data, alpha, beta, out, name]) | 它根據輸入陣列形狀從伽馬分佈中生成隨機樣本。 |
| generalized_negative_binomial_like([data, …]) | 它根據輸入陣列形狀從廣義負二項分佈中生成隨機樣本。 |
| negative_binomial_like([data, k, p, out, name]) | 它根據輸入陣列形狀從負二項分佈中生成隨機樣本。 |
| normal_like([data, loc, scale, out, name]) | 它根據輸入陣列形狀從正態(高斯)分佈中生成隨機樣本。 |
| poisson_like([data, lam, out, name]) | 它根據輸入陣列形狀從泊松分佈中生成隨機樣本。 |
| uniform_like([data, low, high, out, name]) | 它根據輸入陣列形狀從均勻分佈中生成隨機樣本。 |
實現示例
在下面的示例中,我們將使用shuffle()函式隨機打亂元素。它將沿第一個軸打亂陣列。
data = mx.nd.array([[0, 1, 2], [3, 4, 5], [6, 7, 8],[9,10,11]])
x = mx.sym.Variable('x')
y = mx.sym.random.shuffle(x)
y.eval(x=data)
輸出
您將看到以下輸出:
[ [[ 9. 10. 11.] [ 0. 1. 2.] [ 6. 7. 8.] [ 3. 4. 5.]] <NDArray 4x3 @cpu(0)>]
示例
y.eval(x=data)
輸出
執行上述程式碼時,您應該看到以下輸出:
[ [[ 6. 7. 8.] [ 0. 1. 2.] [ 3. 4. 5.] [ 9. 10. 11.]] <NDArray 4x3 @cpu(0)>]
在下面的示例中,我們將從廣義負二項分佈中抽取隨機樣本。為此,我們將使用函式generalized_negative_binomial()。
mx.sym.random.generalized_negative_binomial(10, 0.1)
輸出
輸出如下:
<Symbol _random_generalized_negative_binomial0>
symbol.sparse
稀疏符號API定義在mxnet.symbol.sparse包中。顧名思義,它提供稀疏神經網路圖和CPU上的自動微分。
函式及其引數
以下是mxnet.symbol.sparse API涵蓋的一些重要函式(包括符號建立例程、符號操作例程、數學函式、三角函式、雙曲函式、約簡函式、舍入、冪、神經網路)及其引數:
| 函式及其引數 | 定義 |
|---|---|
| ElementWiseSum(*args, **kwargs) | 此函式將逐元素相加所有輸入引數。例如,𝑎𝑑𝑑_𝑛(𝑎1,𝑎2,…𝑎𝑛=𝑎1+𝑎2+⋯+𝑎𝑛)。在這裡,我們可以看到add_n可能比呼叫n次add更高效。 |
| Embedding([data, weight, input_dim, …]) | 它將整數索引對映到向量表示,即嵌入。它實際上將單詞對映到高維空間中的實值向量,這稱為詞嵌入。 |
| LinearRegressionOutput([data, label, …]) | 在反向傳播過程中計算並最佳化平方損失,在正向傳播過程中僅給出輸出資料。 |
| LogisticRegressionOutput([data, label, …]) | 將邏輯函式(也稱為sigmoid函式)應用於輸入。該函式計算為1/1+exp(−x)。 |
| MAERegressionOutput([data, label, …]) | 此運算子計算輸入的平均絕對誤差。MAE實際上是對應於絕對誤差期望值的風險度量。 |
| abs([data, name, attr, out]) | 顧名思義,此函式將返回輸入的逐元素絕對值。 |
| adagrad_update([weight, grad, history, lr, …]) | 它是AdaGrad最佳化器的更新函式。 |
| adam_update([weight, grad, mean, var, lr, …]) | 它是Adam最佳化器的更新函式。 |
| add_n(*args, **kwargs) | 顧名思義,它將逐元素相加所有輸入引數。 |
| arccos([data, name, attr, out]) | 此函式將返回輸入陣列的逐元素反餘弦。 |
| dot([lhs, rhs, transpose_a, transpose_b, …]) | 顧名思義,它將給出兩個陣列的點積。它將取決於輸入陣列維度:一維:向量的內積;二維:矩陣乘法;N維:第一個輸入的最後一個軸和第二個輸入的第一個軸上的和積。 |
| elemwise_add([lhs, rhs, name, attr, out]) | 顧名思義,它將相加引數的逐元素值。 |
| elemwise_div([lhs, rhs, name, attr, out]) | 顧名思義,它將相除引數的逐元素值。 |
| elemwise_mul([lhs, rhs, name, attr, out]) | 顧名思義,它將相乘引數的逐元素值。 |
| elemwise_sub([lhs, rhs, name, attr, out]) | 顧名思義,它將相減引數的逐元素值。 |
| exp([data, name, attr, out]) | 此函式將返回給定輸入的逐元素指數值。 |
| sgd_update([weight, grad, lr, wd, …]) | 它充當隨機梯度下降最佳化器的更新函式。 |
| sigmoid([data, name, attr, out]) | 顧名思義,它將計算x的逐元素sigmoid值。 |
| sign([data, name, attr, out]) | 它將返回給定輸入的逐元素符號。 |
| sin([data, name, attr, out]) | 顧名思義,此函式將計算給定輸入陣列的逐元素正弦。 |
實現示例
在下面的示例中,我們將使用ElementWiseSum()函式隨機打亂元素。它將整數索引對映到向量表示,即詞嵌入。
input_dim = 4 output_dim = 5
示例
/* Here every row in weight matrix y represents a word. So, y = (w0,w1,w2,w3) y = [[ 0., 1., 2., 3., 4.], [ 5., 6., 7., 8., 9.], [ 10., 11., 12., 13., 14.], [ 15., 16., 17., 18., 19.]] /* Here input array x represents n-grams(2-gram). So, x = [(w1,w3), (w0,w2)] x = [[ 1., 3.], [ 0., 2.]] /* Now, Mapped input x to its vector representation y. Embedding(x, y, 4, 5) = [[[ 5., 6., 7., 8., 9.], [ 15., 16., 17., 18., 19.]], [[ 0., 1., 2., 3., 4.], [ 10., 11., 12., 13., 14.]]]