trainer における途中入力のあるネットワークの学習

652 views
Skip to first unread message

Taiki Nomura

unread,
Aug 12, 2016, 4:55:48 AM8/12/16
to Chainer Japanese User Group
chainerを用いて学習を行う際に、複数の入力を用いて学習させています。
現在、片方の入力の時限が大きいために途中層で入力を付加しています。
学習状況を可視化するためにtrainerを利用しようとしており、入力をcall内で分割させました。
しかし、callで渡している入力サイズと初めの層で渡した入力サイズが異なるためにErrorが発生しています。
この問題を解決する方法はなにかありませんか?


class MyNet(chainer.Chain):
    def __init__(self):
        self.train=False
        super(MyNet, self).__init__(
            L1 = L.Linear(414400,2800),
            L2 = L.Linear(2800,1400),
            AL1 = L.Linear(5496,1000),
            AL2 = L.Linear(1000,3)
        )

    def __call__(self, x):
        x1=chainer.Variable(x.data[:4096])
        x2=chainer.Variable(x.data[4096:])
        o = self.__forward(x1, x2)
        return o

   def __forward(self,x1,x2):
        h = F.dropout(F.relu(self.L1(x1)), train=self.train, ratio=0.5)       
        h = F.dropout(F.relu(self.L2(h)), train=self.train, ratio=0.5)       

        h = F.concat((h,x2),axis=1)
        h = F.dropout(F.relu(self.AL1(anoteted)), train=self.train, ratio=0.5)
        o = self.Al2(h)
        return o

?[JTraceback (most recent call last):
  File "trainMyModel.py", line 61, in <module>

  File "trainMyModel.py", line 45, in MyModelTrain

  File "C:\Python27\lib\site-packages\chainer\training\trainer.py", line 265, in run
    update()
  File "C:\Python27\lib\site-packages\chainer\training\updater.py", line 167, in update
    self.update_core()
  File "C:\Python27\lib\site-packages\chainer\training\updater.py", line 179, in update_core
    optimizer.update(loss_func, *in_vars)
  File "C:\Python27\lib\site-packages\chainer\optimizer.py", line 387, in update
    loss = lossfun(*args, **kwds)
  File "C:\Python27\lib\site-packages\chainer\links\model\classifier.py", line 67, in __call__
    self.y = self.predictor(*x)
  File "C:\Users\Nomura\Desktop\python\EmoImgEEG ver5\mymodel.py", line 28, in __call__
    o = self.__forward(x1, x2)
  File "C:\Users\Nomura\Desktop\python\EmoImgEEG ver5\mymodel.py", line 40, in __forward
    h = F.dropout(F.relu(self.L1(x1)), train=self.train, ratio=0.5)
  File "C:\Python27\lib\site-packages\chainer\links\connection\linear.py", line 86, in __call__
    return linear.linear(x, self.W, self.b)
  File "C:\Python27\lib\site-packages\chainer\functions\connection\linear.py", line 79, in linear
    return LinearFunction()(x, W, b)
  File "C:\Python27\lib\site-packages\chainer\function.py", line 122, in __call__
    self._check_data_type_forward(in_data)
  File "C:\Python27\lib\site-packages\chainer\function.py", line 197, in _check_data_type_forward
    raise type_check.InvalidType(e.expect, e.actual, msg=msg)
chainer.utils.type_check.InvalidType:
Invalid operation is performed in: LinearFunction (Forward)

Expect: prod(in_types[0].shape[1:]) == in_types[1].shape[1]
Actual: 418496 != 414400

Kenta Oono

unread,
Aug 15, 2016, 7:49:30 PM8/15/16
to Chainer Japanese User Group
大野です

> しかし、callで渡している入力サイズと初めの層で渡した入力サイズが異なるためにErrorが発生しています。
__call__の引数となっているxと、__forwardの引数となっているx1, x2でshapeが想定されたものと異なっているのはどちらでしょうか。
xが間違っていれば、データセットを用意する段階でバグがある可能性が高く、x1, x2の方が間違っていれば__call__の中でのデータの分割の仕方(xからx1, x2を作る方法)
が間違っている可能性が高いと思います。

本件と関係あるかわかりませんが、__call__の中で、xを最初の軸で分割し、ミニバッチの最初の4096データを取り出してx1を作成しております。
個人的にはミニバッチをミニバッチ次元(最初の軸)で分割するのをあまり見たことはありませんが、こちらは想定している動作でしょうか?

2016年8月12日金曜日 17時55分48秒 UTC+9 Taiki Nomura:

Taiki Nomura

unread,
Aug 19, 2016, 1:12:52 AM8/19/16
to Chainer Japanese User Group
返信ありがとうございます。

>本件と関係あるかわかりませんが、__call__の中で、xを最初の軸で分割し、ミニバッチの最初の4096データを取り出してx1を作成しております。個人的にはミニバッチをミニバッチ次元(最初の軸)で分割するのをあまり見たことはありませんが、こちらは想定している動作でしょうか?
こちらは想定している動作です。
trainer、dataset.DataMixin、Classifierの他変数入力の場合の挙動がわかりませんでした。
そのため、本来は分割してx1,x2として入力させるはずのデータを連結し、xとして入力して分割することで無理やり動かそうとしていました。
もう少し賢い方法を調べてみようと思います。

Errorについては仰るとおりバッチ処理を行っていたため、データの分割の方法が間違っていたようです。修正したところ動きました



2016年8月16日火曜日 8時49分30秒 UTC+9 Kenta Oono:
Reply all
Reply to author
Forward
0 new messages