首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Chainer对MLP进行错误训练

使用Chainer对MLP进行错误训练
EN

Stack Overflow用户
提问于 2017-12-01 21:41:05
回答 1查看 350关注 0票数 0

我正试图训练和测试一个简单的多层感知器,与第一个Chainer教程完全一样,但是使用我自己的数据集而不是MNIST。这是我使用的代码(主要来自本教程):

代码语言:javascript
复制
class MLP(Chain):
    def __init__(self, n_units, n_out):
        super(MLP, self).__init__()
        with self.init_scope():
            self.l1 = L.Linear(None, n_units)
            self.l2 = L.Linear(None, n_units)
            self.l3 = L.Linear(None, n_out)
    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        y = self.l3(h2)
        return y

X, X_test, y, y_test, xHeaders, yHeaders = load_train_test_data('xHeuristicData.csv', 'yHeuristicData.csv')

print 'dataset shape   X:', X.shape, '  y:', y.shape

model = MLP(100, 1)
optimizer = optimizers.SGD()
optimizer.setup(model)

train = tuple_dataset.TupleDataset(X, y)
test = tuple_dataset.TupleDataset(X_test, y_test)

train_iter = iterators.SerialIterator(train, batch_size=100, shuffle=True)
test_iter = iterators.SerialIterator(test, batch_size=100, repeat=False, shuffle=False)
updater = training.StandardUpdater(train_iter, optimizer)
trainer = training.Trainer(updater, (10, 'epoch'), out='result')

trainer.extend(extensions.Evaluator(test_iter, model))
trainer.extend(extensions.LogReport())
trainer.extend(extensions.PrintReport(['epoch', 'main/accuracy', 'validation/main/accuracy']))
trainer.extend(extensions.ProgressBar())

trainer.run()

print 'Predicted value for a test example'
print model(X_test[0])

我没有训练和打印预测值,而是在“trainer.run()”中得到以下错误:

代码语言:javascript
复制
dataset shape   X: (1003, 116)   y: (1003,)
Exception in main training loop: __call__() takes exactly 2 arguments (3 given)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/trainer.py", line 299, in run
    update()
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/updater.py", line 223, in update
    self.update_core()
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/updater.py", line 234, in update_core
    optimizer.update(loss_func, *in_arrays)
  File "/usr/local/lib/python2.7/dist-packages/chainer/optimizer.py", line 534, in update
    loss = lossfun(*args, **kwds)
Will finalize trainer extensions and updater before reraising the exception.
Traceback (most recent call last):
  File "trainHeuristicChainer.py", line 76, in <module>
    trainer.run()
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/trainer.py", line 313, in run
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/trainer.py", line 299, in run
    update()
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/updater.py", line 223, in update
    self.update_core()
  File "/usr/local/lib/python2.7/dist-packages/chainer/training/updater.py", line 234, in update_core
    optimizer.update(loss_func, *in_arrays)
  File "/usr/local/lib/python2.7/dist-packages/chainer/optimizer.py", line 534, in update
    loss = lossfun(*args, **kwds)
TypeError: __call__() takes exactly 2 arguments (3 given)

我不知道如何处理这个错误。我使用其他框架成功地训练了类似的网络,但我对Chainer很感兴趣,因为它与PyPy兼容。

包含这些文件的tgz可以在这里获得:https://mega.nz/#!wwsBiSwY!g72pC5ZgekeMiVr-UODJOqQfQZZU3lCqm9Er2jH4UD8

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-02 17:31:41

您正在将(X, y)的元组发送到MLP中,而实现的__call__只接受x

可以将实现修改为

代码语言:javascript
复制
class MLP(Chain):
    def __init__(self, n_units, n_out):
        super(MLP, self).__init__()
        with self.init_scope():
            self.l1 = L.Linear(None, n_units)
            self.l2 = L.Linear(None, n_units)
            self.l3 = L.Linear(None, n_out)
    def __call__(self, x, y):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        predict = self.l3(h2)
        loss = F.squared_error(predict, y)
        // or you can write it on your own as follows
        // loss = F.sum(F.square(predict - y))
        return loss

默认情况下,标准更新程序假定__call__为丢失函数,在chainer中可能与其他框架不同。因此,调用model(X, y)将返回当前迷你批处理的损失。这就是为什么chainer教程引入了另一个Classifier类来计算损失函数并保持MLP简单。分类器在MNIST中是有意义的,但不适合您的任务,所以您需要自己来实现丢失函数。

当您完成培训后,您可以只保存模型实例(可能通过在训练器中添加snapshot_object的扩展)。

要使用保存的模型,就像在测试中一样,您必须在类中使用与当前__call__相同的代码在类中编写另一个可能命名为test的方法,该方法只有X输入,因此不需要其他y

此外,如果您不喜欢在MLP类中添加任何额外的方法,使其变得纯净,那么您需要自己编写更新程序并更自然地计算损失函数。为了更容易地继承标准,您可以按以下方式编写它,

代码语言:javascript
复制
class MyUpdater(chainer.training.StandardUpdater):
    def __init__(self, data_iter, model, opt, device=-1):
        super(MyUpdater, self).__init__(data_iter, opt, device=device)
        self.mlp = model

    def update_core(self):
        batch = self.get_iterator('main').next()
        x, y = self.converter(batch, self.device)
        predict = self.mlp(x)
        loss = F.squared_error(predict, y)
        self.mlp.cleargrads()
        loss.backward()
        self.get_iterator('main').update()

updater = MyUpdater(train_iter, model, optimizer)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47601878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档