Yoloを使って欠点豆検出アプリを作ったお話(iOS)

他のカレンダーが埋まってしまったので、
[物体検出 / 画像識別アプリ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/object-detection) として参加します。

##はじめに
コーヒー好きの文系大学生です。
機械学習の勉強も兼ねて欠点豆検出アプリを作ったのでそれを記事にしました。
とりあえずこの記事では自分が作った成果物について書いています。


##そもそも欠点豆とは？
虫食い、病気、未熟、欠けてしまっているコーヒー豆のことです。(※他にも種類はあります)

コーヒー好きな方はご存知だと思いますが、欠点豆は焙煎前後に混入しており、機械選別やハンドピッキングを行いこれを取り除いています。

欠点豆が混入したコーヒーは美味しくないので、多くの店では美味しいコーヒーのために欠点豆を必死で取り除いています。


##なぜ作ったか？
・精度の高い機械選別機は正直高い & サイズが大きい。(安いやつでも200~300万円程)
・機械選別しても結局最後はハンドピッキングを行います。

以上の2点から、安く、精度の高い欠点豆検出器が作れないかと考え取り組みました。

自分はハードのことはわからないので、ソフトウェアとして作成しオープンソースにすることで、ハードが作れる方や今後に役立てないかと。

また、ハンドピッキング初心者の方が使うにはいいかもしれません！


##なぜYOLO?
実はYOLOを導入する前に、Opencvでコーヒー豆カスケードを作っていました。
つまり、Opencvをオリジナルデータで検出できるようにしました。
200枚程度でテストしたところ、これだと多種類ある欠点豆に対応できなくね？
ということに気付き、やっぱSSD or YOLOかということになりました。

YOLOを選んだ主な理由は、**速さ**です！
やはり現場で使用してもらうことを考えると、人間より遅い検出器は正直使えません。
そのため、精度はやや落ちるものの検出スピードが速いTiny-YOLOを選びました！

また、Tiny-YOLOがCoreML変換でアプリとして使用可能なことも理由の一つです。

↓こちらopencvでテストした結果
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">リアルタイムでのコーヒー豆検出に成功しました〜 <a href="https://t.co/3wYLOy6mGE">pic.twitter.com/3wYLOy6mGE</a></p>&mdash; Mr.Beans(ミスタービーンズ) (@91beans) <a href="https://twitter.com/91beans/status/1169921322589151233?ref_src=twsrc%5Etfw">September 6, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##やりたいこと
**完全に君は欠点豆だね!!**という欠点豆をちゃんと検出できるようにする。

理由: まずは分かりやすい豆から検出可能にしていく & 微妙な欠点豆はお店によって判断が変わるからです。　
![うう.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409586/a69657f9-c7bb-181d-4713-aaab8015d7b3.jpeg)
視覚化させるとこんな感じです。

##欠点豆の収集方法
収集方法は主に3つあります。
1.自分でコーヒー豆を購入して欠点豆を収集する　(→生豆ならできそうだが、焙煎豆はほぼ無理)
2.直接焙煎もしているコーヒー店さん or 企業さんにお願いする
3.SNSで募集する

自分は2,3の方法を使って収集しました。
**3.SNSでは多くの個人店さん**から、**2某コーヒー企業さん**から大量に欠点豆をいただきました。

**皆さんお忙しいはずなのに、親身に接していただき本当に感謝しております🙇‍♂️**
(とても嬉しかったですし、
焙煎方法についてもかなり詳しく教えていただき頭あがらないです。)
##ざっくりした作り方
詳しい作り方は後々記事にするとして、ざっくりした作り方を明記します。

1. Yoloの環境構築を行う
2. 画像を収集(自分は写真を撮りました)
3. アノテーションを行う(labelImg もしくは VOTT )
4. Tiny-YOLO の cfgファイルを変更し学習させる (※yolov2-tiny)
5. 学習後 YAD2K を使用し .h5 変換する
6.  .h5 → CoreML変換する
7. xcodeにCoreMLをポイする
8. swift用にコードを書き換える
9. お好みで機能を追加する

##パラメーター
いろいろ試しましたが、なんらかんら初期設定の **batch: 64** が一番上手く収束し精度もよかった。

