開発のヒホ

iOSとかAndroidとかのアプリを開発するのに四苦八苦するブログ

TypeError: type object argument after * must be a sequence, not FunctionSet

 chainerでサンプルコードを動かすと、optimizer.setupでこけた。

>>> import numpy as np
>>> from chainer import cuda, Function, FunctionSet, gradient_check, Variable, optimizers, utils
>>> import chainer.functions as F
>>> model = FunctionSet(
...     l1 = F.Linear(4, 3),
...     l2 = F.Linear(3, 2),
... )
>>> optimizer = optimizers.SGD()
>>> optimizer.setup(model)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/site-packages/chainer/optimizer.py", line 51, in setup
    for p, g in zip(*params_grads):
TypeError: type object argument after * must be a sequence, not FunctionSet

 model内のl1やl2の勾配を設定していないことが原因だ。実はchainerはバージョン1.3.1辺りから、setupするだけで勾配の初期値を設定してくれるようになった。旧バージョンだと別の関数を叩く必要があるが、最新版はsetupだけで良いのだ。つまりこのエラーをなんとかするには、chainerのバージョンを上げればいい。

sudo pip3 install --upgrade chainer

MATLABのparfor内でSubscripted assignment between dissimilar structuresエラー

 MATLABで唯一(?)マルチスレッドが可能になるparfor、かなり便利に作られている反面、意図しない予想外なエラーがぽこぽこ出てきて困る時があります。

 今回はparfor内でSubscripted assignment between dissimilar structures.というエラーが出ました。

inputs(1:10) = struct('data', 10)
outputs = []
parfor i = 1:10
    inputs(i).data2 = inputs(i).data^2;
    outputs = [outputs struct('data', inputs(i).data2)];
end

 エラー文は以下の感じ。

Error using (parfor consume)
Subscripted assignment between dissimilar structures.

Error in (line 1)
parfor i = 1:10

Caused by:
    Subscripted assignment between dissimilar
    structures.

 parfor内のエラーは発生箇所が明確にわからず、デバッグが困難になる場合が多いのでparfor文からfor文に直すのですが、forだとエラーは発生しない・・・
 このエラー文を検索すると、struct配列のフィールドの不一致が原因です。今回inputsとoutputsの2つのstruct配列がありますが、この場合はinputsが原因です。

 どうやらparfor内でstruct配列の一部のフィールドを改変したためなようです。
 parfor内でstruct配列の一部のフィールドが変わると他との整合性が取れなくてエラーになるのでしょう。for文ではうまいこと整合性を取るのでエラーになりません。なるほど。

zipファイル内のJSONファイルをzipfileとjsonで読み込む

 全然スマートじゃないですが、読み込めたので、まあ良しとしてください。
 JSONファイルに日本語などが混じっている場合は、最後の.decode()で適切な文字コードを指定する必要があるかと思います。

import json
import zipfile

zippath = 'test.zip'
z = zipfile.ZipFile(zippath)

jsonname = 'test.json'
j = json.loads( z.open(jsonname, 'r').read().decode() )

参考にしたWebページ
13.5. zipfile — ZIP アーカイブの処理 — Python 3.4.3 ドキュメント
19.2. json — JSON エンコーダおよびデコーダ — Python 3.3.6 ドキュメント