Apache MXNet - Python API ndarray



本章介紹 Apache MXNet 中提供的 ndarray 庫。

Mxnet.ndarray

Apache MXNet 的 NDArray 庫定義了所有數學計算的核心 DS(資料結構)。NDArray 的兩個基本作用如下:

  • 它支援在各種硬體配置上快速執行。

  • 它自動跨可用硬體並行化多個操作。

以下示例顯示瞭如何使用來自常規 Python 列表的 1-D 和 2-D“陣列”建立 NDArray:

import mxnet as mx
from mxnet import nd

x = nd.array([1,2,3,4,5,6,7,8,9,10])
print(x)

輸出

輸出如下所示

[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
<NDArray 10 @cpu(0)>

示例

y = nd.array([[1,2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9,10]])
print(y)

輸出

這將產生以下輸出:

[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
 [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
 [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]]
<NDArray 3x10 @cpu(0)>

現在讓我們詳細討論 MXNet 的 ndarray API 的類、函式和引數。

下表包含 MXNet 的 ndarray API 的類:

定義
CachedOp(sym[, flags]) 用於快取操作控制代碼。
NDArray(handle[, writable]) 用作表示多維、同構的固定大小項陣列的陣列物件。

函式及其引數

以下是 mxnet.ndarray 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 中的 remap 函式,則此函式的用法與此非常相似。唯一的區別是它具有反向傳播。

BlockGrad([data, out, name]) 顧名思義,此函式停止梯度計算。它基本上阻止了輸入的累積梯度在反向方向上透過此運算子流動。
cast([data, dtype, out, name]) 此函式將輸入的所有元素轉換為新型別。

實現示例

在下面的示例中,我們將使用 BilinierSampler() 函式將資料縮小兩倍並將資料水平移動 -1 畫素:

import mxnet as mx
from mxnet import nd
data = nd.array([[[[2, 5, 3, 6],
   [1, 8, 7, 9],
   [0, 4, 1, 8],
   [2, 0, 3, 4]]]])
affine_matrix = nd.array([[2, 0, 0],
   [0, 2, 0]])

affine_matrix = nd.reshape(affine_matrix, shape=(1, 6))

grid = nd.GridGenerator(data=affine_matrix, transform_type='affine', target_shape=(4, 4))

output = nd.BilinearSampler(data, grid)

輸出

執行上述程式碼後,您應該會看到以下輸出

[[[[0. 0. 0. 0. ]
   [0. 4.0000005 6.25 0. ]
   [0. 1.5 4. 0. ]
   [0. 0. 0. 0. ]]]]
<NDArray 1x1x4x4 @cpu(0)>

以上輸出顯示了資料縮小兩倍。

將資料移動 -1 畫素的示例如下:

import mxnet as mx
from mxnet import nd
data = nd.array([[[[2, 5, 3, 6],
   [1, 8, 7, 9],
   [0, 4, 1, 8],
   [2, 0, 3, 4]]]])
warp_matrix = nd.array([[[[1, 1, 1, 1],
   [1, 1, 1, 1],
   [1, 1, 1, 1],
   [1, 1, 1, 1]],
   [[0, 0, 0, 0],
   [0, 0, 0, 0],
   [0, 0, 0, 0],
   [0, 0, 0, 0]]]])
grid = nd.GridGenerator(data=warp_matrix, transform_type='warp')
output = nd.BilinearSampler(data, grid)

輸出

輸出如下所示:

[[[[5. 3. 6. 0.]
[8. 7. 9. 0.]
[4. 1. 8. 0.]
[0. 3. 4. 0.]]]]
<NDArray 1x1x4x4 @cpu(0)>

類似地,以下示例顯示了 cast() 函式的使用:

nd.cast(nd.array([300, 10.1, 15.4, -1, -2]), dtype='uint8')

輸出

執行後,您將收到以下輸出:

[ 44 10 15 255 254]
<NDArray 5 @cpu(0)>

ndarray.contrib

Contrib NDArray API 在 ndarray.contrib 包中定義。它通常為新功能提供許多有用的實驗性 API。此 API 作為社群嘗試新功能的地方。功能貢獻者也將獲得反饋。

函式及其引數

以下是 mxnet.ndarray.contrib API 涵蓋的一些重要函式及其引數:

函式及引數 定義
rand_zipfian(true_classes, num_sampled, …) 此函式從近似齊夫分佈中抽取隨機樣本。此函式的基本分佈是齊夫分佈。此函式隨機抽取 num_sampled 個候選樣本,並且 sampled_candidates 的元素是從上面給出的基本分佈中抽取的。
foreach(body, data, init_states) 顧名思義,此函式在維度 0 上對 NDArrays 執行一個帶有使用者定義計算的 for 迴圈。此函式模擬一個 for 迴圈,body 包含 for 迴圈迭代的計算。
while_loop(cond, func, loop_vars[, …]) 顧名思義,此函式執行一個帶有使用者定義計算和迴圈條件的 while 迴圈。此函式模擬一個 while 迴圈,如果條件滿足,則按字面意思執行自定義計算。
cond(pred, then_func, else_func) 顧名思義,此函式使用使用者定義的條件和計算執行 if-then-else。此函式模擬一個 if 型別的分支,根據指定的條件選擇執行兩個自定義計算之一。
isinf(data) 此函式執行按元素檢查以確定 NDArray 是否包含無限元素。
getnnz([data, axis, out, name]) 此函式提供稀疏張量的儲存值的數目。它還包括顯式零。它僅支援 CPU 上的 CSR 矩陣。
requantize([data, min_range, max_range, …]) 此函式將以 int32 量化的給定資料及其相應的閾值重新量化為 int8,使用在執行時計算或來自校準的最小和最大閾值。

實現示例

在下面的示例中,我們將使用 rand_zipfian 函式從近似齊夫分佈中抽取隨機樣本:

import mxnet as mx
from mxnet import nd
trueclass = mx.nd.array([2])
samples, exp_count_true, exp_count_sample = mx.nd.contrib.rand_zipfian(trueclass, 3, 4)
samples

輸出

您將看到以下輸出:

[0 0 1]
<NDArray 3 @cpu(0)>

示例

exp_count_true

輸出

輸出如下所示

[0.53624076]
<NDArray 1 @cpu(0)>

示例

exp_count_sample

輸出

這將產生以下輸出

[1.29202967 1.29202967 0.75578891]
<NDArray 3 @cpu(0)>

在下面的示例中,我們將使用 while_loop 函式執行一個帶有使用者定義計算和迴圈條件的 while 迴圈

cond = lambda i, s: i <= 7
func = lambda i, s: ([i + s], [i + 1, s + i])
loop_var = (mx.nd.array([0], dtype="int64"), mx.nd.array([1], dtype="int64"))
outputs, states = mx.nd.contrib.while_loop(cond, func, loop_vars, max_iterations=10)
outputs

輸出

輸出如下所示:

[
[[       1]
 [      2]
 [      4]
 [      7]
 [     11]
 [     16]
 [     22]
 [     29]
 [3152434450384]
 [     257]]
<NDArray 10x1 @cpu(0)>]

示例

States

輸出

這將產生以下輸出:

[
[8]
<NDArray 1 @cpu(0)>,
[29]
<NDArray 1 @cpu(0)>]

ndarray.image

Image NDArray API 在 ndarray.image 包中定義。顧名思義,它通常用於影像及其特徵。

函式及其引數

以下是 mxnet.ndarray.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]) 它將形狀為 (C x H x W) 或 (N x C x H x W) 的張量與 均值標準差 (SD) 進行歸一化。
random_crop([data, xrange, yrange, width, …]) 與 crop() 類似,它隨機裁剪形狀為 (H x W x C) 或 (N x H x W x C) 的影像 NDArray 到使用者給定的尺寸。如果源影像小於該尺寸,它將對結果進行上取樣。
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 到給定尺寸。如果源影像小於該尺寸,它將對結果進行上取樣。它也將隨機化區域和縱橫比。
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.nd.random.uniform(0, 255, (4, 2, 3)).astype(dtype=np.uint8)
mx.nd.image.to_tensor(img)

