スキップしてメイン コンテンツに移動

1906.09 ChainerのNNモデルの定義でビギナーが陥りやすいエラー 4例

1906.09 ChainerのNNモデルの定義でビギナーが陥りやすいエラー 4例

Chainerを始めて、エラーが起こると、そのエラーの説明表示を見ても、よく分からないことが多い。ここでは、問題形式で、ビギナーが陥りやすいエラーを4例、挙げてみました。

例1

例えば、以下のコードを実行すると「Expect: in_types[2].dtype == in_types[0].dtype」「Actual: float32 != float64」のエラーが発生する。何がいけないのか?
In [1]:
# sec: lib

import numpy as np

import chainer
import chainer.links as L
import chainer.functions as F

# sec: ver

chainer.print_runtime_info()
Platform: Windows-7-6.1.7601-SP1
Chainer: 5.3.0
NumPy: 1.16.2
CuPy: Not Available
iDeep: Not Available

NNモデルを定義

In [2]:
class MyConvNet(chainer.Chain):

    def __init__(self):
        super(MyConvNet, self).__init__()

        # パラメータを持つ層の登録
        with self.init_scope():
            self.c1 = L.Convolution2D(None, 20, ksize=3, stride=2, pad=0)
            self.c2 = L.Convolution2D(None, 40, ksize=3, stride=2, pad=0)
            self.l1 = L.Linear(None, 100)
            self.l2 = L.Linear(None, 100)
            self.l3 = L.Linear(None, 40)

    def forward(self, x):
        # データを受け取った際のforward計算を書く
        
        # sec: conv
        
        print("x", x.shape, np.prod(x.shape[1:]))
        h = F.relu(self.c1(x))
        print("conv1", h.shape, np.prod(h.shape[1:]))
        h = F.relu(self.c2(h))
        print("conv2", h.shape, np.prod(h.shape[1:]))
        
        # sec: fc
        
        h = F.relu(self.l1(h))
        print("fc1", h.shape)
        h = F.relu(self.l2(h))
        print("fc2", h.shape)
        h = self.l3(h)
        print("fc3", h.shape)
        return h

NNモデルをチェック

In [3]:
n_batch = 128
n_ch = 3
n_height = 20
n_width = 120

# sec: NNモデルの出力値を計算

model = MyConvNet()

x = np.zeros((n_batch, n_ch, n_height, n_width))
y = model(x)
print("y", y.shape)
x (128, 3, 20, 120) 7200
---------------------------------------------------------------------------
InvalidType                               Traceback (most recent call last)
<ipython-input-3-483ddd3c675a> in <module>
      9 
     10 x = np.zeros((n_batch, n_ch, n_height, n_width))
---> 11 y = model(x)
     12 print("y", y.shape)

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\link.py in __call__(self, *args, **kwargs)
    240         if forward is None:
    241             forward = self.forward
--> 242         out = forward(*args, **kwargs)
    243 
    244         # Call forward_postprocess hook

<ipython-input-2-1f801910ef7f> in forward(self, x)
     18 
     19         print("x", x.shape, np.prod(x.shape[1:]))
---> 20         h = F.relu(self.c1(x))
     21         print("conv1", h.shape, np.prod(h.shape[1:]))
     22         h = F.relu(self.c2(h))

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\link.py in __call__(self, *args, **kwargs)    240         if forward is None:
    241             forward = self.forward
--> 242         out = forward(*args, **kwargs)
    243 
    244         # Call forward_postprocess hook

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\links\connection\convolution_2d.py in forward(self, x)    173         return convolution_2d.convolution_2d(
    174             x, self.W, self.b, self.stride, self.pad, dilate=self.dilate,
--> 175             groups=self.groups)
    176 
    177 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\connection\convolution_2d.py in convolution_2d(x, W, b, stride, pad, cover_all, **kwargs)    569     else:
    570         args = x, W, b
--> 571     y, = fnode.apply(args)
    572     return y

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in apply(self, inputs)    243 
    244         if configuration.config.type_check:
