Colaboratory 上で Tensorflow 2 を使い、自分の手書き数字のラベルを予測する。

## 最終的なノートブック

- https://colab.research.google.com/drive/1RCAgCCtzUuMYlOjc9TDwo6z4tApC5yFN

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/98d18136-0a5b-fa4a-ecd4-0ebd96664d37.png)


## Colaboratory 上でノートブックを作る

[Colaboratory](https://colab.research.google.com/notebooks/) 上で、

- `ファイル` > `Python 3 の新しいノートブック`

から新しいノートブックを作ります。

- `編集` > `ノートブックの設定`

を選択すると次のようなポップアップが表示されるので、`ハードウェア アクセラレート` のドロップダウンメニューから `GPU` を選びましょう。

<img width="536" alt="Screen Shot 2019-12-25 at 16.49.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/de4da49f-d326-8598-8240-64c1de05c426.png">


## 手書き文字画像のラベルを予測するモデルを学習する

次のチュートリアルを実行していきます。

- [エキスパートのための TensorFlow 2.0 入門  |  TensorFlow Core](https://www.tensorflow.org/tutorials/quickstart/advanced?hl=ja)

### Tensorflow のバージョン設定

```
!pip list | grep tensorflow
```

上記を実行すると、バージョンが `1.15.0` であることがわかります。

<img width="1366" alt="Screen Shot 2019-12-25 at 16.57.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/219d9c52-e200-f47e-be18-344d36a851fa.png">

```
!pip install -U tensorflow
```

上記を実行すると次のようなエラーが出ますが、今回の範囲内では問題ありませんでした。

<img width="1360" alt="Screen Shot 2019-12-25 at 17.01.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/b3a0772d-2fcf-3559-1a16-46b685812cb4.png">

もう一度 `pip list` でバージョンを確認しておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/0e96fb3e-0226-71c6-cabd-dac167411b07.png)


### モデルを学習させる

ひたすら、[チュートリアル](https://www.tensorflow.org/tutorials/quickstart/advanced?hl=ja)のコードをコピペして、実行していきます。。。
5 epoch 回るのに、数分かかりましたが、問題なく終了しました。

### MNIST データセットの入力がどんなものか表示してみる

ノートブック上で画像を表示する方法はいくつかありますが、今回は `PIL` を使います。

```
from PIL import Image

img = Image.fromarray(x_test[0].reshape((28,28)) * 255).convert("RGB")
img
```

次のように画像が `7` の画像が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/a9762472-4ad2-f70d-bc55-52be34f7c8a0.png)


### 自分の手書き数字の画像のラベル予測してみる

鉛筆だと線が細すぎてうまくいかなかったので、マジックペンで上書きした次のような画像を用意しました。

![my_input.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/4a093012-40a8-c762-6647-cf2d22cec969.jpeg)

左のペインを開くと、 `ファイル` というタブがあるので、選択すると今のワーキングディレクトリのファイルが表示されます。
`アップロード` というボタンがあるので、そこから自分の手書き画像をアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/57de4a2d-9967-156e-7051-aa21cda6b024.png)





MNISTの入力との違いは、

- サイズが大きいこと
- 白黒画像じゃないこと
- 背景の方が明度が高いこと

なので、次のコードでMNISTの画像に合わせます。

```
from PIL import ImageOps

my_img = ImageOps.invert(Image.open("my_input.jpg").resize((28, 28)).convert("L"))
my_img
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/9ddbb564-c08d-57bd-141c-821aef77c261.png)

値を0~1に変換し、チャンネルの次元を加えて、先ほど学習したモデルに入力すると、
出力は次のようになりました。

```
import numpy as np

my_input = (np.array(my_img) / 255).reshape((28,28,1))
my_output = model([my_input]).numpy()[0]
my_output
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/85d93740-2a40-8308-202c-5000970ccd9c.png)

次のコードで何番目のラベルの確率が一番高いか確認します。

```
my_output.argmax()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32636/ff8afb09-2ce4-dec5-7594-eb2168b2360d.png)

うまく予測できていることが確認できました。