TensorFlow.jsでお絵かき大喜利

#ご挨拶
年の瀬ですね。
はじめまして、@doushiman_jp と申します。

僕は今年の４月にPHONE APPLIにJOINしたんですが、環境の変化やらコロナやらでほとんど春夏秋の記憶がないままに、年末の崖っぷちに立っています。
こうやってまた一つ歳をとっていくかと思うと、**とても恐ろしい**ですね。

もういくつ寝るとお正月、という事で僕の年末年始のお楽しみは、お酒を飲みながらバラエティ番組をだらだら見ることなんですが、よく絵心のない芸人さんがお題に沿った絵を書いてその出来栄えを競うみたいなコーナーがありますよね。

僕も絵心をお母さんのお腹の中に置いてきた口で、そんな絵心無い芸人さんたちに親近感を感じて「がんばれ・・・！」ってつい応援しちゃうんですけど、そんな定番のコーナーを機械学習で再現してみます。

# フロー

![図1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/ee9fa359-7e51-e5af-6946-83f919955cfd.jpeg)

全てJavaScriptで作ります。
肝心の採点部分ですが、採点の揺らぎや忖度を排除するために[TensorFlow.js](https://www.tensorflow.org/js?hl=ja)を使って機械的に行います。（この記事唯一のテック系な部分）

※Mac+Chromeでのみ動作確認しています

#TensorFlow.js
TensorFlow.jsはJavaScriptで動作する機械学習ライブラリです。
JavaScriptなのでフロントエンドのみで完結しますし、公式が学習済みモデルを公開してくれているので、ゴリゴリに学習させて認識精度をガリガリ上げて〜っていうよりは手軽に機械学習に触れることができるライブラリです。

撮影した画像が何者であるかは公式で公開されている [coco-ssd](https://www.tensorflow.org/js/models?hl=ja)という学習済みモデルを使用して、画像内のオブジェクトを判定してみます。

# つくったもの
まずはちゃんと画像認識ができるのか、写真で試してみました。
写真は我が家の愛犬です。かわいいですね。

![スクリーンショット 2020-12-07 16.56.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/dbb055ce-fb35-1b96-a522-6b88365ea135.png)



「お題！！」ボタンを押すと **「お題は＊＊＊です」** 、とランダムでお題を提出してくれます（coco-ssdの物体検知モデルは80種類くらいのオブジェクトの認識ができるので、その中からチョイスしています）

カメラの前に絵（写真）を置いて「判定！！」ボタンを押すと、画像を撮影し、TensorFlowがオブジェクト認識を行い、それが何であるかを**「これは＊＊＊ですね！」**と教えてくれます。

SCOREはTensorFlowがどれだけ一致していると判断したか、ですかね？あまり低いと判定不能になります。
判定不能な場合、アプリケーション的には**「すいません、わかりません！」**と表示するようにしています。

ちなみに、TensorFlow側が
> **これは「dog」ですね！**

と某監督のような言い回しで回答しているのが**若干鼻につきます**が、TensorFlow.jsからのレスポンスをそのまま表示しているためですのでその点ご了承ください。

プログラム的にはまず、TensorFlow.jsとcoco-ssdを読み込ませます。

```
cocoSsd.load()
```

環境によってはここで数秒程度読み込み待ちが発生します。
一度読み込んでしまえばあとはサクサクです。

「判定！！」ボタンを押すとカメラから撮影した画像をcanvasにセットして判定を行います。
実際の判定はこんな感じです。


```
cocoModel.detect(canvasElement)
```

判定に成功すると、解析結果と共にコールバックが呼ばれるので、その中で処理をおこいます。

ちなみに結果はJSONでこんな感じで帰ってきます。

```
[{
 bbox:[0,0,200,300],
 class:"dog",
 score:0,9231.....
}]
```


では、お絵かきして、実際に判定してみます。

# 計測
冒頭でも言いましたが、僕はとにかく絵心がないのです。
なので、絵そのもののクオリティの低さには目を瞑っていただけると幸いです。

まずは肩慣らしに簡単なお題からいってみましょう。

##お題：時計
![スクリーンショット 2020-12-07 17.12.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/4f86c281-f642-6a67-693b-2c08768305d4.png)


**「CLOCK」認定いただきました〜（ホッ）**

若干SCOREが低いことが気になりますが、TensorFlowも僕の書いた絵は時計である、と太鼓判を押してくれたことになりますね。
もしかして一個も認識されないのでは？と思っていたので、ホッとしました。

では、難易度をあげて次のお題にいきましょう。

## お題：犬

難易度上がりすぎ。生物はやばい。
僕が書いた絵はこちら。

![IMG_1714.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/451ad7e3-9bd3-6180-0cee-4d4ebf035553.jpeg)

僕としてはうまく描けた方じゃないかな？ つぶらな瞳も可愛いワンチャン。
横顔なのもオシャンですね。
では判定の結果は！！

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/bc5aed04-ca28-46dc-81fb-562df253e16c.png)

**謝られちゃった！！！**

何度か読み込ませてみても、ついにこの絵が犬と判定されることはありませんでした（泣）

この後は

## にんじん
![IMG_1717.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/2c805807-283e-b1f9-802e-26bf42d0e005.jpeg)

##バナナ
![IMG_1716.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/f5084742-3fd0-d0fa-bbbc-72654d4439cb.jpeg)

##傘
![IMG_1715.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911700/c44f4ea8-1e86-bd6c-228a-eb7ce1ba9c0d.jpeg)

を判定させてみたものの、TensorFlow.jsは僕に **「すいません！わかりません！」** と謝罪をするばかりで、なんだかこちらが申し訳ないような、謝りたいような気持ちでいっぱいのまま、実験は終了したのでした。


# まとめ

このままだとTensorFlow.jsの**認識精度に問題**があるのでは？となってしまいそうですが、写真を読み込ませて実験したところでは優れた認識精度を示してくれていたので、この結果はただただ単純に、**僕の画力の問題**である、とここに補足させていただきます（そりゃそうだ）
学習モデルとしても実際の写真を教師データに使っているでしょうから、写実的な絵であればあるほど認識精度は上がるかと思います。（**僕の絵を大量に学習**させればワンチャンありますが**めちゃくちゃ不毛な作業**になるのでやりませんw）

このご時世、年末年始もなかなか集まる機会もないかもしれませんが、リモート飲みで年越し、なんて際はTensorFlow.jsを使ってお絵かき大喜利で初笑い、なんていかがでしょうか。
ではでは。