Fender12345
@Fender12345 (Fender 12345)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

CNNの全結合層の出力サイズ確認におけるAssertionErrorの対処

解決したいこと

1層CNNの全結合層の出力サイズを確かめた際に表示されたAssertionErrorの対処方法

発生している問題・エラー

1層CNNの全結合層の入力サイズを確かめてみました。

(前回の質問でご回答いただけた内容を用いております)
https://qiita.com/ZZE12345/questions/d209d73d09ff42010ff7

AssertionError                            Traceback (most recent call last)
<ipython-input-386-59bf517e9f78> in <module>()
     41 # ---------- CNNの出力確認 ----------
     42 cnn = CNN()                   #インスタンスの作成
---> 43 print(cnn(size_check).shape)  #AssertionErrorの発生...原因は??
     44 
     45 #       except AssertionError:

<ipython-input-386-59bf517e9f78> in __call__(self, x)
     27 
     28     def __call__(self, x):
---> 29         conv1 = self.conv1(x)
     30         bat1  = self.bat1(conv1)
     31         relu1 = F.relu(bat1)

~\Anaconda3\lib\site-packages\chainer\link.py in __call__(self, *args, **kwargs)
    285             # forward is implemented in the child classes
    286             forward = self.forward  # type: ignore
--> 287         out = forward(*args, **kwargs)
    288 
    289         # Call forward_postprocess hook

~\Anaconda3\lib\site-packages\chainer\links\connection\convolution_nd.py in forward(self, x)
    213         return convolution_nd.convolution_nd(
    214             x, self.W, self.b, self.stride, self.pad, cover_all=self.cover_all,
--> 215             dilate=self.dilate, groups=self.groups)
    216 
    217 

~\Anaconda3\lib\site-packages\chainer\functions\connection\convolution_nd.py in convolution_nd(x, W, b, stride, pad, cover_all, dilate, groups)
    497     ndim = len(x.shape[2:])
    498     fnode = ConvolutionND(
--> 499         ndim, stride, pad, cover_all, dilate=dilate, groups=groups)
    500     args = (x, W) if b is None else (x, W, b)
    501     y, = fnode.apply(args)

~\Anaconda3\lib\site-packages\chainer\functions\connection\convolution_nd.py in __init__(self, ndim, stride, pad, cover_all, dilate, groups)
     23         self.pad = conv_nd.as_tuple(pad, ndim)
     24         self.cover_all = cover_all
---> 25         self.dilate = conv_nd.as_tuple(dilate, ndim)
     26         self.groups = groups
     27 

~\Anaconda3\lib\site-packages\chainer\utils\conv_nd.py in as_tuple(x, n)
     11 def as_tuple(x, n):
     12     if hasattr(x, '__getitem__'):
---> 13         assert len(x) == n
     14         return tuple(x)
     15     return (x,) * n

AssertionError: 

該当するソースコード

Chainerを使用して、L.ConvolutionNDで1層CNNを作成しました。
最下段の「print(cnn(size_check).shape)」でAssertionErrorが発生しております

#---------- import ----------
import chainer
import chainer.functions as F
import chainer.links as L
import numpy as np
import pandas as pd
import scipy.io

# ---------- 入力データの作成 ----------

abc = chainer.Variable(np.array([[1, 2, 3] , [4, 5, 6] , [7, 8, 9] , [10, 11, 12]], dtype=np.float32))
size_check = abc
print("size_check.shape",size_check.shape) 

# ---------- CNNの定義 ----------
class CNN(chainer.Chain):
    def __init__(self):
        super(CNN,self).__init__()
        with self.init_scope():
            self.conv1  = L.ConvolutionND(1,4,10,3,stride=1,pad=1)  #(1次元畳み込み,入力4ch,出力10ch,フィルターサイズ:3、stride=1,pad=1)
            self.bat1   = L.BatchNormalization(10)
            self.l1     = L.Linear(None, 3)

    def __call__(self, x):
        conv1 = self.conv1(x)
        bat1  = self.bat1(conv1)
        relu1 = F.relu(bat1)
        pool1 = F.max_pooling_nd(relu1,2,Stride=1)
        xyz   = self.l1(pool1)
        return xyz 
    
    def check_cnn_size(self,size_check):
        out = self(size_check)
        return out   
    
# ---------- CNNの出力確認 ----------
cnn = CNN()                   #インスタンスの作成    
print(cnn(size_check).shape)  #AssertionErrorの発生...原因は??

確認したこと

AssertionErrorについて調べてみましたが、
assert文で宣言された条件がFalseだった場合にAssertionErrorが表示されるとのことでした。

おそらく....エラーコード内の下記部分が該当すると予想しておりますが
自力では対処方法が分からず困っております
_____________________________________
~\Anaconda3\lib\site-packages\chainer\utils\conv_nd.py in as_tuple(x, n)
11 def as_tuple(x, n):
12 if hasattr(x, 'getitem'):
---> 13 assert len(x) == n
14 return tuple(x)
15 return (x,) * n
_____________________________________

0

1Answer

batch_size分の階数が足りなくてエラーが起きてます.

-   abc = chainer.Variable(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], dtype = np.float32))
+   abc = chainer.Variable(np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]], dtype = np.float32))

AssertionErrorを出す比較文len(x) == nにおいて,len(x)xの最初の階数の次元数を取得します.が,nと比較してFalseだったということです1.あってるはずの次元数を比較して間違っているのであれば,階数が足りないのではと考えてバッチサイズ分の階数を追加してみたところ,AssertionErrorは消えました.

  1. エラー文においてconvolution_nd.pyの497行目にあるndim = len(x.shape[2:])で,チャネルの階数2より後の階数の個数をndimとしていることがわかります.AssertionErrorを出したconv_nd.as_tuple(dilate, ndim)を呼ぶときに第二引数としてas_tuple(x, n)に渡されて,len(x) == nという比較になりました.dilateは途中で加工されて(1,)になっており,len((1,))1です.len(x.shape[2:])0だったために比較文がFalseになりました.

  2. 階数と内容は順にバッチの階数(バッチサイズ),チャネルの階数(チャネル数),特徴量1の階級数(特徴量1のサイズ),特徴量2の階数(特徴量2のサイズ),...となっています.入力データxのshapeは必ず0番目にバッチサイズを入れる階数が存在してなければなりません.

1Like

Comments

  1. @Fender12345

    Questioner

    PondVillege様

    ご回答ありがとうございます!
    エラーが解決せず困っていたので感謝しております。

    AssertionErrorの原因について、batch_size分の階級が足りなくてエラー発生とのこと、理解できました。
    おそらく、Trainなどで学習⇔誤差把握を繰り返す作業を行うためにChainerの関数が最適化されているため、今回のように任意のデータを1つだけ入れた場合Chainer側の想定と異なっていたことで、batch_size分の階級に該当する[]を1セット追加する必要があったと理解しました。

    また、今回のご回答でAssertionErrorの際にどこがNGだったかも、コードを追いつつ把握できました。ありがとうございました。
  2. 伝わってよかったです.質問をクローズにするのをお忘れなきよう.

Your answer might help someone💌