【问题标题】:Possible to Use MXNet gluon.Trainer without a Neural Network?可以在没有神经网络的情况下使用 MXNet gluon.Trainer?
【发布时间】:2018-04-22 17:10:38
【问题描述】:

我正在尝试使用 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 中通常可以使用Trainer,而使用optimizer in PyTorch。但是,在我的情况下,我不明白如何正确初始化 Trainer,因为人们通常会按照以下方式做某事

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

我显然误解了一些基本的东西,所以如果有人能指出我的一些澄清会有所帮助。如果有人理解我的要求并能够总结出我做错的原因,那就更有帮助了。

【问题讨论】:

    标签: python mxnet


    【解决方案1】:

    gluon 中的 Trainer 只是根据优化器更新一组参数。您需要将要在目标函数中优化的参数传递给它。已经有几点:

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

    如果您发布了您的目标函数、错误日志,我可能会为您提供进一步的帮助。

    也不是必须使用Trainer。看看这个教程:https://github.com/zackchase/mxnet-the-straight-dope/blob/master/chapter02_supervised-learning/linear-regression-scratch.ipynb 它正在从头开始执行线性回归优化,只使用NDArrayautograd

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      • 2012-11-14
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多