--> 245             self._check_data_type_forward(in_data)
    246 
    247         hooks = chainer.get_function_hooks()

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in _check_data_type_forward(self, in_data)    328         in_type = type_check.get_types(in_data, 'in_types', False)
    329         with type_check.get_function_check_context(self):
--> 330             self.check_type_forward(in_type)
    331 
    332     def check_type_forward(self, in_types):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\connection\convolution_2d.py in check_type_forward(self, in_types)     72                 b_type.dtype == x_type.dtype,
     73                 b_type.ndim == 1,
---> 74                 b_type.shape[0] == w_type.shape[0],
     75             )
     76 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\utils\type_check.py in expect(*bool_exprs)    544         for expr in bool_exprs:
    545             assert isinstance(expr, Testable)
--> 546             expr.expect()
    547 
    548 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\utils\type_check.py in expect(self)    481             raise InvalidType(
    482                 '{0} {1} {2}'.format(self.lhs, self.exp, self.rhs),
--> 483                 '{0} {1} {2}'.format(left, self.inv, right))
    484 
    485 

InvalidType: 
Invalid operation is performed in: Convolution2DFunction (Forward)

Expect: in_types[2].dtype == in_types[0].dtype
Actual: float32 != float64

修正点

これは、ChainerのNNモデルに入力する変数xの型は既定でfloat32でなくてはならないが、np.zerosを使うと既定ではfloat64の型で生成されるので、明示的にfloat32で定義する必要がある。「x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")」のように修正しなくてはならない。
知っている人にとっては当たり前に感じるが、知らない人にとっては思い付きようがないので苦労するだろうと思います。。。
In [4]:
n_batch = 128
n_ch = 3
n_height = 20
n_width = 120

# sec: NNモデルの出力値を計算

model = MyConvNet()

x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")
y = model(x)
print("y", y.shape)
x (128, 3, 20, 120) 7200
conv1 (128, 20, 9, 59) 10620
conv2 (128, 40, 4, 29) 4640
fc1 (128, 100)
fc2 (128, 100)
fc3 (128, 40)
y (128, 40)

例2

例えば、以下のコードを実行すると「Expect: t.dtype.kind == i」「Actual: f != i」のエラーが発生する。何がいけないのか?
In [5]:
import numpy as np

import chainer
import chainer.links as L
import chainer.functions as F

chainer.print_runtime_info()
Platform: Windows-7-6.1.7601-SP1
Chainer: 5.3.0
NumPy: 1.16.2
CuPy: Not Available
iDeep: Not Available

NNモデルを定義

In [6]:
class MyConvNet(chainer.Chain):

    def __init__(self):
        super(MyConvNet, self).__init__()

        # パラメータを持つ層の登録
        with self.init_scope():
            self.c1 = L.Convolution2D(None, 20, ksize=3, stride=2, pad=0)
            self.c2 = L.Convolution2D(None, 40, ksize=3, stride=2, pad=0)
            self.l1 = L.Linear(None, 100)
            self.l2 = L.Linear(None, 100)
            self.l3 = L.Linear(None, 40)

    def forward(self, x):
        # データを受け取った際のforward計算を書く
        
        # sec: conv
        
        print("x", x.shape, np.prod(x.shape[1:]))
        h = F.relu(self.c1(x))
        print("conv1", h.shape, np.prod(h.shape[1:]))
        h = F.relu(self.c2(h))
        print("conv2", h.shape, np.prod(h.shape[1:]))
        
        # sec: fc
        
        h = F.relu(self.l1(h))
        print("fc1", h.shape)
        h = F.relu(self.l2(h))
        print("fc2", h.shape)
        h = self.l3(h)
        print("fc3", h.shape)
        return h

NNモデルのチェック

In [7]:
n_batch = 128
n_ch = 1
n_height = 20
n_width = 120

# sec: NNモデルの出力値を計算

model = MyConvNet()

