機械学習で、自分の書いた数字を認識させてみる

# はじめに
最近になり、機械学習というものを体験してみようと思い。Keras と MNIST を使って、本に載っていたサンプルプログラムを試してみました。
内容はほとんど理解できないまま、一通り実行した後で、自分で書いた数字を認識できるか試してみようと思ったのですが、その本にはそのような記述は載っていませんでした。
そこで、ネットを検索してみたのですが、だいたいどのページも train と test までで終わっています。それでもいくつか参考になるページを見つけたので、見よう見まねでプログラムを作ってみました。
なお、参考にした書籍は「Pythonで動かして学ぶ！ あたらしい機械学習の教科書 」（翔泳社）です。
試したのは、第8章 ニューラルネットワーク・ディープラーニングの応用（手書き数字の認識）の中に記載されているリスト 8-1-(7) とリスト 8-2-(7)です。一通り学習と検証を実施した後に自分で書いた数字を認識させるようにしました。
使用した主な環境は、下記のとおりです。

  - Windows10
  - Anaconda 1.8.2
  - Python 3.6.4
  - Tensorflow 1.7.0
  - Keras 2.1.5

# 具体的に
##１．手書き文字の作成
　認識させる文字は、メモ帳を使い以下のようにして作成しました。

 1) サイズ 100x100
 2) 背景を真っ黒に塗りつぶす
 3) ペンを使って白い数字を描く。
 4) img_0n.png という名前で保存。（今回は、0 ～ 9 まで10種類を作成）

 5)作成したイメージファイルを下記階層のフォルダへ保存する。
 
```
     ユーザー\
         （ログインユーザ）\
             mnist_data\
                 myself\
                     0\
                         img_00.png
                     1\
                         img_01.png
                     2\
                         img_02.png
                      ：
                     9\
                         img_09.png
```

##２．リスト 8-1-(7)

 下記コードをリストの後ろに追加して、実行すると自分で書いた数字イメージと左下にフォルダ名（カテゴリ）、右下に認識した結果の数字を表示します。もし、一致していなければイメージの上部に青い線を引きます。
 この時点では、1 ～ 5 は一致しましたが、0、6 ～ 9 は不一致でした。

<img width="669" alt="test07e.png" src="https://qiita-image-store.s3.amazonaws.com/0/245347/9546ff6f-a026-d493-e7eb-7cd9796e754b.png">


``` 
import os, sys

from PIL import Image

mypath = 'mnist_data/myself/'

def myself():
    x_input = []
    y_input = []
    z_input = []
    n = 0

    # イメージの取得
    for dir in os.listdir(mypath):
        input_path = mypath + '/' + dir

        for file in os.listdir(input_path):
            image = Image.open(input_path + '/' + file).convert('L')
            image = image.resize((28, 28), Image.ANTIALIAS)

            data = np.asarray(image, dtype = float)
            data = data.reshape(1, 784)
            data = data.astype('float32')
            data /= 255
            
            x_input.append(data)
            y_input.append(dir)
            n += 1

    # 認識
    for i in range(n):
        num = model.predict_classes(x_input[i], batch_size = 32)
        z_input.append(num[0])
        print('テストラベル、認証ラベル：' , y_input[i], z_input[i])

    # イメージ描画
    plt.figure(2, figsize = (12, 8))
    plt.gray()
    for i in range(n):
        plt.subplot(8, 12, i + 1)
        x = x_input[i]
        x = x.reshape(28, 28)

        plt.pcolor(1 - x)
        plt.text(2,  25.5, y_input[i], fontsize = 12)
        plt.text(22, 25.5, z_input[i], fontsize = 12)
        
        if (str(y_input[i]) != str(z_input[i])):
            plt.plot([0, 27], [1, 1], color = 'cornflowerblue', linewidth = 5)
        
        plt.xlim(0, 27)
        plt.ylim(27, 0)
        plt.xticks([], "")
        plt.yticks([], "")

    plt.show()

myself()
```

##３．リスト 8-2-(7)

書籍の中で、集大成と記述されているリストの後ろに追加します。
実行してみると、今度は見事にすべて一致しました。

<img width="665" alt="test26f.png" src="https://qiita-image-store.s3.amazonaws.com/0/245347/2fa09871-1eaf-7616-b723-53758f732284.png">


```
import os, sys

from PIL import Image

mypath = 'mnist_data/myself/'

def myself():
    x_input = []
    y_input = []
    z_input = []
    n = 0

    # イメージの取得
    for dir in os.listdir(mypath):
        input_path = mypath + '/' + dir

        for file in os.listdir(input_path):
            image = Image.open(input_path + '/' + file).convert('L')
            image = image.resize((28, 28), Image.ANTIALIAS)

            data = np.asarray(image, dtype = float)
            data = data.reshape(1, 28, 28, 1)
            data = data.astype('float32')
            data /= 255
            
            x_input.append(data)
            y_input.append(dir)
            n += 1

    # 認識
    for i in range(n):
        num = model.predict_classes(x_input[i], batch_size = 32)
        z_input.append(num[0])
        print('テストラベル、認証ラベル：' , y_input[i], z_input[i])

    # イメージ描画
    plt.figure(2, figsize = (12, 8))
    plt.gray()
    for i in range(n):
        plt.subplot(8, 12, i + 1)
        x = x_input[i]
        x = x.reshape(28, 28)

        plt.pcolor(1 - x)
        plt.text(2,  25.5, y_input[i], fontsize = 12)
        plt.text(22, 25.5, z_input[i], fontsize = 12)
        
        if (str(y_input[i]) != str(z_input[i])):
            plt.plot([0, 27], [1, 1], color = 'cornflowerblue', linewidth = 5)
        
        plt.xlim(0, 27)
        plt.ylim(27, 0)
        plt.xticks([], "")
        plt.yticks([], "")

    plt.show()

myself()
```

とりあえず、実行はできましたが、改善点だらけなので、改訂していくつもりです。