【MNIST】手書き数字をAIに認識させよう【webアプリの開発】

# 1. はじめに
`mnisterツール`を作成しました。このツールで自分の手書き数字をAIに認識させることができます。

> 「ツール作るのメンドクセ」という方はこちらからすぐに遊べます。
> <font color="DeepPink"><strong>HEROKUへデプロイしました。すぐに遊べます😊！</strong></font>
> → https://mnister-web.herokuapp.com/
> ※HEROKU無料枠のため、サーバがSLEEPしている場合、初回起動のみ45秒程度時間がかかります。
> こちらのモデルは[汎化性能をUP](https://qiita.com/PoodleMaster/items/54c184d9f2f70cc011d0)させた高認識版を使用しております。

![mnister sample localhost](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/1b39532a-e5f7-1106-8c10-9d8b10a54d3d.gif)

※モデルは『[`0からはじめる「Python AIプログラミング」 for Google Colab`](https://qiita.com/PoodleMaster/items/f6b7205c4c20948e9c0d)』で作った認識精度99%のモデルを利用しています。

# 2. なぜ`mnisterツール`を作ったのか
`MNIST`を利用した数字認識モデルを作って「**認識精度が99%**だった、スゲー！」
<img width=812 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/3a21fb49-2791-4fda-886d-93721763fe8b.png">
「………………ん😒？………………でっ！？」ってなりますよね？<BR>`AI`って何ぞやから始まって色々とモデルを作るために様々な`知恵熱`を絞り出して作りだした`俺のMNISTモデル`。そのやっとこ出来上がったモデルを「**他人が用意したテストデータで、認識精度を確認して終わり！**」とするのは、どうも納得できませんでした。

# 3. `mnisterツール`で遊ぼう
ということで、精魂込めて自分で作りあげた`俺のMNISTモデル`の効果を簡単に確認できるツールを作ってみました。**自分の手書き文字が正しく認識されるか、意地悪に書いても正しく認識できるのか、なぜ認識されないのか、どうすれば認識するようになるのか**、など色々考えて遊びましょう。

## (1) 環境構築
`mnisterツール`をGithubに公開しており、環境構築手順などはこちらの`README.md`に記載していますので、こちらを参照してください。なお、`Google Colab`でも、`Local PC`でも、どちらでも遊ぶことができますが、**`Google Colab`の方が超簡単なのでオススメ**です。

``` cmd:mnisterダウンロード
git clone https://github.com/PoodleMaster/mnister
```

``` cmd:mnisterリスト
mnister
    │
    ├─Extra
    │     │
    │     ├─colab_mnist.hdf5           ← ImageDataGeneratorを使用した高汎化版モデル
    │     └─ImageDataGenerator.ipynb   ← モデルの作り方はこちら
    │
    ├─static
    │     │
    │     ├─favicon.ico
    │     ├─GitHub-Mark-32px.png
    │     ├─Input.js
    │     └─mnister-Mark-28px.png
    │
    ├─templates
    │     │
    │     └─index.html
    │
    ├─colab_mnist.hdf5                 ← サーバが読み込むモデル(普通に学習した低汎化版モデル)
    ├─LICENSE
    ├─README.md
    └─server.py                        ← サーバはこちらを起動
```

``` cmd:mnister起動
python server.py
```

## (2) ソースコード
> <img width=64 src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/3a342531-d030-6a66-678e-45f328de072f.png'><img width=120 src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/7e2c1f12-f920-922c-81f2-312da1406ad0.png'>
> Github : https://github.com/PoodleMaster/mnister
> 
> ・[Google Colabで遊ぶ方への説明](https://github.com/PoodleMaster/mnister/blob/master/README.md#when-running-on-google-colab)　([【参考】mnister.ipynb](https://github.com/PoodleMaster/mnister/blob/master/mnister.ipynb))
> ・[Local PCで遊ぶ方への説明](https://github.com/PoodleMaster/mnister/blob/master/README.md#when-running-on-local-pc)

※Google Colabの使用方法が良く分からない方は、[こちらの記事](https://qiita.com/PoodleMaster/items/f6b7205c4c20948e9c0d)を参考にしてください。

## (3) 遊ぼう
webブラウザの黒いキャンバスのところにマウスで0～9の数字を書いたら、「`Predict`」をクリックしてください。結果が表示されます。

![mnister sample ngrok](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/de3ecb61-9e78-3c17-f858-a6ede70cb119.gif)

## (4) 意外と認識できない
**MNISTの認識精度99%モデル**を使用しているので、ちょっとくらい意地悪してみても問題ないかなと思ったら、普通に書いたり、少し回転させたりしても**認識できないものが結構ある**ことが分かりました。このままでは、一般並みに実用化するにはもっと色々と工夫が必要ですね。

→結局、**MNISTのテストデータを使った認識精度が99%だったということに過ぎない**ので、もっと様々なバリエーションの数字に対応させる(汎化させる)必要があることが分かりました。

![誤認識1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/25390721-d7e2-05d1-014e-5ecf854f7b89.png) ![誤認識2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/1e0d8a55-bbb5-1d75-36a6-6b6fa9c5150a.png)

# 4. オレのMNISTモデル
ここまででも十分かもしれませんが、他人が作ったMNISTモデルで認識させてもイマイチ楽しくないかもしれません。自分で`オレのMNISTモデル`を作ってみてください。
![create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/ba14646a-e023-d753-dcdb-4ab4f9a2dd90.png)

`オレのMNISTモデル`を作るのメンドクセという方に、**スペシャルサービス**として出来上がった高汎化版のモデルも用意しております。「`低汎化版モデル：mnister/colab_mnist.hdf5`」を「`高汎化版モデル：mnister/Extra/colab_mnist.hdf5`」に置き換えて実行してみてください。こちらは、[ImageDataGenerator](https://qiita.com/PoodleMaster/items/54c184d9f2f70cc011d0)を利用して汎化性能を向上させたモデルとなっております。**置き換えて認識率の違いを楽しんでみてください❤**

# 5. 使用した技術など
ブラウザで文字入力させたものをAI認識させる様にできないかなぁと思ったら、AI処理部(Python)だけでも大変だったのに、flask、javascript、jQuery(Ajax)、json、base64、Createjs、html、公開プログラム格納のためのGithub………、などなど、色々と幅広い基礎知識が必要となってしまいとても結構大変でした。でも、おかげさまで幅広く勉強することができて良かったと思っています😊
![仕組み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/062b9ac0-115d-3253-dcb4-fe5068a8f471.png)

## ■サーバ機能 (server.py)
|技術|説明|
|:-:|:--|
|Flask<BR>Flask-ngrok(Google Colab)|webサーバ起動とバックエンドでpython(AI)を使用したいため|
|Tensorflow|推定処理(AI)のため|

## ■クライアント機能 (Input.js、index.html)
|技術|説明|
|:-:|:--|
|Createjs|文字入力インタフェースのため|
|jQuery(Ajax)|サーバ側との非同期通信のため|


# 6. 以上
もしこの記事が、あなたに貢献することができたなら、ぜひLGTM、またはストックをお願い致します😉

お疲れ様でした！