Python API 自动微分和初始化器



本章介绍 MXNet 中的自动微分和初始化器 API。

mxnet.autograd

这是 MXNet 的 NDArray 自动微分 API。它包含以下类:

类:Function()

它用于在自动微分中进行自定义微分。可以写成 **mxnet.autograd.Function**。如果出于任何原因,用户不想使用默认链式法则计算的梯度,那么他/她可以使用 mxnet.autograd 的 Function 类来自定义微分进行计算。它有两个方法,分别是 Forward() 和 Backward()。

让我们通过以下几点来了解这个类的作用:

  • 首先,我们需要在 forward 方法中定义我们的计算。

  • 然后,我们需要在 backward 方法中提供自定义微分。

  • 现在,在梯度计算期间,mxnet.autograd 将使用用户定义的 backward 函数,而不是用户定义的 backward 函数。我们也可以在 forward 和 backward 中强制转换为 numpy 数组并返回,以进行某些操作。

示例

在使用 mxnet.autograd.function 类之前,让我们定义一个稳定的 sigmoid 函数,其中包含 backward 和 forward 方法,如下所示:

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)

现在,函数类可以按如下方式使用:

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

输出

运行代码时,您将看到以下输出:

array([0.21458015, 0.21291625, 0.23330082, 0.2361367 , 0.23086983,
0.24060014, 0.20326573, 0.21093895, 0.24968489, 0.24301809],
dtype=float32)

方法及其参数

以下是 mxnet.autogard.function 类的所有方法及其参数:

方法及其参数 定义
forward (heads[, head_grads, retain_graph, …]) 此方法用于前向计算。
backward(heads[, head_grads, retain_graph, …]) 此方法用于反向计算。它计算 heads 相对于先前标记变量的梯度。此方法接受与 forward 输出一样多的输入。它还返回与 forward 输入一样多的 NDArray。
get_symbol(x) 此方法用于检索记录的计算历史作为 **Symbol**。
grad(heads, variables[, head_grads, …]) 此方法计算 heads 相对于 variables 的梯度。计算完成后,梯度将作为新的 NDArrays 返回,而不是存储到 variable.grad 中。
is_recording() 借助此方法,我们可以获取关于记录和不记录的状态。
is_training() 借助此方法,我们可以获取关于训练和预测的状态。
mark_variables(variables, gradients[, grad_reqs]) 此方法将 NDArrays 标记为变量,以便为自动微分计算梯度。此方法与变量中的函数 .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”语句中使用,其中前向传递行为设置为训练模式,而不会更改记录状态。

实现示例

在下面的示例中,我们将使用 mxnet.autograd.grad() 方法来计算 head 相对于 variables 的梯度:

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

输出

输出如下所示:

[
[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。它包含以下类:

类及其参数

以下是 **mxnet.autogard.function** 类的所有方法及其参数

类及其参数 定义
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。

实现示例

在下面的示例中,我们将使用 mxnet.init.Normal() 类创建初始化器并检索其参数:

init = mx.init.Normal(0.8)
init.dumps()

输出

输出如下所示:

'["normal", {"sigma": 0.8}]'

示例

init = mx.init.Xavier(factor_type="in", magnitude=2.45)
init.dumps()

输出

输出如下所示:

'["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())

输出

输出如下所示:

fullyconnected1_weight
[[ 0.0097627 0.01856892 0.04303787]]
fullyconnected1_bias
[ 0.]
广告