可以在没有神经网络的情况下使用MXNet gluon.Trainer吗?

时间:2018-04-22 17:10:38

标签: python mxnet

我正在尝试使用MXNet的图形结构来加速某些计算,我目前正在尝试模仿我已经在PyTorch中实现的行为。但是,我对如何正确执行此操作感到困惑,无论是gluon.Trainer还是其他方法。

为了解释一个例子,我在PyTorch中工作的是以下内容(略微修改以尝试给出最简单的示例),并且我想将其转换为MXNet。

import torch.optim


def unconstrained_fit(objective, data, pdf, init_pars, tolerance):
    init_pars.requires_grad = True
    optimizer = torch.optim.Adam([init_pars])
    max_delta = None
    n_epochs = 10000
    for _ in range(n_epochs):
        loss = objective(init_pars, data, pdf)
        optimizer.zero_grad()
        loss.backward()
        init_old = init_pars.data.clone()
        optimizer.step()
        max_delta = (init_pars.data - init_old).abs().max()
        if max_delta < tolerance:
            break
    return init_pars

作为The Straight Dope points out in the PyTorch to MXNet cheatsheet,在MXNet中,人们通常可以使用培训师,其中人们会使用optimizer in PyTorch。但是,我不明白如何在我的案例中正确初始化培训师,因为人们通常会按照

的方式做一些事情。
trainer = gluon.Trainer(net.collect_params(), 'adam')

我认为我需要自己收集参数,因为我没有我想要使用的神经网络,而是我想要最小化的objective。我对如何正确地做到这一点很困惑,因为下面显然不正确。

import mxnet as mx
from mxnet import gluon, autograd

def unconstrained_fit(self, objective, data, pdf, init_pars, tolerance):
    ctx = mx.cpu()
    # How to properly do this chunck?
    init_pars = mx.gluon.Parameter('init_pars',
                                   shape=init_pars.shape,
                                   init=init_pars.asnumpy().all)
    init_pars.initialize(ctx=ctx)
    optimizer = mx.optimizer.Adam()
    trainer = gluon.Trainer([init_pars], optimizer)
    ###
    max_delta = None
    n_epochs = 10000
    for _ in range(n_epochs):
        with autograd.record():
            loss = objective(init_pars, data, pdf)
        loss.backward()
        init_old = init_pars.data.clone()
        trainer.step(data.shape[0])
        max_delta = (init_pars.data - init_old).abs().max()
        if max_delta < tolerance:
            break
    return init_pars

我显然误解了一些基本的东西,所以如果有人能指出我澄清一些有用的东西。更有帮助的是,如果有人理解我的要求并且能够总结为什么我所做的是错误的。

1 个答案:

答案 0 :(得分:1)

胶子中的训练师只是根据优化器更新一组参数。您需要将目标函数中要优化的参数传递给它。已经有几点了:

  • Trainer需要ParameterDict,而不是Parameter[]
  • 您需要使用.data()来获取参数的数据,而不是.data

如果您发布了目标函数,错误日志,我可以帮助您。

同样使用Trainer不是强制性的。请看一下本教程:https://github.com/zackchase/mxnet-the-straight-dope/blob/master/chapter02_supervised-learning/linear-regression-scratch.ipynb它仅从头开始执行线性回归优化,仅使用NDArrayautograd

一个关键点是为参数附加一个渐变,以分配内存,以便在使用autograd.record()时可以存储渐变(这里有两个参数,wb):< / p>

w = nd.random_normal(shape=(num_inputs, num_outputs), ctx=model_ctx)
b = nd.random_normal(shape=num_outputs, ctx=model_ctx)
params = [w, b]
for param in params:
    param.attach_grad()

然后在调用loss.backward()之后,您可以访问每个参数的渐变并使用SGD公式更新它们,如下所示:

for param in params:
    param[:] = param - lr * param.grad