Chainer: 中間層のノード数を可変にしてみよう


2017年 04月 19日

サンプルプログラム train_mnist.py のネットワークの定義は以下のようになっていた。

    def __init__(self, n_units, n_out):
super(MLP, self).__init__(
# the size of the inputs to each layer will be inferred
l1=L.Linear(None, n_units),  # n_in -> n_units
l2=L.Linear(None, n_units),  # n_units -> n_units
l3=L.Linear(None, n_out),  # n_units -> n_out
)
このプログラムでは、入力層のサイズは指定がなく、データにより自動決定される。
2つの中間層はいずれも n_units でノード数が与えられるので、同じサイズになる。
デフォルトでは1000である。
出力層は、0から9を判別するためにn_out に10がパラメータとして与えられる。

中間層の2層が同じサイズというのは、ちょっと面白くない。
それぞれサイズを変えることができれば、中間層のノード数の変化と学習の関係をより詳しく調べられる。

デフォルトのままだと 784 ==> 1000 ==> 1000 ==> 10 であるのを、 784 ==> 150 ==> 50 ==> 10 という感じの指定ができるようにしたい。

コマンドラインパーサーの説明は、先日行った。
その中間層のサイズの解析部分は以下のようになっている。

    parser.add_argument('--unit', '-u', type=int, default=1000,
help='Number of units')
これをどう変更すればよいだろうか?
-u に対して1つの数字だけ受け付けていたのを、複数(2つ)の数字を受け取るようにしないといけない。
ということで、次のように変更した。

    parser.add_argument('--units', '-u', type=int, nargs='+', default=[1000,1000],
help='Number of units')
これで、 -u の後ろに並べた数は、整数リストになり、args.units になる。
nargs=’+’ により、可変個数のリストを処理できるようだ。
一応、複数になったというとを示すため、 unit から units に変更した。

実行時の最初に、ネットワークや学習に関する情報をprintするのだが、そこは unit を units に変更しただけだ。
単なるスカラーのintか、intのリストかはPythonは勝手に判断し、良きに計らってくれる。

    print('# units: {}'.format(args.units))

ネットワークを作るところでも、同じく s をつけるだけで、リストが渡せる。
        model = L.Classifier(MLP(args.units, 10))

そして、ネットワークを実際に細かく定義する部分は以下のように変更した。
    def __init__(self, n_units, n_out):
super(MLP, self).__init__(
# the size of the inputs to each layer will be inferred
l1=L.Linear(None, n_units[0]),  # n_in -> n_units[0]
l2=L.Linear(None, n_units[1]),  # n_units[0] -> n_units[1]
l3=L.Linear(None, n_out),  	    # n_units[1] -> n_out
)

以上で、中間層のサイズをコマンドから自由に指定できるようになったはずだ。

長くなってしまったので、動くかどうかは次回に回す。