苦労と試行
python初心者が chainerのエラーに遭遇して、ひたすら苦労しながら解決していった記録。
無慈悲なエラーメッセージと、それがどういう意味で、何を言いたくて、どうしなければいけないのかを記録していきたいと思う。
エラーなんて原因がわかってしまえばなんてことはないんだけど、わかるまでが大変。。。
windowsでcudaを利用する場合インストール時
windowsでcudaを利用する場合に、
pip install chainer でインストールすると、以下のエラーが出る場合がある。
cupy\cuda\cudnn.cpp(3662) : error C3861: 'cudnnAddTensor_v3'
githubにある新しいバージョンで修正されている。2016/12/31にpipで入れようとしたら、このバグ修正がまだpip版に反映されていなくてとても苦労した。
github版では修正されているので、githubからソースコードを持ってきてインストールするとOK。
https://github.com/pfnet/chainer/pull/2031
git clone https://github.com/pfnet/chainer cd chainer python setup.py install
正解データは0からの整数で出力数とあっていないといけないらしい。
Traceback (most recent call last): File "test.py", line 54, in <module> trainer.run() File "chainer\training\trainer.py", line 289, in run update() File "chainer\training\updater.py", line 170, in update self.update_core() File "chainer\training\updater.py", line 182, in update_core optimizer.update(loss_func, *in_vars) File "chainer\optimizer.py", line 390, in update loss = lossfun(*args, **kwds) File "chainer\links\model\classifier.py", line 68, in __call__ self.loss = self.lossfun(self.y, t) File "chainer\functions\loss\softmax_cross_entropy.py", line 223, in softmax_cross_entropy use_cudnn, normalize, cache_score, class_weight)(x, t) File "chainer\function.py", line 199, in __call__ outputs = self.forward(in_data) File "chainer\function.py", line 319, in forward return self.forward_cpu(inputs) File "chainer\functions\loss\softmax_cross_entropy.py", line 68, in forward_cpu log_p = log_yd[numpy.maximum(t.ravel(), 0), numpy.arange(t.size)] IndexError: index 3 is out of bounds for axis 0 with size 3
データ(主に正解データ)を0からスタートしていないときや、
出力個数があっていない時にでるらしい。
たとえば、以下のようなモデルがあった場合、正解データは0-3のいづれかでないとダメらしい。
class IrisModel(Chain): def __init__(self): super(IrisModel, self).__init__( l1=L.Linear(4, 100), l2=L.Linear(100, 100), l3=L.Linear(100, 3), #正解データ ) def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) y = self.l3(h2) return y
l3=L.Linear(100, 正解データの個数)
正解データの個数 = 3 だった場合
正解データは、 [0,1,2] で合計 3つにならないといけないらしい。
それを間違えて、 [1,2,3] で合計 3つにすると、このエラーが発生する。
正解データは、 [0,1,2] で3つにしないといけないらしい。
学習データは、2次元のfloat32データ np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32) 正解データは、1次元のint32データで0から開始する np.array([0,1,2]).astype(np.int32)
正解データは、一次元配列でなければならないっぽい
Traceback (most recent call last): File "test.py", line 54, in <module> trainer.run() File "chainer\training\trainer.py", line 289, in run update() File "chainer\training\updater.py", line 170, in update self.update_core() File "chainer\training\updater.py", line 182, in update_core optimizer.update(loss_func, *in_vars) File "chainer\optimizer.py", line 390, in update loss = lossfun(*args, **kwds) File "chainer\links\model\classifier.py", line 68, in __call__ self.loss = self.lossfun(self.y, t) File "chainer\functions\loss\softmax_cross_entropy.py", line 223, in softmax_cross_entropy use_cudnn, normalize, cache_score, class_weight)(x, t) File "chainer\function.py", line 189, in __call__ self._check_data_type_forward(in_data) File "chainer\function.py", line 280, in _check_data_type_forward type_check.InvalidType(e.expect, e.actual, msg=msg), None) File "<string>", line 2, in raise_from chainer.utils.type_check.InvalidType: Invalid operation is performed in: SoftmaxCrossEntropy (Forward) Expect: in_types[1].ndim == in_types[0].ndim - 1 Actual: 2 != 1
正解データを、一次元の配列にしていない時に出る。
入力データは、 [0,1,2] みたいに、2次元配列でなければいけないらしい。
(そしてデータは0から始まるnumpy.int32型でないといけないっぽい)
学習データは、2次元のfloat32データ np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32) 正解データは、1次元のint32データで0から開始する np.array([0,1,2]).astype(np.int32)
正解データが numpy.int32の配列になっていないとき
Traceback (most recent call last): File "test.py", line 54, in <module> trainer.run() File "chainer\training\trainer.py", line 289, in run update() File "chainer\training\updater.py", line 170, in update self.update_core() File "chainer\training\updater.py", line 182, in update_core optimizer.update(loss_func, *in_vars) File "chainer\optimizer.py", line 390, in update loss = lossfun(*args, **kwds) File "chainer\links\model\classifier.py", line 68, in __call__ self.loss = self.lossfun(self.y, t) File "chainer\functions\loss\softmax_cross_entropy.py", line 223, in softmax_cross_entropy use_cudnn, normalize, cache_score, class_weight)(x, t) File "chainer\function.py", line 189, in __call__ self._check_data_type_forward(in_data) File "chainer\function.py", line 280, in _check_data_type_forward type_check.InvalidType(e.expect, e.actual, msg=msg), None) File "<string>", line 2, in raise_from chainer.utils.type_check.InvalidType: Invalid operation is performed in: SoftmaxCrossEntropy (Forward) Expect: in_types[1].dtype == <class 'numpy.int32'> Actual: float32 != <class 'numpy.int32'>
このエラーは、正解データを、一次元の numpy.int32の配列にしていない時に出るっぽい。
入力データは、 [0,1,2] みたいに、1次元配列でなければいけない。
(そしてデータは0から始まるnumpy.int32型でないとダメ)
data.astype(numpy.int32) で型を明示的に指定するといい。
学習データは、2次元のfloat32データ np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32) 正解データは、1次元のint32データで0から開始する np.array([0,1,2]).astype(np.int32)
学習データは numpy.float32 でなければならないらしい
Traceback (most recent call last): File "test.py", line 54, in <module> trainer.run() File "chainer\training\trainer.py", line 289, in run update() File "chainer\training\updater.py", line 170, in update self.update_core() File "chainer\training\updater.py", line 182, in update_core optimizer.update(loss_func, *in_vars) File "chainer\optimizer.py", line 390, in update loss = lossfun(*args, **kwds) File "chainer\links\model\classifier.py", line 67, in __call__ self.y = self.predictor(*x) File "test.py", line 22, in __call__ h1 = F.relu(self.l1(x)) File "chainer\links\connection\linear.py", line 92, in __call__ return linear.linear(x, self.W, self.b) File "chainer\functions\connection\linear.py", line 79, in linear return LinearFunction()(x, W, b) File "chainer\function.py", line 189, in __call__ self._check_data_type_forward(in_data) File "chainer\function.py", line 280, in _check_data_type_forward type_check.InvalidType(e.expect, e.actual, msg=msg), None) File "<string>", line 2, in raise_from chainer.utils.type_check.InvalidType: Invalid operation is performed in: LinearFunction (Forward) Expect: in_types[2].dtype == in_types[0].dtype Actual: float32 != float64
このエラーは学習データを numpy.float32 にしていないと出るらしい。
data = data.astype(numpy.float32) として、numpy.float32へ変換すると解決できます。
学習データは、2次元のfloat32データ np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32) 正解データは、1次元のint32データで0から開始する np.array([0,1,2]).astype(np.int32)
学習データの個数があっていないときのエラー
Traceback (most recent call last): File "test.py", line 54, in <module> trainer.run() File "chainer\training\trainer.py", line 289, in run update() File "chainer\training\updater.py", line 170, in update self.update_core() File "chainer\training\updater.py", line 182, in update_core optimizer.update(loss_func, *in_vars) File "chainer\optimizer.py", line 390, in update loss = lossfun(*args, **kwds) File "chainer\links\model\classifier.py", line 67, in __call__ self.y = self.predictor(*x) File "test.py", line 22, in __call__ h1 = F.relu(self.l1(x)) File "chainer\links\connection\linear.py", line 92, in __call__ return linear.linear(x, self.W, self.b) File "chainer\functions\connection\linear.py", line 79, in linear return LinearFunction()(x, W, b) File "chainer\function.py", line 189, in __call__ self._check_data_type_forward(in_data) File "chainer\function.py", line 280, in _check_data_type_forward type_check.InvalidType(e.expect, e.actual, msg=msg), None) File "<string>", line 2, in raise_from 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: 5 != 4
このエラーは、学習データの個数があっていなときにでるっぽい。
たとえば、以下のようなモデルがあった場合、学習データは[ [1,2,3,4],[5,6,7,8],[9,10,11,12] ] みたいに、定義した数と個数があっていないといけないらしい。
class IrisModel(Chain): def __init__(self): super(IrisModel, self).__init__( l1=L.Linear(4, 100), #学習データ l2=L.Linear(100, 100), l3=L.Linear(100, 3), ) def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) y = self.l3(h2) return y
l1=L.Linear(学習データの個数, 100),
学習データの個数 = 4 だった場合
学習データは、 [ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]みたいに、要素が4つの要素を持っていないとダメです。
上の例だと、len(arr[0])==4 len(arr[1])==4 len(arr[2])==4 です。( len(arr) ではなく、 len(arr[0])の方の要素数の話です。 )
それを間違えて、 [ [1,2,3,4,99],[5,6,7,8,99],[9,10,11,12,99] ] みたいに個数を間違えると、このエラーが発生します。
学習データは、2次元のfloat32データ np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32) 正解データは、1次元のint32データで0から開始する np.array([0,1,2]).astype(np.int32)