ディープラーニングで画像から佐野ラーメンか喜多方ラーメンかを自動判定するWebサービスを作った。

# この記事について
- 僕は栃木県佐野市の出身なのですが、言わずもがな[佐野ラーメン](https://www.google.co.jp/search?q=%E4%BD%90%E9%87%8E%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%B3&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiUwquQkpjbAhWCy7wKHfa2DrEQ_AUICygC&biw=1920&bih=1080&dpr=2)がとても好きです。
- また、同じくらい[喜多方ラーメン](https://www.google.co.jp/search?biw=1920&bih=1080&tbm=isch&sa=1&ei=2m4DW_npBMWX8gWQ9qvwBA&q=%E5%96%9C%E5%A4%9A%E6%96%B9%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%B3&oq=%E5%96%9C%E5%A4%9A%E6%96%B9%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%B3)も好きなのですが、両者とも見た目がとても似ているなと常々思っており、ディープラーニングで両者のラーメンの画像を学習させたら、どれくらいの精度で正しく自動判定できるか試してみたいなと思いました。
- そこで、CNNのモデルの1つであるVGG16をImageNetで学習させたものをFine Tuningするのが近道と判断し、Twitter APIやBing APIから両者のラーメンの画像を収集し、それぞれ500枚の画像を用いて、学習をさせたところ、Epochによってブレはありますが、正答率は平均80%程度になりました。
- 80%の正答率が良いかどうか判断に迷うところですが、店によって様々なラーメンの見た目があり、人間でも判別が難しい写真がある中で、そこそこ頑張って学習してくれたのかなと思っています。
- せっかく学習させたので、これはもしや、見た目だけだは佐野ラーメンと喜多方ラーメンの違いが分からず、日々思い悩む人の役に立つかもしれないと思い、Webサービスとして公開することにしました。
- また、あわせて、このサービスの作成工程も簡単ですが、記載したいと思います。

# 佐野ラーメン・喜多方ラーメン自動判定サービスのURL

- 以下のURLからアクセスできます。 
- https://sano-ramen-app-092832js2a.herokuapp.com/
- 画像をアップロードすると、佐野ラーメン80%、喜多方ラーメン20%と言ったように、佐野ラーメンと喜多方ラーメンのどちらに近いかを、それぞれの割合で出してくれます。
- herokuの無料プランで作っているので場合によっては、少し起動に時間がかかります。

# 使い方

- クリックして画像を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/64437/7d1fbc05-6404-fafd-3059-14e762e172ca.png)

- 判定対象の画像が表示されるので、判定する、ボタンを押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/64437/018dc01c-1585-6ccf-6564-b10b334f111f.png)

- 佐野ラーメンと喜多方ラーメンの、どちらに近いかを割合で出してくれます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/64437/7b66f9fc-b17f-b2d9-b5a1-76baaa966cce.png)

# ソースコード
- ソースコードはこちらに載せています。
- ディープラーニングのフレームワークはkeras、WebアプリケーションのフレームワークはFlaskを用いています。
- 学習は、CNNモデルの1つであるVGG16をImageNetで学習済のものを用いました。(kerasから簡単に利用できます。)

**ラーメンの画像を機械学習させるためのコード**
https://github.com/fukumame/ramen_deep_learning

**学習済モデルを用いたWebサービス**
https://github.com/fukumame/ramen_web_app

# 実装方法

## 画像の収集
- 画像の収集にあたっては、Twitter APIと Bing APIを用いました。
- それぞれ800枚ほどの画像が集まりましたが、学習に向かない画像データ(ラーメンの画像ではないもの、チャーハンや餃子などが一緒に写っているものなど)を除き、600枚程度になりました。

### Twitter APIでの収集
- 以下のコードを作成し、Twitter API経由で佐野ラーメンと喜多方ラーメンの画像を自動収集しました。
- https://github.com/fukumame/ramen_deep_learning/blob/master/collect_from_twitter.py
- Twitter APIを利用するに当たっての手順は[こちら](http://blog.wackwack.net/entry/2017/12/24/180728)を参考にさせていただきました。

### Bing APIでの収集
- Bingの画像検索APIでも同様に収集を行いました。　その際のコードは以下のとおりです。
- https://github.com/fukumame/ramen_deep_learning/blob/master/collect_from_bing.py
- Bing APIの利用に当たっての手順は[こちら](https://qiita.com/ysdyt/items/49e99416079546b65dfc)を参考にさせていただきました。

## 画像の学習
- 次に画像の学習をさせるにあたって、今回はVGG16というCNNモデルをImageNetで学習させたものが、既にkerasで利用できるため、それをFine tuningさせて学習させることにしました。
- 実装コードはこちらです。
- https://github.com/fukumame/ramen_deep_learning/blob/master/learning_process.ipynb
- 学習用データ 500枚、テスト用データ50枚を用いました。

## Webサービスの実装
- 自動判定Webサービスの実装に当たっては、FlaskというPythonのシンプルなWebアプリケーション・フレームワークを使用しました。
- 実装コードはこちらです。
- https://github.com/fukumame/ramen_web_app/blob/master/ramen_apps.py

## 学習の結果
- Epochを30に設定して、学習を行いました。
- テストデータがあまり良くなかったのか、80%あたりをふらついて、終わってしまいましたが、今後画像の精査などをしっかり行い、精度を上げていきたいと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64437/45580dff-7099-3940-cb07-34dcd81ee688.png)

## まとめと今後の展望
- 佐野ラーメンと喜多方ラーメンという似た部類のラーメンでもある程度の精度が出たので、今後、他のラーメンの判別も出来るようにバージョンアップしていきたいと思います。


# 参考にさせていただいたサイト
今回の記事を作成するにあたり、下記の記事を参考にさせていただきました。
有用な情報を提供いただいたことを心より感謝いたします。

**Twitter APIの実装**
[Twitterのツイート検索APIを使って画像を自動収集する - 小さな星がほらひとつ](http://blog.wackwack.net/entry/2017/12/24/180728)

**Bing APIの実装**
[Bingの画像検索APIを使って画像を大量に収集する - Qiita](https://qiita.com/ysdyt/items/49e99416079546b65dfc)
[Bing Image Search API v7で画像をちょっと保存する方法 - mirenn所感](http://mirennmm.hatenablog.com/entry/2017/11/12/001831)

**画像の学習**
[VGG16のFine-tuningによる17種類の花の分類 - 人工知能に関する断創録](http://aidiary.hatenablog.com/entry/20170131/1485864665)