Teachable Machineで飼い猫を判定する

## はじめに
お手軽に機械学習が出来るサービスを知ったので遊んでみた。

## Teachable Machineとは
Teacheableっていうくらいだから教師あり学習のことね。よく知らんけど
判定したい内容の数だけ画像で種類を覚えこませて、結果が利用できる。Webブラウザ上からお手軽に

## やってみること
純血種（ロシアンブルー）を飼っているので、「飼い猫」か「他のロシアンブルー」かを判定させてみよう。
ロシアンブルー100匹と紛れてしまったときに役立つかもしれない。そんなわけないけど、おもしろそう

## サンプルデータの用意
学習に必要なサンプル画像を用意する。当たり前だけど多い方が精度はよくなる。
飼い猫の画像は500枚用意した。500枚くらい余裕だぜ

<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/49b09898-4eb4-6943-9e72-e6587952d4c4.png">

他のロシアンブルーの画像は学習用に外国のサイトがあったので利用させてもらった。

https://www.robots.ox.ac.uk/~vgg/data/pets/

torrent経由で200枚のロシアンブルーの画像をダウンロードして使わせてもらう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/11fba0e9-6c5d-01b5-4979-5ad4c2a237fe.png)

## Teachable Machineの利用
https://teachablemachine.withgoogle.com にアクセスし、画像プロジェクトを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/421911f4-6bd4-48a5-242a-34e0183e1157.png)

標準の画像モデルを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/34769a7b-b872-89f1-1a0f-f09ef82a0b1a.png)

クラスの画面が表示されるので、判定したい種類毎に名前を変えておく。ここではMy catとOther Russian Buleにする。その後アップロードをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/ac6cbc38-2168-97ae-76db-0aacf3409d2f.png)


アップロード画面が表示されるので、用意したサンプル画像をドラッグ＆ドロップする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/0ed51e47-ed1c-9ab2-2094-ed43a5395ee5.png)

クラス数分アップロードしたら、「モデルをトレーニングする」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/fdcd15ff-8350-3670-c15a-950e574871e6.png)

少し待つと学習が終わるので、「モデルをエクスポートする」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/e9085da6-402f-c77b-81d0-34a2bb7ebf32.png)

pythonを使いたいので、Tensorflowタブを選択してから、モデルをダウンロードをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/1c8496a5-e021-43da-6f88-ede81326e010.png)

数分待つと converted_keras.zip がダウンロードされる。

## ダウンロードしたファイル
解凍するとkeras_model.h5 と labels.txt が手に入る。前者はバイナリファイル、後者はテキストファイルで中身はインデックスとクラス名
``` labels.txt
0 My cat
1 Other Russian Blue
```


## pythonのプログラム
モデルダウンロード時の画面にサンプルがあるので、ちょっとだけ修正する。
引数に画像ファイルを指定するようにした


```python:cat.py
from keras.models import load_model  # TensorFlow is required for Keras to work
from PIL import Image, ImageOps  # Install pillow instead of PIL
import numpy as np

def judge(file_path):

    # Disable scientific notation for clarity
    np.set_printoptions(suppress=True)

    # Load the model
    model = load_model("keras_Model.h5", compile=False)

    # Load the labels
    class_names = open("labels.txt", "r", encoding='utf-8').readlines()

    # Create the array of the right shape to feed into the keras model
    # The 'length' or number of images you can put into the array is
    # determined by the first position in the shape tuple, in this case 1
    data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)

    # Replace this with the path to your image
    image = Image.open(file_path).convert("RGB")

    # resizing the image to be at least 224x224 and then cropping from the center
    size = (224, 224)
    image = ImageOps.fit(image, size, Image.Resampling.LANCZOS)

    # turn the image into a numpy array
    image_array = np.asarray(image)

    # Normalize the image
    normalized_image_array = (image_array.astype(np.float32) / 127.5) - 1

    # Load the image into the array
    data[0] = normalized_image_array

    # Predicts the model
    prediction = model.predict(data)
    index = np.argmax(prediction)
    class_name = class_names[index]
    confidence_score = prediction[0][index]

    # Print prediction and confidence score
    print("Class:", class_name[2:], end="")
    print("Confidence Score:", confidence_score)

    return class_name[2:].strip('\n'), confidence_score


# メイン関数
def main():

    file_name = 'aaa.jpg'
    class_name, score = judge(file_name)
    print(file_name + 'のファイルは' + f'{score * 100:0.3f}' + '％の確率で' + class_name + 'です！')


if __name__ == "__main__":
    main()
```

## 実行してみる
プログラムと同じディレクトリに、解凍した２ファイルと判定したい画像(aaa.jpg)を置いて実行すると、ちゃんと判定できた。ちょっと確率低いけど(笑)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/38f3f85b-eb27-2db8-a385-93143753812c.png)



## おわりに
My cat と Other Russian Blue が判別できるかで遊んでみた。
ただ判定が難しい内容で学習させちゃった気はする。普通に間違えることもあったし。
手の形がグー、チョキ、パー、のどれか？とか、家電の電源がONかどうか、とかそういう用途でまた今度遊んでみようかな