x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")
y = model(x)
print("y", y.shape)
x (128, 1, 20, 120) 2400
conv1 (128, 20, 9, 59) 10620
conv2 (128, 40, 4, 29) 4640
fc1 (128, 100)
fc2 (128, 100)
fc3 (128, 40)
y (128, 40)
In [8]:
# sec: 勾配を計算

loss = F.softmax_cross_entropy(y, np.zeros(n_batch))
print(loss)

model.cleargrads()
loss.backward()
---------------------------------------------------------------------------
InvalidType                               Traceback (most recent call last)
<ipython-input-8-76e8540795b5> in <module>
      1 # sec: 勾配を計算
      2 
----> 3 loss = F.softmax_cross_entropy(y, np.zeros(n_batch))
      4 print(loss)
      5 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\loss\softmax_cross_entropy.py in softmax_cross_entropy(x, t, normalize, cache_score, class_weight, ignore_label, reduce, enable_double_backprop)    380     else:
    381         return SoftmaxCrossEntropy(
--> 382             normalize, cache_score, class_weight, ignore_label, reduce)(x, t)

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function.py in __call__(self, *inputs)    231         self._owned_node = None
    232 
--> 233         ret = node.apply(inputs)
    234 
    235         if len(ret) == 1:

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in apply(self, inputs)    243 
    244         if configuration.config.type_check:
--> 245             self._check_data_type_forward(in_data)
    246 
    247         hooks = chainer.get_function_hooks()

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in _check_data_type_forward(self, in_data)    328         in_type = type_check.get_types(in_data, 'in_types', False)
    329         with type_check.get_function_check_context(self):
--> 330             self.check_type_forward(in_type)
    331 
    332     def check_type_forward(self, in_types):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function.py in check_type_forward(self, in_types)    128 
    129     def check_type_forward(self, in_types):
--> 130         self._function.check_type_forward(in_types)
    131 
    132     def forward(self, inputs):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\loss\softmax_cross_entropy.py in check_type_forward(self, in_types)     76 
     77             x_type.shape[0] == t_type.shape[0],
---> 78             x_type.shape[2:] == t_type.shape[1:],
     79         )
     80 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\utils\type_check.py in expect(*bool_exprs)    544         for expr in bool_exprs:
    545             assert isinstance(expr, Testable)
--> 546             expr.expect()
    547 
    548 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\utils\type_check.py in expect(self)    481             raise InvalidType(
    482                 '{0} {1} {2}'.format(self.lhs, self.exp, self.rhs),
--> 483                 '{0} {1} {2}'.format(left, self.inv, right))
    484 
    485 

InvalidType: 
Invalid operation is performed in: SoftmaxCrossEntropy (Forward)

Expect: t.dtype.kind == i
Actual: f != i

修正点

これは、クラス識別のタクスでsoftmaxを用いた場合の真値ラベルの型はint32でなくてはならないが、np.zerosを使うと既定ではfloat64の型で生成されるので、明示的にint32で定義する必要がある。「np.zeros(n_batch, dtype="int32")」のように修正しなくてはならない。
知っている人にとっては当たり前に感じるが、知らない人にとっては思い付きようがないので苦労するだろうと思います。。。
In [10]:
# sec: 勾配を計算

loss = F.softmax_cross_entropy(y, np.zeros(n_batch, dtype="int32"))
print(loss)

model.cleargrads()
loss.backward()
variable(3.68888)

例3

例えば、以下のコードを実行すると「AssertionError: Height in the output should be positive.」のエラーが発生する。何がいけないのか?
In [5]:
import numpy as np

import chainer
import chainer.links as L
import chainer.functions as F

chainer.print_runtime_info()
Platform: Windows-7-6.1.7601-SP1
Chainer: 5.3.0
NumPy: 1.16.2
CuPy: Not Available
iDeep: Not Available

NNモデルを定義

