モバイル上でのDeepLearningによる画像認識

#はじめに
これは，DeepLearning Advent Calendar 2016 8日目の記事です．関連記事は[目次](http://qiita.com/advent-calendar/2016/deeplearning)にまとめられています．

さて，本記事は以下の3つについて書かれています．

1. 私がリリースしたアプリ[DeepLearningを使った画像認識iOSアプリ](https://itunes.apple.com/jp/app/deepfoodcam/id1111261423?mt=8)で使われているDeepLearning周りの紹介

~~2. DeepLearningを学習する上で参考になるサイト~~
~~3. DeepLearningを学習する上で参考になる書籍~~

1.については自分の研究についてなるべく~~わかりやすく~~書き直したものです．
~~2.3.については，自分にとってとても参考になったサイトや書籍をまとめたものになっています．なので，2.3.のリンク集については随時更新するかもしれません．~~(時間が無いので，また今度書きます…)

**※DeepLearning Advent Calendarということもあり，それ界隈の知識(畳込み層やプーリング層，基本的なNNアーキテクチャなど)を知ってる前提に書くことをご了承下さい．**

**※畏まった内容というよりも，ざっくばらんな体裁で書いています．**
#画像認識iOSアプリ

#概要
DeepLearningという言葉自体が普通にニュースで取り上げられ，もはやバズワードにもなってしまったのは，やはり2016年くらいかと思います．(私が一番驚いたのは，私の親もDeepLearningについて言葉自体は知っていて，本を読んで何となくはイメージを持っていた，くらいには世に浸透している言葉のように感じます．この話も，まだ，私の親の世代(50前半)なら何となく知っててもわからなくもないが，祖父母または親戚など多くの身近にいる人がDeepLearningの言葉自体はニュース及び新聞などで見て，知っていることには度肝を抜かれたのを鮮明に覚えています．)

というのも，大規模画像認識のCompetitionであるImageNet Large-scale Visual Recognition Challenge(ILSVRC 2015年)において，**訓練された人間よりも機械に画像認識させた方が認識精度を上回った**，また，**GoogleのAlphaGoがヨーロッパの囲碁王者を打ち破った**，などの過激なワードに世が溢れ始めたのが2016年くらいからで，それらにマスメディアが色々と拡大解釈し始めたのがきっかけのように感じます．

![tmp1.png](https://qiita-image-store.s3.amazonaws.com/0/149625/ae5b19b7-1af2-5177-4aeb-dbf8f69c4fbd.png)

何を言いたいかというと，それくらい**DeepLearningは可能性を秘めていて，GoogleやFacebookなどの世界的企業による企業買収及びトップ人材の囲い込み合戦になるほど，世界がDeepLearning一色**ということである．現に，[DeepLearning界隈のトップを走るStanford大学のLi Fei-Feiは今年11月にGoogleにhireされています．](http://fortune.com/2016/11/15/google-fei-fei-li-snapchat-machine-learning/)

まあ，余談は置いといて，研究に話を戻すと，DeepLearning(深層学習，ディープラーニング，DNN,CNN，DCNNなど色んな言葉がありますが，本記事では全て同じものとみなして使います．特に，CNNをメインに話すのでDeepLearningをCNNに以後，置き換えます．)の応用として，モバイル上での画像認識が考えられると思います．しかし，モバイルに実装するにはDeepLearningにかかる計算量がボトルネックとなります．特に，CNNの各層の中でも畳込みにおける畳込み演算の計算量が全体の計算時間の大部分を占める(下図はAlexNetの推論時の計算時間の内訳を棒グラフで表したもの)ことから，畳込み層の演算を高速化することが，モバイル上でDeepLearningを実装する上で重要になってきます．

<img width="706" alt="スクリーンショット 2016-12-08 20.41.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/149625/afadb23a-0e9c-b16a-ca57-bfd806efbc93.png">

また，モバイル特有の悩みとしてメモリ容量にも限りがあり，なるべく小さいニューラルネットワークモデルを利用するのが正解となってます．

そこで，本記事では，高速化の工夫とモバイルに最適なネットワーク，などを簡単に説明し，iPhone上で高速高精度な画像認識アプリを紹介したいと思います．

#基本認識アーキテクチャ
##モバイルに最適なNNアーキテクチャとは？
物体認識で用いる基本的なCNNアーキテクチャには，一般的には，下図にあるようにAlexNet，GoogLeNet, VGG-16, Network-In-Network(NIN)などを用います．(※新しさ順で言うならば，GoogLeNet, VGG-16(2014年)>NIN(2013年)>AlexNet(2012年)の順番だと思います．この他にも，ResNet(2015年)などがありますが，今回は言及しません．また，2016年度のILSVRC優勝者は何のネットワークなの？というと，ResNetやGoogleNetなど革新的なアーキテクチャは生まれず，既存手法の組合せに留まっていた，らしいので，ここでは紹介しません．)

![tmp2.png](https://qiita-image-store.s3.amazonaws.com/0/149625/bf5bf25d-6fc9-f018-dbb2-df7bc5f4bf78.png)

ここで，各4つのNeural Network(NN)アーキテクチャの畳込み層(CONV層)や全結合層(FC層)のレイヤ数やパラメータ数を表にまとめると以下のようになります．

![image](https://qiita-image-store.s3.amazonaws.com/0/149625/71973c9c-2a1a-f548-1f37-0d4eaa94b96e.png)

表のAlexNetとVGG-16のFC層や合計パラメータ数を見るとわかりますが，冗長なパラメータを持つFC層を3層含むネットワークであるなど，モバイルに実装するにはアプリ容量が大きくなってしまいます．また，GoogleNetは5x5，3x3, 1x1の畳込み層及びプーリング層からなる"Inception modules"という複雑なCNNアーキテクチャで構成されていることから，モバイルに効果的なパラレル実装が難しいという理由から，今回は，シンプルなNNアーキテクチャであるNINを画像認識エンジンに採用することにしました．

![tmp3.jpg](https://qiita-image-store.s3.amazonaws.com/0/149625/6bec6690-7153-1001-4a33-ab30a9c3f8bf.jpeg)

NINを拡大すると以下のNNアーキテクチャになっていて，本記事が紹介する画像認識アプリでは[Batch Normalization(BN)](https://arxiv.org/abs/1502.03167)を全ての層のReLU関数の直前に追加するなどの修正を若干加えています．BNを加えている理由は学習スピードの高速化及び，深いNNでもDropOutを用いずに収束させることができ，NNの学習では必須のテクニックになっています．([[Survey]Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](http://qiita.com/supersaiakujin/items/8a465ecb1dcbc7df8b02)が参考になります．)(また，余談ですが，この必須テクニックであるBN，提案者はGoogleとなっています．そして，[US20160217368A1](https://patents.google.com/patent/US20160217368A1/en)を見ると…GoogleはBNの特許を申請しているようです…これから先，どうなることやら…)

![tmp4.png](https://qiita-image-store.s3.amazonaws.com/0/149625/9b774f2d-ff46-c048-c334-fc7b9a3a0711.png)

##NIN選んだけど認識精度は？
下図はImageNet2000種類におけるAlexNetとNINの認識精度を示したものですが，認識精度はほぼ変わりませんが，NINのパラメータ数がAlexNetの1/9であることがわかると思います．なので，認識精度面でもNINは最適であると伺えます．

<img width="487" alt="スクリーンショット 2016-12-08 22.07.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/149625/7ad6e082-d974-e13c-25a7-469d61ccebd7.png">

##学習はどうしてる？
NINのモデルを利用して，ILSVRC1000種類と食事に関連した1000種類のImageNet画像2000種類，計210万枚でpre-trainして，そのモデルを各認識対象データセット(食事，鳥，犬，花など)でfine-tuningしています．DeepLearningのフレームワークにはCaffeを用いて学習し，[ネットワーク定義ファイルやcaffemodelなどをCに変換して(リンク先のSlide Shareに少しだけ記載してあります．)](http://qiita.com/negi111111/items/533471ef2dea29121756)，モバイルで利用しています．

##CNNの計算のお話
CNNを高速に計算するには畳込み層の畳込み演算を高速に行う必要がありますが，その際にim2col操作を行います．im2colとは下図[(から引用)](https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/)のように画像に畳込みフィルタのカーネルサイズと同じ大きさにパッチに画像を切り分け，画像のパッチを列行列に変換する操作のことです．この操作により，畳込み層における畳込み演算を行列積で計算することができます．

<img width="615" alt="スクリーンショット 2016-12-08 22.32.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/149625/dd89265e-ae37-f283-620f-b12a25e2cc22.png">

その後は，CNNの演算では，行列積(Generic Matrix Multiplication,GEMM)が多用されるため，GEMMを高速に演算させる必要が出てきます．そこで，それらの処理はライブラリに任せることにして，iOSではBLASの実装としてデバイスに高度に最適化されたAccelerate Frameworkを利用しています．一方，AndroidではBLASの実装としてOpenBLAS を利用しています．さらにAndroidではOpenBLASが高速化に役に立たなかったため，NEON命令を用いた独自のGEMMルーチンも作成しています．NEONとはARMプロセッサのSingle Instruction Multiple Data(SIMD)命令セットであり，一の命令で複数の処理を可能にするベクトル処理機構のことです．NEON命令により，同時に4つの32bit単精度浮動小数点を演算させることが可能で，また，マルチプロセッサにより，iOSでは2コア同時実行の合計8演算を同時に実行することができます．Androidではコア数がQuadCoreの4コアであることが一般的なので，合計16演算を同時実行でき，畳込み演算を高速化しています．

##認識時間はどのくらいなの？
認識時間は入力画像227x227の場合，下図の速度で認識することが可能です．ここでは詳細は省きますが，入力画像を小さく，例えば，227x227 -> 160x160にした場合(精度が落ちるのでは？と思いますが，NINのAverage PoolingをGAPにすることで精度低下を防いでいます．)，iPhone 7 Plus上で26.2[ms]のリアルタイムに物体を認識することが可能です．

<img width="528" alt="スクリーンショット 2016-12-08 22.38.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/149625/cbdf4ff2-9441-d2e5-4828-d47b2a624a65.png">

##デモ動画とかは？？
実際にアプリをダウンロードして体験していただければ幸いです．現状，食事101種類(食事100種類＋非食事の合計101種類)認識アプリのみリリースしていますが，今後，機能や認識対象を選べるようにバージョンアップする予定です．

<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">認識アプリの動作例 <a href="https://t.co/BthVtdkS2o">pic.twitter.com/BthVtdkS2o</a></p>&mdash; ねぎ (@negi111111) <a href="https://twitter.com/negi111111/status/806858712988028928">2016年12月8日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

・[DeepFoodCam(食事101種類認識iOSアプリ)](https://itunes.apple.com/jp/app/deepfoodcam/id1111261423?mt=8)
・[Android版(右側のDeepFoodCamをタッチすればAPKファイルがダウンロード可能です．)](http://foodcam.jp/)

##あれ？画像変換の話は？？
[Chainer Advent Calendar 2016 23日目](http://qiita.com/advent-calendar/2016/chainer)で書くネタがなくなってしまうので，こっちに書くことにしました…デモ動画のみでご勘弁下さい．

<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">DeepLearningを使ったiOSアプリ無料公開しています!!<br>「DeepFoodCam(画像認識)」<a href="https://t.co/wWMM3x5FB5">https://t.co/wWMM3x5FB5</a><br>「RealTimeMultiStyleTransfer(画風変換)」<a href="https://t.co/DNTb5I7THa">https://t.co/DNTb5I7THa</a> <a href="https://t.co/xBA144vB4B">pic.twitter.com/xBA144vB4B</a></p>&mdash; ねぎ (@negi111111) <a href="https://twitter.com/negi111111/status/795180081337364484">2016年11月6日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

#おわりに
時間があるときにもう少し加筆修正をしたいのと，時間がなくて，後半は雑になってしまったこと，お許し下さい．また，時間あるときに書き直したいです．

私事ですが，[OpenCV Advent Calendar 2016 8日目](http://qiita.com/negi111111/items/533471ef2dea29121756)にも参加しているので，見て頂ければ幸いです．**OpenCV DNN moduleのiOSでの利用方法とその実行速度の比較**について書いていて，Caffeで学習したモデルなどのCへの変換などについて学会で発表させて頂いたスライドを少し載せています．

また，[Chainer Advent Calendar 2016 23日目](http://qiita.com/advent-calendar/2016/chainer)にも参加していて，ここでは，**モバイル上でのStyle変換のお話．Chainerで学習したモデルをiOSで利用したアプリ**について自身の研究(スタイル変換)や各企業の動向を踏まえて書くつもりです．

またまた，[今年読んだ一番好きな論文2016 Advent Calendar 2016 23日目](http://www.adventar.org/calendars/1785)にも参加していて，2016年に読んだ論文の中で、**自分の中で一番インパクトのあった、面白かった論文を紹介する系のAdvent Calendar**なのですが，記事を投稿すると，なんと！**豪華な商品があたる**チャンスがあるそうなので，参加してみました．笑 12/15以降はすべて埋まっているみたいですが，それ以外はまだ空きがあるそうなので，ぜひぜひ，参加して豪華賞品を掴みましょう！
(**※大学院生限定なのでそこは注意してください！ただ，それ以外は縛りはなく，どの分野どんな論文でも良いみたいなので，気軽に参加できます．注意事項は本リンク先を御覧ください．**)

#参考
1. [Neural Network Architectures](https://culurciello.github.io/tech/2016/06/04/nets.html)
2. [Network In Network](https://arxiv.org/abs/1312.4400)