輸出

您將看到以下輸出:

[[[0.972549 0.5058824 ]
   [0.6039216 0.01960784]
   [0.28235295 0.35686275]
   [0.11764706 0.8784314 ]]

[[0.8745098 0.9764706 ]
   [0.4509804 0.03529412]
   [0.9764706 0.29411766]
   [0.6862745 0.4117647 ]]

[[0.46666667 0.05490196]
   [0.7372549 0.4392157 ]
   [0.11764706 0.47843137]
   [0.31764707 0.91764706]]]
<NDArray 3x4x2 @cpu(0)>

示例

img = mx.nd.random.uniform(0, 255, (2, 4, 2, 3)).astype(dtype=np.uint8)

mx.nd.image.to_tensor(img)

輸出

執行程式碼後,您將看到以下輸出:

[[[[0.0627451 0.5647059 ]
[0.2627451 0.9137255 ]
[0.57254905 0.27450982]
[0.6666667 0.64705884]]
[[0.21568628 0.5647059 ]
[0.5058824 0.09019608]
[0.08235294 0.31764707]
[0.8392157 0.7137255 ]]
[[0.6901961 0.8627451 ]
[0.52156866 0.91764706]
[0.9254902 0.00784314]
[0.12941177 0.8392157 ]]]
[[[0.28627452 0.39607844]
[0.01960784 0.36862746]
[0.6745098 0.7019608 ]
[0.9607843 0.7529412 ]]
[[0.2627451 0.58431375]
[0.16470589 0.00392157]
[0.5686275 0.73333335]
[0.43137255 0.57254905]]
[[0.18039216 0.54901963]
[0.827451 0.14509805]
[0.26666668 0.28627452]
[0.24705882 0.39607844]]]]
<NDArgt;ray 2x3x4x2 @cpu(0)>

