Apache Mxnet 简明教程
Python API Autograd and Initializer
本章介绍了 MXNet 中的自动微分和初始化器 API。
mxnet.autograd
这是 MXNet 对 NDArray 的自动微分 API。它具有以下类 -
Class: Function()
它用于自动微分中的自定义微分。它可以写为 [s2]。如果由于任何原因,用户不希望使用默认链式法则计算的梯度,那么他/她可以使用 mxnet.autograd 的 Function 类自定义微分的计算。它有两个方法,即 Forward() 和 Backward()。
让我们借助以下要点来了解此类的作用 -
-
首先,我们需要在正向方法中定义计算。
-
然后,我们需要在反向方法中提供自定义微分。
-
现在在梯度计算期间,mxnet.autograd 将使用用户定义的反向函数,而不是用户定义的反向函数。我们还可以转换为 numpy 数组,然后再进行一些操作,向前和向后。
Example
在使用 mxnet.autograd.function 类之前,让我们定义一个稳定的 sigmoid 函数及其反向和正向方法,如下所示 -
class sigmoid(mx.autograd.Function):
def forward(self, x):
y = 1 / (1 + mx.nd.exp(-x))
self.save_for_backward(y)
return y
def backward(self, dy):
y, = self.saved_tensors
return dy * y * (1-y)
现在,function 类可以用作以下 -
func = sigmoid()
x = mx.nd.random.uniform(shape=(10,))
x.attach_grad()
with mx.autograd.record():
m = func(x)
m.backward()
dx_grad = x.grad.asnumpy()
dx_grad
Output
运行代码后,你将看到以下输出 −
array([0.21458015, 0.21291625, 0.23330082, 0.2361367 , 0.23086983,
0.24060014, 0.20326573, 0.21093895, 0.24968489, 0.24301809],
dtype=float32)
Methods and their parameters
mxnet.autogard.function 类的以下方法和参数 -
Methods and its Parameters |
Definition |
forward(head[,head_grads,retain_graph,…]) |
此方法用于正向计算。 |
backward(heads[, head_grads, retain_graph, …]) |
此方法用于反向计算。它计算 head 的相对于先前标记变量的梯度。此方法的输入数量与 forward 的输出数量相同。它还返回与 forward 的输入一样多的 NDArray。 |
get_symbol(x) |
此方法用于检索记录的计算历史记录为 Symbol 。 |
grad(heads, variables[, head_grads, …]) |
此方法计算 head 相对于变量的梯度。计算完成后,梯度将作为新 NDArray 返回,而不是存储到 variable.grad 中。 |
is_recording() |
在这个方法的帮助下,我们可以获得记录和不记录的状态。 |
is_training() |
在该方法的帮助下,我们可以获得训练和预测的状态。 |
mark_variables(variables, gradients[, grad_reqs]) |
该方法会将 NDArray 标记为变量以计算 autograd 的梯度。该方法与变量中的函数 .attach_grad() 相同,但唯一的区别是我们可以使用此调用将梯度设置为任何值。 |
pause([train_mode]) |
该方法返回一个范围上下文用于不在“with”语句中的代码,不需要计算梯度。 |
predict_mode() |
该方法返回一个范围上下文用于不在“with”语句中,其中正向通过行为被设置为推断模式,并且不会更改记录状态。 |
record([train_mode]) |
它将返回一个 autograd 记录范围上下文用于“with”语句,并捕获需要计算梯度的代码。 |
set_recording(is_recording) |
与 is_recoring() 一样,在该方法的帮助下,我们可以获得记录和未记录的状态。 |
set_training(is_training) |
与 is_traininig() 一样,在该方法的帮助下,我们可以将状态设置为训练或预测。 |
train_mode() |
该方法将返回一个范围上下文用于不在“with”语句中,其中正向通过行为被设置为训练模式,并且不会更改记录状态。 |
Implementation Example
在以下示例中,我们将使用 mxnet.autograd.grad() 方法来计算目标相对于变量的梯度 −
x = mx.nd.ones((2,))
x.attach_grad()
with mx.autograd.record():
z = mx.nd.elemwise_add(mx.nd.exp(x), x)
dx_grad = mx.autograd.grad(z, [x], create_graph=True)
dx_grad
Output
输出如下:
[
[3.7182817 3.7182817]
<NDArray 2 @cpu(0)>]
我们可以使用 mxnet.autograd.predict_mode() 方法来返回一个范围用于“with”语句 −
with mx.autograd.record():
y = model(x)
with mx.autograd.predict_mode():
y = sampling(y)
backward([y])
mxnet.intializer
这是 MXNet 的 API 用于权重初始化器。它具有以下类 −
Classes and their parameters
以下为 mxnet.autogard.function 类的方法和其参数:
Classes and its Parameters |
Definition |
Bilinear() |
在该类帮助下,我们可以初始化上采样层权重。 |
Constant(value) |
该类将权重初始化到给定值。值可以是标量,也可以是与要设置的参数形状相匹配的 NDArray。 |
FusedRNN(init, num_hidden, num_layers, mode) |
顾名思义,此类为融合循环神经网络 (RNN) 初始化参数。 |
InitDesc |
它作为初始化模式描述符。 |
Initializer(**kwargs) |
这是初始化器的基类。 |
LSTMBias([forget_bias]) |
该类将 LSTMCell 的所有偏差初始化为 0.0,但除了遗忘门,其偏差被设置为一个自定义值以外。 |
Load(param[, default_init, verbose]) |
该类通过从文件或词典加载数据来初始化变量。 |
MSRAPrelu([factor_type, slope]) |
顾名思义,此类根据 MSRA 论文初始化权重。 |
Mixed(patterns, initializers) |
它使用多个初始化器来初始化参数。 |
Normal([sigma]) |
Normal() 类使用从均值为零且标准差 (SD) 为 sigma 的正态分布中抽取的随机值来初始化权重。 |
One() |
它将该参数的权重均初始化为 1。 |
Orthogonal([scale, rand_type]) |
顾名思义,此类将权重初始化为正交矩阵。 |
Uniform([scale]) |
它使用在给定范围内均匀抽取的随机值初始化权重。 |
Xavier([rnd_type, factor_type, magnitude]) |
它实际上返回一个执行权重“Xavier”初始化的初始化器。 |
Zero() |
它将该参数的权重均初始化为 0。 |
Implementation Example
在以下示例中,我们将使用 mxnet.init.Normal() 类创建初始化器并获取其参数 −
init = mx.init.Normal(0.8)
init.dumps()
Output
输出如下 −
'["normal", {"sigma": 0.8}]'
Example
init = mx.init.Xavier(factor_type="in", magnitude=2.45)
init.dumps()
Output
输出如下所示−
'["xavier", {"rnd_type": "uniform", "factor_type": "in", "magnitude": 2.45}]'
在以下示例中,我们将使用 mxnet.initializer.Mixed() 类使用多个初始化器来初始化参数 −
init = mx.initializer.Mixed(['bias', '.*'], [mx.init.Zero(),
mx.init.Uniform(0.1)])
module.init_params(init)
for dictionary in module.get_params():
for key in dictionary:
print(key)
print(dictionary[key].asnumpy())
Output
输出如下所示−
fullyconnected1_weight
[[ 0.0097627 0.01856892 0.04303787]]
fullyconnected1_bias
[ 0.]