batch: 128以上で試したところ、GPUを使用しているのに終わる気配がなく精度もあまり変化しませんでした。ここはやりたいものによって変わると思うので、いろいろ試すことをおすすめします。

train : test の比率ですが、9 : 1, 8 : 2, 7 : 3で試したところ
**7 : 3**が一番 Lossが収束していました。
(9 : 1 は Loss が上手く収束しませんでした。)

max_batch ですが、 **class数 *2000** にすると良いらしい。(darknet本家に記述有)
個人的には画像枚数分の回数で良いような気もします。(1万枚なら、1万回程)
実際画像枚数が200枚の際、300回以上になると過学習に陥りました。

##個人的に感じたポイント
- 学習回数が 2000~3000回超えると、まともな精度が出た印象。
- 学習画像は少なくとも1000枚は欲しい。(200枚程だとすぐに過学習に陥りました)
- 欠点豆は検出が難しいので、判別が微妙な欠点豆は今回利用しませんでした。(人間でも人によって判別変わるライン)
- Lossが0.1, mAPが80%超えると良いよう。(自分のデータはLoss: 0.2程)


##作ったもの
リアルタイムでカメラ映像から欠点豆を検出できるアプリです。

オリジナルデータの weight,cfg → .h5変換し、さらにCoreML変換することでiPhoneアプリで使用できるようにしました！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Good と Bad の詳細はこちらです。<a href="https://t.co/xgwaxLmqn9">https://t.co/xgwaxLmqn9</a> <a href="https://t.co/NMBIA0TryR">https://t.co/NMBIA0TryR</a></p>&mdash; Mr.Beans(ミスタービーンズ) (@91beans) <a href="https://twitter.com/91beans/status/1198556070420942848?ref_src=twsrc%5Etfw">November 24, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
**↑ Good と Bad 一覧**


<img width="375" alt="IMG_8452.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409586/9f6d87af-8ced-f8c3-8bc3-cffd5b3483dd.png">
↑：明らかな欠点豆はちゃんと識別されています。良い豆も白くGoodで表示されています。

良い豆に関しては、　GoodになったりBadになったり判断に迷っているようでした。
**→ 画像を増強して精度を上げます。**


##大変な作業
機械学習は前処理が**9割**だとよく言われますが(7割説もあるらしい)、本当にそうだと今回身に染みました。

**1万枚**の画像データをアノーテーションしましたが、１日フル作業しているのに **1週間程**かかりました。(泣きそうでした...)



また、今回はYoloの既存モデルを利用したので自分でオリジナルモデルにカスタマイズしませんでした。(CoreML変換したかったので改変すると少し面倒)

なのでチューニング可能なパラメータ等をいじりました。

##今後の展望
もう **1万枚** 画像を増強し、精度を上げます。
特に良い豆(Good)の判断に迷いがあるようなので、Goodを少し多めに。

また無料アプリとしてリリースしたいと思っています。**(大赤字です泣)**
そのため当初の予定通りオープンソースとして公開します。

この記事が未来のコーヒーに少しでも役に立てば幸いです。

##ちなみに...
お気づきの方もいると思いますが、
これを応用すれば、**リアルタイムのスカウターアプリ**や
**動物園、水族館でも楽しめるアプリ**が制作できます。
※既にSNOWとかも...

今回初めてオリジナルアプリを作りましたが、作ってて楽しかったです!
半年前にこれが作れるとは思っていなかったので、半年前の自分に自慢したいと思います。

YOLOは現在商用フリーなので心配な方はこちらを見ると良いかと。
[darknet LICENSE](https://github.com/pjreddie/darknet/blob/master/LICENSE)


##参考記事様
YOLO本家
[darknet](https://pjreddie.com/darknet/)
[darknet LICENSE](https://github.com/pjreddie/darknet/blob/master/LICENSE)

またiOS版として参考にした記事
[YOLO-CoreML-MPSNNGraph](https://github.com/hollance/YOLO-CoreML-MPSNNGraph)
こちらライセンス(商用可能ですがよく読んでください)
[YOLO-CoreML-MPSNNGraphのLICENCE](https://github.com/hollance/YOLO-CoreML-MPSNNGraph/blob/master/LICENSE.txt)



[]()