FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

ChainerでシンプルなNeural Networkを作る勉強(テストセットの検算)

前回、シンプルなMNISTのネットワークを作成したが、本当にこれで正解が出せているんだろうか? 実際にニューラルネットワークの出力結果を見て、チェックしてみたい。

ニューラルネットワークの出力結果と、テストセットの回答を比較する

ニューラルネットワークへの入力は、テストセット中の入力値を取り出し、入力ノードへ挿入、そして出力ノードを取得して、誤差を算出していた。

for i in six.moves.range(0, N_test, batchsize):
    x_batch = x_test[i:i + batchsize]
    y_batch = y_test[i:i + batchsize]

    y = model._forward(x_batch)

ここで、x_batchは入力値の配列、つまり28x28の浮動小数点のデータセット、そしてyはそのデータがどの数値に割り当てられるかを示している。

たとえば、こんなのだ。

[7 4 6 0 1 1 1 0 4 4 7 6 3 0 0 4 3 0 6 1 9 6 1 3 8 1 2 5 6 2 7 3 6 0 1 9 7
 6 6 8 9 2 9 5 8 3 1 0 0 7 6 6 2 1 6 9 3 1 8 6 9 0 6 0 0 0 6 3 5 9 3 4 5 5
 8 5 3 0 4 0 2 9 6 8 2 3 1 2 1 1 5 6 9 8 0 6 6 5 5 3]

それぞれのデータセットに対して、どの数値であるかを示した解答になる。

これだけでは比較しにくいので、これを単位ベクトル(というよりも、当該インデックスの部分だけ1.0になる配列)に変換する。

    y_array = np.zeros((len(y_batch), 10), dtype=np.float32)
    for j in six.moves.range(0, y_batch.size):
        y_array[j][y_batch[j]]=1.0

こんな感じに変換される。

 [ 0.  1.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  1.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]
 [ 0.  1.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  1.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]
 [ 0.  0.  0.  1.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  1.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]
 [ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.  0.  0.  0.  0.  0.]
 [ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  1.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  1.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  1.  0.  0.]]

これらに対してmean_squared_errorを計算し、誤差とするというわけだ。

実際には、ニューラルネットワークの解答と模範解答はどのようになっているのだろう。 並べて出力してみた。

    for j in six.moves.range(0, y_batch.size):
        for k in six.moves.range(0, 9):
            sys.stdout.write ("%6.2f " % y.data[j][k])
        print ("")
        for k in six.moves.range(0, 9):
            sys.stdout.write ("%6.2f " % y_array[j][k])
        print ("")

以下が出力結果だ。

  0.44  -4.27  -0.45   3.53  -1.60   8.68  -5.54  -2.44   3.45   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00   0.00   # 模範解答
 -0.13  -5.28   3.96  -3.01  -0.70   1.34  11.88  -9.02   2.18   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00   # 模範解答
 -4.42  -4.03   1.32   2.68  -2.91  -2.16  -6.93  10.24   1.22   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   0.00   0.00   1.00   0.00   # 模範解答
  0.43  -5.09   2.09   6.89  -5.47   3.91  -7.45  -3.74   8.98   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   1.00   # 模範解答
  0.30  -9.02  -3.99  -2.19   6.19  -2.12   0.06   1.68   1.44   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   # 模範解答
 11.41  -8.38  -1.84   0.28  -6.18   7.81   0.96  -7.60   5.74   # ニューラルネットワークの出力
  1.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   # 模範解答
 -6.01   8.12   3.10   0.82  -5.00  -1.51   0.43  -1.96   2.63   # ニューラルネットワークの出力
  0.00   1.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   # 模範解答
 -3.29  -3.35  11.90   5.64  -7.12  -1.42  -1.35  -1.77   3.82   # ニューラルネットワークの出力
  0.00   0.00   1.00   0.00   0.00   0.00   0.00   0.00   0.00   # 模範解答
 -0.00  -4.13   4.15  11.41 -10.48   2.46  -4.78   2.21   0.40   # ニューラルネットワークの出力
  0.00   0.00   0.00   1.00   0.00   0.00   0.00   0.00   0.00   # 模範解答
 -6.62  -5.67  -2.40  -1.92   7.58   1.53  -1.18   1.71   2.86   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   1.00   0.00   0.00   0.00   0.00   # 模範解答
 -1.53  -1.00  -1.88  -0.54   0.27   5.76   0.43  -3.32   4.31   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00   0.00   # 模範解答
  3.28  -8.44   4.75  -4.24  -0.21   1.62  12.40  -6.84  -0.52   # ニューラルネットワークの出力
  0.00   0.00   0.00   0.00   0.00   0.00   1.00   0.00   0.00   # 模範解答

偶数行がニューラルネットワークの解答、奇数行が模範解答となっており、おおよそニューラルネットワークの出力した最大値の場所が、1.0となっており、模範解答と一致していることが分かる。

今度は、このネットワークを別の問題にも応用していこう。