LoginSignup
19
18

More than 5 years have passed since last update.

コインをバラまいた画像から合計金額を推定するAI

Last updated at Posted at 2019-01-01

世間では、お正月が来たようです。
そこで、初詣に行ったついでに、賽銭箱の底をのぞいてみましょう!

これいくら?

scattered_overlapp_yen.jpg

こんな画像をパッと見て総額がわかれば、なにかと嬉しいのではないかと。大体でもいいので。
(たとえば神社さんの確定申告システムに直結するとか・・。)
まぁ応用はさておき、いまどきの時代なので、AIに金額を数えさせてみましょう!

しかし、コインが重なりあったりしてると難航しそうな予感。
というわけで、最初は

条件を単純化します。

scatter_sparse_yen.jpg
このように、コインどうしが重なってないなら、ちょっとハードル下げられるかな?
しかし日本の硬貨6種類(1円5円10円50円100円500円)全部を対象にしてやってみると、手元の環境の環境ではちょっとキビシいみたい。(モデルにもよるでしょうが・・)

あ、手元の環境というのは、Google Colaboratory (略称:colab) のGPU版です。
(手元・・とはいえないか?)
そこでもうちょっと単純化・・まあ実用の可能性を探るという目的で一歩づつ、いきます。はい、

1円玉と5円玉と10円玉の3種類しかない貧乏世界

のバージョンで進めていきます。
scatter_1_5_10yen_yen.jpg
人間が計算する場合でも、コインの種類が少ないほうが易しそうですよね。

ただ、解像度が高いとメモリーとかの負荷が高くなって・・上の画像の場合、300×300ドットのフルカラー画像なんですが、ちょっとやってみると、もう一声、単純化しないとツラそうで・・。
で、こんなかんじにしました。50x50ドット:scatter_50x50.jpg  に圧縮。
・・日本人なら、なんとか金額を計算できる解像度かと。
(今回の colab さんは、米国人かもしれんが(爆))

学習/評価用データの生成

で、今回この3種類の硬貨を賽銭箱に投げこんだ、という想定のシミュレーション画像を1000枚生成しました。教師データは金額(=**円)です。
#000900_0016yen_03(01_01_01_00_00_00).png=16円 #000901_0028yen_07(03_03_01_00_00_00).png=28円 #000902_0012yen_03(02_00_01_00_00_00).png=12円 #000903_0009yen_05(04_01_00_00_00_00).png=9円 #000904_0021yen_03(01_00_02_00_00_00).png =21円・・・・・

モデリング

昔、取り組んだ、keras でパターンを数える の応用で、ちょっとだけディープなモデル:
image.png
(→各数字は,次元数の参考値。50x50といってもRGB3チャンネルあったりするので、まあ目安ということで。詳細はソースリスト を参照。回帰モデルなので、キモとしては、出力層の活性化関数は softmax ではなく、linear にしています。)

をつくって学習させてみたところ・・・
各コインの枚数を数えるところまでは、けっこうな精度で出来るようになったものの、シーケンシャルモデルでは、意外と算数(合計=各コインの額面と枚数の関和の計算)が苦手なようなのです。。まあ計算量をつぎ込んだりすれば出来るかもしれませんが。

そこで、「各コインの枚数を数えるシーケンシャルモデル」を3本用意して、合計は「電子計算機」が担当する、という複合モデルにしました。
いわば、ニューラルネットワークと電子計算機のハイブリッドモデルですな。
image.png

なにをいってるんだか・・と言われるかもしれませんが、20世紀後半に急激に発展した「人間が電子計算機を使う」モデルにおいて、「人間」の部分をAIに置き換える、という発想です。

予測/評価

で、1000枚の生成画像のうち、900枚を学習用(各コイン500エポック)、残り100枚を評価用とした場合、評価用画像の予測値がこんな感じになりました。

入力画像 正解値 予測値
(=今回のモデル
 が認識した
推定値)
誤差率
#000900_0016yen_03(01_01_01_00_00_00).png 16 円 16.41 円 2.55 %
#000901_0028yen_07(03_03_01_00_00_00).png 28 円 21.16 円 -24.44 %
(※)
#000902_0012yen_03(02_00_01_00_00_00).png 12 円 11.70 円 -2.51 %
#000903_0009yen_05(04_01_00_00_00_00).png 9 円 9.13 円 1.44 %
#000904_0021yen_03(01_00_02_00_00_00).png 21 円 21.55 円 2.64 %

(以下略)

上から2枚目のやつ(※)なんかは、誤差が24.44% とデカいですが、これは学習用データの数を増やすことによって解消に向かうようです。
誤差の原因としては、後述しますが、5円玉に対する認識がわりと苦手のようです。

対して、学習の繰り返し=エポック数を増やすだけでは、未知の画像に対する精度は、それほど高まらないようです。

予測データの視覚化

1円玉の個数推定のバラツキ

 横軸:各画像に含まれる真のコインの個数、
 縦軸:各画像から推定されたコインの個数
 x=y の直線に近いものほど精度が高い推定といえる。以下同様。
1yen_count.png
(2019/01/27 データ訂正)

5円玉の個数推定のバラツキ

 ・・・5円玉に対しては、他と比べて精度が出にくい。
 さらにサンプル数を増やすことで精度が向上する見込み。
5yen_count.png

10円玉の個数推定のバラツキ

まぁまぁの精度か。
10yen_count.png

トータル金額推定のバラツキ

 横軸:真の金額
 縦軸:画像から推定された各コインの個数から電子計算機で求めた金額

サンプル画像数:1000枚 の場合 ↓
value_prediction.png
 さらにサンプル数を増やすことで精度が向上する。つまり分布が x=y の直線に近づく。

サンプル画像数:3000枚 の場合 ↓ (検証用データは上記と同一)
value_prediction3000samplesx500ep.png

結論

以上、今回は実用レベルには達してないものの、画像認識による計数という分野でポテンシャルを感じられる結果となったと思います。

今後の課題

・コインの種類を拡大(・・50円、100円、500円)
・重なり合ったコインの対応
・実写画像への対応、背景などのノイズ耐性向上
・賽銭箱への実装~神社への売り込み
など、考えられないこともないですけど・・・・・・・・・・・・・。

ソースリスト

「打ち出の小槌」サービス(デモ)

(2019/01/27 追加)
本件で用いたデータ生成機能をサービス化してみたものです。
https://qiita.com/uminor/items/d9a3123ce782451bea74

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18