【TensorFlow】機械学習でポケモンずかんを現実化してみた

# はじめに
皆さん、ポケモンはお好きですか？
私にとってポケモンは、小学生の頃に発売されて以降、私の青春をともに歩いてきたと言っても過言ではないです。通信ケーブルを持っている子の家に集合したり、きんのたまおじさんに怯えたり...。

そんな中、1998年にポケモンずかんのおもちゃが発売されました。([参考:YouTube](https://www.youtube.com/watch?v=o64wHA1mdmw))
「これがあれば、サトシみたいにポケモンマスターを目指せる!!」
そう思った私は、すぐに両親にねだって誕生日プレゼントに買ってもらいました。が、すぐに絶望しました。

**「ピカチュウのぬいぐるみに向けても、ポケモンずかんにピカチュウのデータが表示されない！どうして...」**

冷静に考えたら、ポケモンを判別して図鑑に表示するおもちゃは(当時の技術では)商品化できる訳がないのですが、小学校低学年の私にとっては、それはそれはショックでした。

...

あれから20年、ふとTensorFlowを使った機械学習の取り組みをしている中、思いました。
**「機械学習して画像を判別できるのなら、ポケモンずかんを作れるのでは？」**

# できたもの
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">人工知能の力を使って、ポケモンずかんを現実に！子供の頃の夢が叶ったよ〜😭ﾔｯﾀｰ<a href="https://twitter.com/hashtag/Android?src=hash&amp;ref_src=twsrc%5Etfw">#Android</a> <a href="https://twitter.com/hashtag/TensorFlow?src=hash&amp;ref_src=twsrc%5Etfw">#TensorFlow</a> <a href="https://twitter.com/hashtag/pokemon?src=hash&amp;ref_src=twsrc%5Etfw">#pokemon</a> <a href="https://twitter.com/hashtag/ai?src=hash&amp;ref_src=twsrc%5Etfw">#ai</a> <a href="https://twitter.com/hashtag/%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD?src=hash&amp;ref_src=twsrc%5Etfw">#人工知能</a> <a href="https://t.co/Iu4ZeAQjXD">pic.twitter.com/Iu4ZeAQjXD</a></p>&mdash; ちぇだ@目指せロングヘア (@cheddar_dev) <a href="https://twitter.com/cheddar_dev/status/1044032272402243584?ref_src=twsrc%5Etfw">2018年9月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

**スクリーンショット**
<img height="500" alt="pipup" src="https://qiita-image-store.s3.amazonaws.com/0/148385/525a9655-3919-ae98-32f5-58069505e7b4.png">　<img height="500" alt="slowpoke" src="https://qiita-image-store.s3.amazonaws.com/0/148385/61d1307c-76f1-39f9-6615-c84597211689.png">
<img height="500" alt="magikarp" src="https://qiita-image-store.s3.amazonaws.com/0/148385/8767207b-b73e-e124-2b0a-1d8172b4120d.png">　<img height="500" alt="pikachu" src="https://qiita-image-store.s3.amazonaws.com/0/148385/daccba60-2846-e67e-01d5-9d8c0e819b20.png">

(全種類のポケモンの画像収集と学習は時間的に辛いので、今のところ見分けられるのは数匹です。)

# システム構成
<img width="800" alt="system" src="https://qiita-image-store.s3.amazonaws.com/0/148385/7be23b6a-71e4-e759-d050-3c10effa0fff.png">

## 1. 学習元となる画像を収集
Google画像検索と[Chrome拡張(Fatkunバッチダウンロードイメージ)](https://chrome.google.com/webstore/detail/fatkun-batch-download-ima/nnjjahlikiabnchcpehcpkdeckfgnohf)を使って、ポケモン毎に約200枚づつ画像を集めました。200枚という数字に特に意味はないです。試してはいないですが、恐らく最低でも30〜50枚は必要だと思います。

## 2. 転移学習にて学習
[TensorFlowの公式解説(How to Retrain an Image Classifier for New Categories)](https://www.tensorflow.org/hub/tutorials/image_retraining)を参考にしました。特に詰まるところもなくサクサクと進められました :ok_hand:
今回はAndroidアプリで学習結果を使用するため、Android用に変換します。詳しくは[こちら](http://nilhcem.com/android/custom-tensorflow-classifier)の`3. Optimize the model`に詳しく書かれています。

## 3. カメラ画像と学習結果を照らし合わせる
こちらに関しては[TensorFlowのAndroidサンプル](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android)に含まれている`TF Classify`を~~パクって~~参考にして作成しました。

### 3-1. 作成した学習結果へ置き換え
サンプルアプリのassetsフォルダに`2. 転移学習にて学習`にて作成した学習結果を配置します。また、コードから学習結果を呼び出している箇所があるため、指定するパスを修正します。

```Java:ClassifierActivity.java
  private static final String MODEL_FILE = "file:///android_asset/tensorflow_inception_graph.pb"; //　ここを作成した学習結果へのパスに置き換え
  private static final String LABEL_FILE =
      "file:///android_asset/imagenet_comp_graph_label_strings.txt"; // ここを作成したラベルデータへのパスに置き換え
```

### 3-2. ポケモンずかんの画像を表示
`camera_connection_fragment.xml`を修正して、ポケモンずかんの画面を作成します。ポケモンずかんのメイン画面にカメラ画像とポケモンの説明、サブ画面に類似度を表示するようにレイアウトを調整しました。
<img width="700" alt="layout" src="https://qiita-image-store.s3.amazonaws.com/0/148385/f3b4ae19-116a-02ae-d6c8-62f4345c78da.png">

余談ですが、私はペイントソフトが苦手なので、ポケモンずかんの画像はKeynoteで作成しました。
<img width="700" alt="keynote.png" src="https://qiita-image-store.s3.amazonaws.com/0/148385/e7a5208e-fa65-4f16-39a4-7a973d889886.png">

## 4. 類似度の高いポケモンの説明を表示する

収集した画像については特にトリミング等の画像編集はしなかったこともあり、学習結果にばらつきが出てしまいました。そのため、ポケモンごとに類似度のしきい値を調整しました。しきい値を超えた場合に、ポケモンずかんに説明と類似度を表示しています。

# まとめ
機械学習の分野は本当に初心者なのですが、簡単に作成することができました。
数年前までは、機械学習はかなり敷居が高いものでしたが...。まさに**「かがくのちからってすげー」**ですね!! アイデア次第で、面白いものが沢山作れそうです :smiley: 

学習結果のみですが、[Git](https://github.com/cheddar-dev/Pokedex)に配置しました。プロジェクトも時間でき次第プッシュしますね。