- 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.]]]