In [21]:
class MyConvNet(chainer.Chain):

    def __init__(self):
        super(MyConvNet, self).__init__()

        # パラメータを持つ層の登録
        with self.init_scope():
            self.c1 = L.Convolution2D(None, 20, ksize=5, stride=5, pad=0)
            self.c2 = L.Convolution2D(None, 40, ksize=5, stride=5, pad=0)
            self.l1 = L.Linear(None, 100)
            self.l2 = L.Linear(None, 100)
            self.l3 = L.Linear(None, 40)

    def forward(self, x):
        # データを受け取った際のforward計算を書く
        
        # sec: conv
        
        print("x", x.shape, np.prod(x.shape[1:]))
        h = F.relu(self.c1(x))
        print("conv1", h.shape, np.prod(h.shape[1:]))
        h = F.relu(self.c2(h))
        print("conv2", h.shape, np.prod(h.shape[1:]))
        
        # sec: fc
        
        h = F.relu(self.l1(h))
        print("fc1", h.shape)
        h = F.relu(self.l2(h))
        print("fc2", h.shape)
        h = self.l3(h)
        print("fc3", h.shape)
        return h

NNモデルのチェック

In [22]:
n_batch = 128
n_ch = 1
n_height = 20
n_width = 120

# sec: NNモデルの出力値を計算

model = MyConvNet()

x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")
y = model(x)
print("y", y.shape)
x (128, 1, 20, 120) 2400
conv1 (128, 20, 4, 24) 1920
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-22-b3b11233d48c> in <module>
      9 
     10 x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")
---> 11 y = model(x)
     12 print("y", y.shape)

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\link.py in __call__(self, *args, **kwargs)    240         if forward is None:
    241             forward = self.forward
--> 242         out = forward(*args, **kwargs)
    243 
    244         # Call forward_postprocess hook

<ipython-input-21-747056a5fafd> in forward(self, x)
     20         h = F.relu(self.c1(x))
     21         print("conv1", h.shape, np.prod(h.shape[1:]))
---> 22         h = F.relu(self.c2(h))
     23         print("conv2", h.shape, np.prod(h.shape[1:]))
     24 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\link.py in __call__(self, *args, **kwargs)    240         if forward is None:
    241             forward = self.forward
--> 242         out = forward(*args, **kwargs)
    243 
    244         # Call forward_postprocess hook

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\links\connection\convolution_2d.py in forward(self, x)    173         return convolution_2d.convolution_2d(
    174             x, self.W, self.b, self.stride, self.pad, dilate=self.dilate,
--> 175             groups=self.groups)
    176 
    177 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\connection\convolution_2d.py in convolution_2d(x, W, b, stride, pad, cover_all, **kwargs)    569     else:
    570         args = x, W, b
--> 571     y, = fnode.apply(args)
    572     return y

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in apply(self, inputs)    261                 outputs = static_forward_optimizations(self, in_data)
    262             else:
--> 263                 outputs = self.forward(in_data)
    264 
    265         # Check for output array types

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in forward(self, inputs)    368         if isinstance(inputs[0], cuda.ndarray):
    369             return self.forward_gpu(inputs)
--> 370         return self.forward_cpu(inputs)
    371 
    372     def forward_cpu(self, inputs):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\connection\convolution_2d.py in forward_cpu(self, inputs)    103             return self._forward_grouped_convolution(x, W, b)
    104         else:
--> 105             return self._forward_cpu_core(x, W, b)
    106 
    107     def _forward_cpu_core(self, x, W, b):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\connection\convolution_2d.py in _forward_cpu_core(self, x, W, b)    112         col = conv.im2col_cpu(
    113             x, kh, kw, self.sy, self.sx, self.ph, self.pw,
--> 114             cover_all=self.cover_all, dy=self.dy, dx=self.dx)
    115         y = numpy.tensordot(
    116             col, W, ((1, 2, 3), (1, 2, 3))).astype(x.dtype, copy=False)

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\utils\conv.py in im2col_cpu(img, kh, kw, sy, sx, ph, pw, pval, cover_all, dy, dx, out_h, out_w)     69     if out_h is None:
     70         out_h = get_conv_outsize(h, kh, sy, ph, cover_all, dy)