在下面的示例中,我們將使用 normalize 函式將形狀為 (C x H x W) 或 (N x C x H x W) 的張量與 均值標準差 (SD) 進行歸一化。

img = mx.nd.random.uniform(0, 1, (3, 4, 2))

mx.nd.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))

輸出

這將產生以下輸出:

[[[ 0.29391178 0.3218054 ]
[ 0.23084386 0.19615503]
[ 0.24175143 0.21988946]
[ 0.16710812 0.1777354 ]]
[[-0.02195817 -0.3847335 ]
[-0.17800489 -0.30256534]
[-0.28807247 -0.19059572]
[-0.19680339 -0.26256624]]
[[-1.9808068 -1.5298678 ]
[-1.6984252 -1.2839255 ]
[-1.3398265 -1.712009 ]
[-1.7099224 -1.6165378 ]]]
<NDArray 3x4x2 @cpu(0)>

示例

img = mx.nd.random.uniform(0, 1, (2, 3, 4, 2))

mx.nd.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))

輸出

執行上述程式碼後,您應該會看到以下輸出:

[[[[ 2.0600514e-01 2.4972327e-01]
[ 1.4292289e-01 2.9281738e-01]
[ 4.5158025e-02 3.4287784e-02]
[ 9.9427439e-02 3.0791296e-02]]
[[-2.1501756e-01 -3.2297665e-01]
[-2.0456362e-01 -2.2409186e-01]
[-2.1283737e-01 -4.8318747e-01]
[-1.7339960e-01 -1.5519112e-02]]
[[-1.3478968e+00 -1.6790028e+00]
[-1.5685816e+00 -1.7787373e+00]
[-1.1034534e+00 -1.8587360e+00]
[-1.6324382e+00 -1.9027401e+00]]]
[[[ 1.4528830e-01 3.2801408e-01]
[ 2.9730779e-01 8.6780310e-02]
[ 2.6873133e-01 1.7900752e-01]
[ 2.3462953e-01 1.4930873e-01]]
[[-4.4988656e-01 -4.5021546e-01]
[-4.0258706e-02 -3.2384416e-01]
[-1.4287934e-01 -2.6537544e-01]
[-5.7649612e-04 -7.9429924e-02]]
[[-1.8505517e+00 -1.0953522e+00]
[-1.1318740e+00 -1.9624406e+00]
[-1.8375070e+00 -1.4916846e+00]
[-1.3844404e+00 -1.8331525e+00]]]]
<NDArray 2x3x4x2 @cpu(0)>

ndarray.random

Random NDArray API 在 ndarray.random 包中定義。顧名思義,它是 MXNet 的隨機分佈生成器 NDArray API。

函式及其引數

以下是 mxnet.ndarray.random API 涵蓋的一些重要函式及其引數:

函式及其引數 定義
uniform([low, high, shape, dtype, ctx, out]) 它從均勻分佈中生成隨機樣本。
normal([loc, scale, shape, dtype, ctx, out]) 它從正態(高斯)分佈中生成隨機樣本。
randn(*shape, **kwargs) 它從正態(高斯)分佈中生成隨機樣本。
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]) 它根據輸入陣列形狀從均勻分佈中生成隨機樣本。

實現示例

在下面的示例中,我們將從均勻分佈中抽取隨機樣本。為此,我們將使用 uniform() 函式。

mx.nd.random.uniform(0, 1)

輸出

輸出如下所示:

[0.12381998]
<NDArray 1 @cpu(0)>

示例

mx.nd.random.uniform(-1, 1, shape=(2,))

輸出

輸出如下所示:

[0.558102 0.69601643]
<NDArray 2 @cpu(0)>

示例

low = mx.nd.array([1,2,3])
high = mx.nd.array([2,3,4])
mx.nd.random.uniform(low, high, shape=2)

輸出

您將看到以下輸出:

[[1.8649333 1.8073189]
 [2.4113967 2.5691009]
 [3.1399727 3.4071832]]
<NDArray 3x2 @cpu(0)>

在下面的示例中,我們將從廣義負二項分佈中抽取隨機樣本。為此,我們將使用 generalized_negative_binomial() 函式。

mx.nd.random.generalized_negative_binomial(10, 0.5)

輸出

執行上述程式碼後,您應該會看到以下輸出:

[1.]
<NDArray 1 @cpu(0)>

示例

mx.nd.random.generalized_negative_binomial(10, 0.5, shape=(2,))

輸出

輸出如下所示:

[16. 23.]
<NDArray 2 @cpu(0)>

示例

mu = mx.nd.array([1,2,3])
alpha = mx.nd.array([0.2,0.4,0.6])
mx.nd.random.generalized_negative_binomial(mu, alpha, shape=2)

輸出

以下是程式碼的輸出:

[[0. 0.]
 [4. 1.]
 [9. 3.]]
<NDArray 3x2 @cpu(0)>

ndarray.utils

實用程式 NDArray API 在 ndarray.utils 包中定義。顧名思義,它為 NDArray 和 BaseSparseNDArray 提供實用程式函式。

函式及其引數

以下是 mxnet.ndarray.utils API 涵蓋的一些重要函式及其引數:

函式及其引數 定義
zeros(shape[, ctx, dtype, stype]) 此函式將返回一個具有給定形狀和型別的新陣列,並填充零。

empty(shape[, ctx, dtype, stype]) 它將返回一個具有給定形狀和型別的新陣列,但不初始化條目。
array(source_array[, ctx, dtype]) 顧名思義,此函式將從任何公開陣列介面的物件建立陣列。
load(fname) 它將從檔案載入陣列。
load_frombuffer(buf) 顧名思義,此函式將從緩衝區載入陣列字典或列表。
save(fname, data) 此函式將陣列列表或 str->array 的字典儲存到檔案。

實現示例

在下面的示例中,我們將返回一個具有給定形狀和型別的新陣列,並用零填充。為此,我們將使用函式zeros()

mx.nd.zeros((1,2), mx.cpu(), stype='csr')

輸出

這將產生以下輸出:

<CSRNDArray 1x2 @cpu(0)>

示例

mx.nd.zeros((1,2), mx.cpu(), 'float16', stype='row_sparse').asnumpy()

輸出

您將收到以下輸出:

array([[0., 0.]], dtype=float16)

在下面的示例中,我們將儲存一個數組列表和一個字串字典。為此,我們將使用函式save()

示例

x = mx.nd.zeros((2,3))
y = mx.nd.ones((1,4))
mx.nd.save('list', [x,y])
mx.nd.save('dict', {'x':x, 'y':y})
mx.nd.load('list')

輸出

執行後,您將收到以下輸出:

[
[[0. 0. 0.]
[0. 0. 0.]]
<NDArray 2x3 @cpu(0)>,
[[1. 1. 1. 1.]]
<NDArray 1x4 @cpu(0)>]

示例

mx.nd.load('my_dict')

輸出

輸出如下所示:

{'x':
[[0. 0. 0.]
[0. 0. 0.]]
<NDArray 2x3 @cpu(0)>, 'y':
[[1. 1. 1. 1.]]
<NDArray 1x4 @cpu(0)>}
廣告