studylog/北の雲

chainer/python/nlp

Chainerメモ12 恐怖のActualエラー

chainerを触りだした頃に一番遭遇していたエラーです。トラウマになりそうでした。

こんなやつ。

chainer.utils.type_check.InvalidType: Expect: in_types[0].ndim == 1
Actual: 2 != 1

#こういうパターンもある 不等号だったりもする
Actual: (1,2) != (1,1)

どういう意味か

データの次元やshapeなどが正しくないという意味です。
Actual: 2 != 1の場合は、左が入力された間違った次元、右が本来入力されるべき正しい次元です。
Actual: (1,2) != (1,1)だったら本来は右の(1,1)というshapeで入力されるべきなのに(1,2)で来ちゃってますよということ。

で、この記事を書く前までは「左は自分が入力した間違い、右はchainerが求めている正しい次元」で固定されてると思っていたのですが、どうやら状況によっては左右が逆になったりしている?ようで混乱しています。はっきりしたことがわかれば追記するかもしれません。

追記:中の人のブログ記事も参考に
Chainerのtype_check
unnonouno: Chainerのtype_check

またありがちな例としてこんなのも。

Actual: (1, 1) != (1,)

そもそも(1,1)と(1,)ってどう違うかというと、

a = numpy.array([0])
a.shape #=>(1,)

b = numpy.array([[0]])
b.shape #=>(1,1)

です。

たいていの場合はバッチ処理(複数のデータを入力して、同時に計算する)で書かれたサンプルコードをよくわからないなりに修正しながら自分の処理を書いていると、いつのまにか入力データはバッチだけど正解データはバッチじゃなくなってる、という具合でshapeが不一致になってしまうのかなと思います。自分も触りだした頃にmnistサンプルを何がなんだかわからないなりに弄っててよくActualエラーに遭遇していました。

このエラーが出たらどうすればいいのか

エラーが出たところのVariableのdataをprintなりでshapeを確認してください。

chainer.functions.mean_squared_error(x, y)

ここでActual: (1, 1) != (1,)と出たら、xとyのshapeを確認すればたいていの場合は解決します。

print(x.data)
#あるいは
print(x.data.shape)

今度はバッチ処理の書き方をチュートリアルっぽくまとめてみたいと思います。