---> 71     assert out_h > 0, 'Height in the output should be positive.'
     72     if out_w is None:
     73         out_w = get_conv_outsize(w, kw, sx, pw, cover_all, dx)

AssertionError: Height in the output should be positive.

修正点

これは、ダミーの入力画像の縦長さが20pxに対して、Convolution2D層の処理設定がksize=5, stride=5, pad=0なので、当層の出力の画像サイズが小さくなっていき、縦長さが無くなってしまったために発生している。「L.Convolution2D(None, 20, ksize=5, stride=2, pad=0)」などのように修正しなくてはならない。
知っている人にとっては当たり前に感じるが、知らない人にとっては思い付きようがないので苦労するだろうと思います。。。
In [19]:
class MyConvNet(chainer.Chain):

    def __init__(self):
        super(MyConvNet, self).__init__()

        # パラメータを持つ層の登録
        with self.init_scope():
            self.c1 = L.Convolution2D(None, 20, ksize=5, stride=2, pad=0)
            self.c2 = L.Convolution2D(None, 40, ksize=5, stride=2, pad=0)
            self.l1 = L.Linear(None, 100)
            self.l2 = L.Linear(None, 100)
            self.l3 = L.Linear(None, 40)

    def forward(self, x):
        # データを受け取った際のforward計算を書く
        
        # sec: conv
        
        print("x", x.shape, np.prod(x.shape[1:]))
        h = F.relu(self.c1(x))
        print("conv1", h.shape, np.prod(h.shape[1:]))
        h = F.relu(self.c2(h))
        print("conv2", h.shape, np.prod(h.shape[1:]))
        
        # sec: fc
        
        h = F.relu(self.l1(h))
        print("fc1", h.shape)
        h = F.relu(self.l2(h))
        print("fc2", h.shape)
        h = self.l3(h)
        print("fc3", h.shape)
        return h
In [20]:
n_batch = 128
n_ch = 1
n_height = 20
n_width = 120

# sec: NNモデルの出力値を計算

model = MyConvNet()

x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")
y = model(x)
print("y", y.shape)
x (128, 1, 20, 120) 2400
conv1 (128, 20, 8, 58) 9280
conv2 (128, 40, 2, 27) 2160
fc1 (128, 100)
fc2 (128, 100)
fc3 (128, 40)
y (128, 40)

例4

例えば、以下のコードを実行すると「IndexError: index 40 is out of bounds for axis 0 with size 40」のエラーが発生する。何がいけないのか?
In [23]:
import numpy as np

import chainer
import chainer.links as L
import chainer.functions as F

chainer.print_runtime_info()
Platform: Windows-7-6.1.7601-SP1
Chainer: 5.3.0
NumPy: 1.16.2
CuPy: Not Available
iDeep: Not Available

NNモデルを定義

In [24]:
class MyConvNet(chainer.Chain):

    def __init__(self):
        super(MyConvNet, self).__init__()

        # パラメータを持つ層の登録
        with self.init_scope():
            self.c1 = L.Convolution2D(None, 20, ksize=3, stride=2, pad=0)
            self.c2 = L.Convolution2D(None, 40, ksize=3, stride=2, pad=0)
            self.l1 = L.Linear(None, 100)
            self.l2 = L.Linear(None, 100)
            self.l3 = L.Linear(None, 40)

    def forward(self, x):
        # データを受け取った際のforward計算を書く
        
        # sec: conv
        
        print("x", x.shape, np.prod(x.shape[1:]))
        h = F.relu(self.c1(x))
        print("conv1", h.shape, np.prod(h.shape[1:]))
        h = F.relu(self.c2(h))
        print("conv2", h.shape, np.prod(h.shape[1:]))
        
        # sec: fc
        
        h = F.relu(self.l1(h))
        print("fc1", h.shape)
        h = F.relu(self.l2(h))
        print("fc2", h.shape)
        h = self.l3(h)
        print("fc3", h.shape)
        return h

