37931


Chainerを利用して、15入力3出力のニューラルネットワークを作成しようと思い、以下のコードを書きました。

[code]

    # -*- coding:utf-8 -*-
    
    import numpy as np
    import chainer
    from chainer.datasets import tuple_dataset
    from chainer import Variable
    from chainer import Function, gradient_check, report, training, utils, 
    Variable
    from chainer import datasets, iterators, optimizers, serializers
    from chainer import Link, Chain, ChainList
    import chainer.functions as F
    import chainer.links as L
    from chainer.training import extensions
    
    import csv
    
    batchsize = 10
    epoch = 20
    
    
    class NChain(Chain):
    
        def __init__(self):
    
            super(NChain, self).__init__()
            self.n_out = 3  # 出力数
            self.n_units = 8  # 中間層ノード数
    
            with self.init_scope():
                self.l1 = L.Linear(None, self.n_units)
                self.l2 = L.Linear(None, self.n_units)
            self.l3 = L.Linear(None, self.n_out)
    
        def __call__(self, x):
    
            h1 = F.relu(self.l1(x))
            h2 = F.relu(self.l2(h1))
            y = self.l3(h2)
            return y
    
    
    class datasets():
        def get_data():
            train_data = []  # trainデータを格納
            train_enr = []  # trainの格納時に利用(15個で一つのデータのため)
            label_data = []  # 教師データ
            dataset_number = 0  # データ総数を格納
    
            # ファイル読み込み(./answer.csv)
            csvfile = './answer.csv'
            f = open(csvfile, "r")
            reader = csv.reader(f)
            # ヘッダーを読み飛ばす
            header = next(reader)
    
            # 教師データの作成
            for row in reader:
                # 入力
                if(len(row) - 1 == 5):
                    for i in range(5):
                        train_enr.append(float(row[i]))
                    if(len(train_enr) == 15):
                        train_data.append(
                            Variable(np.array(train_enr, 
    dtype='float32')))
                        train_enr = []
                # 出力
                elif(len(row) - 1 == 3):
                    label_data.append(
                        Variable(np.array([float(row[0]), float(row[1]), 
    float(row[2])], dtype='float32')))
    
                    # データ数を1カウント
                    dataset_number += 1
    
            # データセットの8割をtrain, 2割をtest用にする
            threshold = int((dataset_number * 8) / 10)
    
            # Trainerで使えるように整形
            train = tuple_dataset.TupleDataset(
                train_data[0:threshold], label_data[0:threshold])
    
            test = tuple_dataset.TupleDataset(
                train_data[threshold:], label_data[threshold:])
    
            return train, test
    
    
    def main():
    
        model = NChain()
    
        optimizer = optimizers.Adam()
        optimizer.setup(model)
    
        # データセット読み込み
        train, test = datasets.get_data()
    
        train_iter = chainer.iterators.SerialIterator(train, batchsize)
        test_iter = chainer.iterators.SerialIterator(test, batchsize,
                                                     repeat=False, 
    shuffle=False)
    
        # Set up a trainer
        updater = training.StandardUpdater(train_iter, optimizer, 
    device=None)
        trainer = training.Trainer(updater, (epoch, '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())
    
        # Run the training
        trainer.run()
    
    
    if __name__ == '__main__':
        main()
    
[/code]

しかし、今までデータセットを自前で作成したりTrainerを使ったことがなかったのですが、練習のために試してみたところ以下のようなエラーが出ました。

[code]

    Traceback (most recent call last):
      File "chainer_pl.py", line 115, in <module>
        main()
      File "chainer_pl.py", line 111, in main
        trainer.run()
      File "/usr/local/lib/python3.5/dist-
    packages/chainer/training/trainer.py", line 296, in run
        update()
          File "/usr/local/lib/python3.5/dist-
    packages/chainer/training/updater.py", line 223, in update
        self.update_core()
      File "/usr/local/lib/python3.5/dist-
    packages/chainer/training/updater.py", line 234, in update_core
        optimizer.update(loss_func, *in_arrays)
      File "/usr/local/lib/python3.5/dist-packages/chainer/optimizer.py", 
    line 527, in update
        loss = lossfun(*args, **kwds)
    TypeError: __call__() takes 2 positional arguments but 3 were given
    
[/code]

どうやらTrainerのUpdateの際のエラーなようですが、解決方法が分かりません。  
どなたかご教示いただけますでしょうか。


CC BY-SA 3.0
2017-09-04T10:48:58.530
37711
2017-10-15T12:53:53.240
question
python 機械学習 chainer ニューラルネットワーク
ChainerのTrainer実行時にエラーが出る


こんにちは。  
NChainを定義して、モデルを読み込むときに損失関数が組み込まれていないため、  
Updaterがバックプロップ出来ないのではないでしょうか？  
具体的な損失関数はわかりませんが、例えば、softmax cross entropyで分類する場合、  
model = NChain()  
ではなく、  
model = L.Classifier(NChain())  
で解決すると思います。


CC BY-SA 3.0
2017-09-13T14:52:00.053
37931
2017-09-13T14:52:00.053
25369
37711
answer