Apache Mxnet 简明教程
Apache MXNet - Python API Symbol
在本章中,我们将了解 MXNet 中的一个接口,该接口被称为 Symbol。
Mxnet.ndarray
Apache MXNet 的 Symbol API 是用于符号编程的接口。Symbol API 的特点是使用以下功能 −
-
Computational graphs
-
Reduced memory usage
-
Pre-use function optimization
以下给出的示例演示了如何使用 MXNet 的 Symbol 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
Output
您将看到以下输出 −
<Symbol _plus0>
Example
(x, y, z)
Output
输出如下 −
(<Symbol x>, <Symbol y>, <Symbol _plus0>)
现在,让我们详细讨论 MXNet 的 ndarray API 的类、函数和参数。
Classes
下表包含了 MXNet 的 Symbol API 的类 −
Class |
Definition |
Symbol(handle) |
这个名为 symbol 的类是 Apache MXNet 的符号图。 |
Functions and their parameters
以下是一些 mxnet.Symbol API 涵盖的重要函数及其参数 −
Function and its Parameters |
Definition |
Activation([data, act_type, out, name]) |
它将激活函数逐元素应用到输入。它支持 relu, sigmoid, tanh, softrelu, softsign 激活函数。 |
BatchNorm([data, gamma, beta, moving_mean, …]) |
它用于批标准化。此函数通过均值和方差对数据批进行标准化。它应用比例 gamma *and offset *beta 。 |
BilinearSampler([data, grid, cudnn_off, …]) |
此函数对输入特征图应用双线性采样。实际上,它是“空间转换器网络”的关键。如果您熟悉 OpenCV 中的 remap 函数,此函数的使用与它非常相似。唯一的区别是它有反向传递。 |
BlockGrad([data, out, name]) |
根据名称指定,此函数停止渐变计算。它基本上阻止输入的累积梯度通过反向流过该运算符。 |
cast([data, dtype, out, name]) |
此函数将把输入的所有元素转换为新类型。 |
此函数将把输入的所有元素转换为新类型。 |
此函数,如名称所指定,返回给定形状和类型的带有零的新符号。 |
ones(shape[, dtype]) |
此函数,如名称所指定,返回给定形状和类型的带有 1 的新符号。 |
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) |
顾名思义,此函数将返回 exp 元素中 base 元素求幂的逐元素结果。两个输入(即 base 和 exp)都可以是符号或标量。此处请注意,不允许广播。如果您想使用广播功能,可以使用 broadcast_pow 。 |
SoftmaxActivation([data, mode, name, attr, out]) |
此函数对输入应用 softmax 激活。它适用于内部层。它实际上已被弃用,我们可以改为使用 softmax() 。 |
Implementation Examples
在下面的示例中,我们将使用函数 power() ,它将返回 exp 元素中 base 元素求幂的逐元素结果:
import mxnet as mx
mx.sym.power(3, 5)
Output
您将看到以下输出 −
243
Example
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()
Output
生成以下输出:
array([1., 8.], dtype=float32)
Example
z = mx.sym.power(4, y)
z.eval(y=mx.nd.array([2,3]))[0].asnumpy()
Output
执行以上代码时,应该看到以下输出 −
array([16., 64.], dtype=float32)
Example
z = mx.sym.power(x, y)
z.eval(x=mx.nd.array([4,5]), y=mx.nd.array([2,3]))[0].asnumpy()
Output
输出如下:
array([ 16., 125.], dtype=float32)
在下面给出的示例中,我们将使用函数 SoftmaxActivation() (or 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())
Output
您将看到以下输出 −
[[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 作为社区的一个地方,社区可以在其中试用新特性。特性贡献者也将获得反馈。
Functions and their parameters
以下是一些 mxnet.symbol.contrib API 涵盖的重要函数及其参数:
Function and its Parameters |
Definition |
rand_zipfian(true_classes, num_sampled, …) |
此函数从近似的 Zipfian 分布中提取随机样本。此函数的基本分布是 Zipfian 分布。此函数随机抽取 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, …]) |
此函数复制一个 new_tensor into the old_tensor by selecting the indices in the order given in index. The output of this operator will be a new tensor that contains the rest elements of old tensor and the copied elements of new tensor 的元素。 |
interleaved_matmul_encdec_qk([queries, …]) |
此算子计算多头注意力中查询和键投影之间的矩阵乘法,用作编码器-解码器。条件是输入应该是一个查询投影张量,其遵循以下布局:(seq_length, batch_size, num_heads*, head_dim)。 |
Implementation Examples
在下面的示例中,我们将使用 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()
Output
您将看到以下输出 −
array([4, 0, 2, 1, 5], dtype=int64)
Example
exp_count_true.eval(true_cls=mx.nd.array([3]))[0].asnumpy()
Output
输出如下:
array([0.57336551])
Example
exp_count_sample.eval(true_cls=mx.nd.array([3]))[0].asnumpy()
Output
您将看到以下输出 −
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)
Output
输出如下:
[<Symbol _while_loop0>]
Example
Print(States)
Output
生成以下输出:
[<Symbol _while_loop0>, <Symbol _while_loop0>]
在下面的示例中,我们将使用将 new_tensor 中的元素复制到 old_tensor 中的函数 index_copy 。
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)
Output
执行以上代码时,应该看到以下输出 −
[[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 包中定义。正如名称所示,它通常用于图像及其功能。
Functions and their parameters
以下是一些 mxnet.symbol.image API 涵盖的重要函数及其参数−
Function and its Parameters |
Definition |
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]) |
它将使用 mean 和 standard deviation(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) 的图像随机裁剪为给定尺寸。如果 src 小于大小,它将对结果进行上采样。它还将随机化区域和纵横比。 |
resize([data, size, keep_ratio, interp, …]) |
正如名称所示,此函数将形状为 (H x W x C) 或 (N x H x W x C) 的图像 NDArray 调整到用户给定的尺寸。 |
to_tensor([data, out, name]) |
它将值在 [0, 255] 范围内的形状为 (H x W x C) 或 (N x H x W x C) 的图像 NDArray 转换为值在 [0, 1] 范围内的形状为 (C x H x W) 或 (N x C x H x W) 的张量 NDArray。 |
Implementation Examples
在下面的示例中,我们将使用 to_tensor 函数将值在 [0, 255] 范围内的形状为 (H x W x C) 或 (N x H x W x C) 的图像 NDArray 转换为值在 [0, 1] 范围内的形状为 (C x H x W) 或 (N x C x H x W) 的张量 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)
Output
输出如下 −
<Symbol to_tensor4>
Example
img = mx.sym.random.uniform(0, 255, (2, 4, 2, 3)).astype(dtype=np.uint8)
mx.sym.image.to_tensor(img)
Output
输出如下所示:
<Symbol to_tensor5>
在下面的示例中,我们将使用 normalize() 函数对形状为 (C x H x W) 或 (N x C x H x W) 的张量使用 mean 和 standard deviation(SD) 进行归一化。
img = mx.sym.random.uniform(0, 1, (3, 4, 2))
mx.sym.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))
Output
以下是代码的输出 −
<Symbol normalize0>
Example
img = mx.sym.random.uniform(0, 1, (2, 3, 4, 2))
mx.sym.image.normalize(img, mean=(0, 1, 2), std=(3, 2, 1))
Output
输出如下所示−
<Symbol normalize1>
symbol.random
随机符号 API 在 symbol.random 包中定义。正如名称所示,它是 MXNet 的随机分配发生器 Symbol API。
Functions and their parameters
以下是一些 mxnet.symbol.random API 涵盖的重要函数及其参数−
Function and its Parameters |
Definition |
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([数据,阿尔法,贝塔,输出,名称]) |
根据输入数组形状从伽马分布生成随机样本。 |
generalized_negative_binomial_like([data, …]) |
它根据输入数组形状根据广义负二项分布生成随机样本。 |
negative_binomial_like([数据,k,p,输出,名称]) |
它根据输入数组形状根据负二项分布生成随机样本。 |
normal_like([数据,位置,比例,输出,名称]) |
它根据输入数组形状根据正态(高斯)分布生成随机样本。 |
poisson_like([data, lam, out, name]) |
它根据输入数组形状根据泊松分布生成随机样本。 |
uniform_like([数据,最低,最高,输出,名称]) |
它根据输入数组形状根据均匀分布生成随机样本。 |
Implementation Examples
在下面的示例中,我们将使用 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)
Output
您将看到以下输出:
[
[[ 9. 10. 11.]
[ 0. 1. 2.]
[ 6. 7. 8.]
[ 3. 4. 5.]]
<NDArray 4x3 @cpu(0)>]
Example
y.eval(x=data)
Output
执行以上代码时,应该看到以下输出 −
[
[[ 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)
Output
输出如下 −
<Symbol _random_generalized_negative_binomial0>
symbol.sparse
稀疏符号 API 在 mxnet.symbol.sparse 程序包中定义。顾名思义,它提供了稀疏神经网络图和 CPU 上的自动微分。
Functions and their parameters
以下一些重要的函数(包括符号创建例程、符号操作例程、数学函数、三角函数、双曲函数、减少函数、舍入、幂、神经网络)及其参数由 mxnet.symbol.sparse API 涵盖:
Function and its Parameters |
Definition |
ElementWiseSum(*args, **kwargs) |
此函数将按元素方式添加所有输入参数。例如,add_n(a1,a2,…an=a1+a2+⋯+an)。在这里,我们可以看到 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 optimizer 的更新函数。 |
adam_update([weight, grad, mean, var, lr, …]) |
它是 Adam optimizer 的更新函数。 |
add_n(*args, **kwargs) |
顾名思义,它将以元素级方式添加所有输入参数。 |
arccos([data, name, attr, out]) |
该函数将返回输入数组的元素级反余弦。 |
dot([lhs, rhs, transpose_a, transpose_b, …]) |
顾名思义,它将给出两个数组的点积。它将取决于输入数组维度:1-D:向量的内积2-D:矩阵乘法N-D:第一个输入数组的最后一个轴和第二个输入数组的第一个轴上求和积。 |
elemwise_add([lhs, rhs, name, attr, out]) |
顾名思义,它将以元素级方式 add 参数。 |
elemwise_div([lhs, rhs, name, attr, out]) |
顾名思义,它将以元素级方式 divide 参数。 |
elemwise_mul([lhs, rhs, name, attr, out]) |
顾名思义,它将以元素级方式 Multiply 参数。 |
elemwise_sub([lhs, rhs, name, attr, out]) |
顾名思义,它将以元素级方式减去参数。 |
exp([data, name, attr, out]) |
该函数将返回给定输入的元素级指数值。 |
sgd_update([weight, grad, lr, wd, …]) |
它充当随机梯度下降优化器的更新函数。 |
sigmoid([data, name, attr, out]) |
正如名称所示,它将计算 sigmoid 的 x 元素。 |
sign([data, name, attr, out]) |
它会返回给定输入的元素符号。 |
sin([data, name, attr, out]) |
如名称所示,此函数将计算给定输入数组的元素正弦。 |
Implementation Example
在下面的示例中,我们将使用 ElementWiseSum() 函数随机对元素进行洗牌。它将把整数索引映射到向量表示中,即单词嵌入。
input_dim = 4
output_dim = 5
Example
/* 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.]]]