NNモデルのチェック

In [25]:
n_batch = 128
n_ch = 1
n_height = 20
n_width = 120

# sec: NNモデルの出力値を計算

model = MyConvNet()

x = np.zeros((n_batch, n_ch, n_height, n_width), dtype="float32")
y = model(x)
print("y", y.shape)
x (128, 1, 20, 120) 2400
conv1 (128, 20, 9, 59) 10620
conv2 (128, 40, 4, 29) 4640
fc1 (128, 100)
fc2 (128, 100)
fc3 (128, 40)
y (128, 40)
In [26]:
# sec: 勾配を計算

loss = F.softmax_cross_entropy(y, np.arange(0, n_batch, dtype="int32"))
print(loss)

model.cleargrads()
loss.backward()
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-26-304aa0a6e035> in <module>
      1 # sec: 勾配を計算
      2 
----> 3 loss = F.softmax_cross_entropy(y, np.arange(0, n_batch, dtype="int32"))
      4 print(loss)
      5 

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\loss\softmax_cross_entropy.py in softmax_cross_entropy(x, t, normalize, cache_score, class_weight, ignore_label, reduce, enable_double_backprop)    380     else:
    381         return SoftmaxCrossEntropy(
--> 382             normalize, cache_score, class_weight, ignore_label, reduce)(x, t)

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function.py in __call__(self, *inputs)    231         self._owned_node = None
    232 
--> 233         ret = node.apply(inputs)
    234 
    235         if len(ret) == 1:

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function_node.py in apply(self, inputs)    261                 outputs = static_forward_optimizations(self, in_data)
    262             else:
--> 263                 outputs = self.forward(in_data)
    264 
    265         # Check for output array types

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function.py in forward(self, inputs)    133         # Retain all inputs by default in old-style functions.
    134         self.retain_inputs(six.moves.range(len(inputs)))
--> 135         return self._function.forward(inputs)
    136 
    137     def backward(self, target_input_indexes, grad_outputs):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\function.py in forward(self, inputs)    340             return self.forward_gpu(inputs)
    341         else:
--> 342             return self.forward_cpu(inputs)
    343 
    344     def forward_cpu(self, inputs):

C:\Users\...\WPy32-3720\python-3.7.2\lib\site-packages\chainer\functions\loss\softmax_cross_entropy.py in forward_cpu(self, inputs)     94         t_valid = t != self.ignore_label
     95         t = t * t_valid
---> 96         log_p = log_yd[t.ravel(), numpy.arange(t.size)]
     97 
     98         log_p *= t_valid.ravel()

IndexError: index 40 is out of bounds for axis 0 with size 40

修正点

これは、NNモデルの出力の数が「self.l3 = L.Linear(None, 40)」と定義されており、0~39までの40カテゴリの範囲に収まらなくてはいけないが、真値ラベルは「np.arange(0, n_batch, dtype="int32")」となっており、0~127までの値がsoftmaxに入るので、40以上のカテゴリは範囲外というエラーが発生している。「np.arange(0, n_batch, dtype="int32") % 40」などのように修正しなくてはならない。
知っている人にとっては当たり前に感じるが、知らない人にとっては思い付きようがないので苦労するだろうと思います。。。
In [27]:
# sec: 勾配を計算

loss = F.softmax_cross_entropy(y, np.arange(0, n_batch, dtype="int32") % 40)
print(loss)

model.cleargrads()
loss.backward()
variable(3.68888)

1906.08 Chainerでエラーが起こると意味が分からないことがある

Chainerは、エラーが起こると、そのエラーの説明表示を見ても、Pythonの呼び出し履歴のログを見ても、なぜエラーになっているのか、全く分からない事があります。Chainerを使い始めたよく知らない人にとっては、死活問題。恐らく、ここで挫折して、Chainerの利用を諦めてしまう人がいるのではないかと危惧しています。

コメント