如何在 Chainer 中对变量应用优化器?

How to apply Optimizer on Variable in Chainer?

这是 Pytorch 中的示例:

optimizer = optim.Adam([modifier_var], lr=0.0005)

在 Tensorflow 中:

self.train = self.optimizer.minimize(self.loss, var_list=[self.modifier])

但是 Chainer 的优化器只能在 'Link' 上使用,如何在 Chainer 中对变量应用优化器?

下面是一个使用 Adam 优化器在 Chainer 中通过 MyChain MLP 模型学习回归任务的示例。

from chainer import Chain, Variable

# Prepare your model (neural network) as `Link` or `Chain`
class MyChain(Chain):
    def __init__(self):
        super(MyChain, self).__init__(
            l1=L.Linear(None, 30),
            l2=L.Linear(None, 30),
            l3=L.Linear(None, 1)
        )

    def __call__(self, x):
        h = self.l1(x)
        h = self.l2(F.sigmoid(h))
        return self.l3(F.sigmoid(h))

model = MyChain()

# Then you can instantiate optimizer
optimizer = chainer.optimizers.Adam()

# Register model to optimizer (to indicate which parameter to update)
optimizer.setup(model)

# Calculate loss, and update parameter as follows.
def lossfun(x, y):
    loss = F.mean_squared_error(model(x), y)
    return loss

# this iteration is "training", to fit the model into desired function.
for i in range(300):
    optimizer.update(lossfun, x, y)

所以综上所述,您需要setup model,之后您可以使用update函数计算损失并更新model的参数。 以上代码来自here

此外,还有其他方法可以使用 Trainer 模块编写训练代码。更详细的Chainer教程请参考下方

总之没有办法直接把chainer.Variable(甚至chainer.Parameter)赋值给chainer.Optimizer

以下是一些多余的解释。

首先,我重新定义VariableParameter以避免混淆。

Variable 在 PyTorch v4 中是 (1) torch.Tensor,在 PyTorch v3 中是 (2) torch.autograd.Variable,在 Chainer v4 中是 (3) chainer.Variable
Variable是一个持有两个张量的对象; .data.grad。它是充分必要条件,所以 Variable 不一定是可学习的参数,这是优化器的目标。

在这两个库中,还有一个class Parameter,与Variable相似但不相同。 Parameter 在 Pytorch 中是 torch.autograd.Parameter,在 Chainer 中是 chainer.Parameter
Parameter 必须是可学习的参数,应该进行优化。

因此,应该没有将Variable(不是Parameter)注册到Optimizer的情况(尽管PyTorch允许将Variable注册到Optimizer : 这只是为了向后兼容)。

其次,在 PyTorch 中 torch.nn.Optimizer 直接优化 Parameter,但在 Chainer 中 chainer.Optimizer 不优化 Parameter:相反,chainer.UpdateRule 优化。 Optimizer 只是在 Link.

中注册 UpdateRules 到 Parameters

因此,chainer.Optimizer 不接收 Parameter 作为其参数是很自然的,因为它只是 UpdateRule 的 "delivery-man"。

如果你想为每个Parameter附加不同的UpdateRule,你应该直接创建一个UpdateRule子class的实例,并将它附加到Parameter