Windows10にOpenVINOを導入してIntelComputeStickを動かした話

　初投稿です。当記事の作成にあたって、全体的な構成などはこちらを参考にしました。ありがとうございます。
URL:https://qiita.com/ammo0613/items/a9bb3b7f20dc02a8d758

##背景
　学校の授業で、ノートPCでもそこそこな精度と動作速度で物体検知をできないか、という課題が出ました。
　私は今まで手軽に使える物体検知フレームワークは、Darknet-Yoloくらいしか知りませんでした。しかしこのYoloは実用的な精度と速度を出すためには、どうしてもディスクリートなGPUが必要でした。(少なくとも私が所有している、または使えるノートPCではその結論になりました。)ちなみにDarknet-YoloにはノートPCなどを対象にした軽量なネットワーク構造を持つTiny版があるのですが、速度が出る分どうしても精度が犠牲になってしまいます。
　インターネットの海を漂っていると、IntelNeuralComputeStick(NCS)というデバイスやOpenVINOと呼ばれるSDKなどの存在を知りました。授業の進捗発表でこれらのことを話すと、約2週間ほどで教授からComputeStickが手渡されました。なので、今回はNCSやOpenVINOを使ってどこまでやれるかを知るためにやっていく上での備忘録を残したいと思います。まずは、環境構築です。なお、この記事ではNCSのことをMovidiusって言ったり表記が混在しています。あしからず。

##環境
Let'sNote(CF-SX2)   Windows10 64bit
ThinkPad25          Windows10 64bit
Intek NeuralComputeStick(1st Gen.)
OpenVINO(2018 R4)

##事前準備
・PCのストレージの空き容量を確保
(OpenVINOの他に、Demoプログラムのビルド等に必要なソフトウェア群のために10GB以上は無いと厳しいです。)
・そこそこの帯域がある通信回線
結構ソフトなどをダウンロードすることが多いのであったほうがいいと思います。プロキシなどがある人は適宜調べてください。

##やったこと
　基本的にIntel公式が公開している手順どおりにやりました。
　URL: https://software.intel.com/en-us/articles/OpenVINO-Install-Windows (英語)

###1.OpenVINOのダウンロードとインストール
　OpenVINO Toolkitをダウンロードします。リンク先は英語です。インストーラは500MB以上あります。

　URL: https://software.intel.com/en-us/openvino-toolkit/choose-download (要会員登録)

　インストールに1.2GB程度必要とのことです。
　CMake(3.4以上)とPython(3.5以上)が入っていない場合、警告が出ます。(インストール自体は続行可能)　後でデモのプログラムなどを動かすのに必要なので、適宜導入してください。


###2.Python(on Miniconda)とCMakeのインストール
　私は都合上Chocolateyを入れたうえでCMakeとMiniconda(Pythonの環境管理ツール)を入れました。Chocolateyだとaptみたいな感じでコマンド一行でソフトが入れられるので楽です。(この辺は好みなので普通にCMakeやPythonを入れても多分大丈夫)
　Chocolateyの導入については割愛します。導入が終わったら、管理者権限でコマンドプロンプト、またはPowerShellウィンドウを開き、

``` 
choco install cmake conda -y　
```

と打ち込みます。後は待っていればインストールが終わるはずです。
　私の場合、環境変数にパスが通っていなかったので、手動で以下の2つ追加しました。(CMakeの方はいらないのかな？)

```C:\Program Files\CMake\bin
C:\ProgramData\Miniconda\Scripts```

パスの追加方法も割愛します。

　パスの追加が終わったら新しくコマンドプロンプトを立ち上げます。(PowerShellだとうまくいかなかったです)
　起動したらOpenVINO用にPythonの環境を作ります。今回はOpenVINOに用意されているPythonスクリプトの都合上、Python3.6を採用します。以下のコマンドを打ち込みます。(環境名movidius,pythonは3.6を使用)

```
conda create -n movidius python=3.6 
```


環境ができたらactivateして有効にします。

```
activate movidius
```

　今後デモプログラムを動かすときはこの有効化の作業をしてから行います。Minicondaを使わず、Python3.6を直接インストールした場合は、コマンドプロンプトを起動するだけでOKだと思います。

Minicondaはこちらの記事を参考にしました。助かりました。

Miniconda(Python仮想環境)導入してPython3.6を入れる
https://cartman0.hatenablog.com/entry/2016/03/23/005430

###3.VisualStudio2017のインストール

　続いてデモプログラムビルド用にVisualStudio2017を導入します。Community版でもうまくいったのでデモを動かす分にはこれで十分だと思います。
https://visualstudio.microsoft.com/ja/downloads/

　例のごとくインストールに時間がかかりますのでご注意を。インストールしたコンポーネントは画像のとおりです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/321239/56886920-1975-da5c-1d2e-15053fab77c9.png)


　公式が提示しているコンポーネントより少ないですが、これで動きました。念のために公式と揃えたほうがいいのかもしれないです。

###4.モデルオプティマイザの設定
　モデルオプティマイザを設定するバッチファイルがあるディレクトリまで移動して、実行します。

```
cd C:\Intel\computer_vision_sdk\deployment_tools\model_optimizer\install_prerequisites
.\install_prerequisites.bat
```

　Pythonの必要なモジュールの導入が始まりますのでしばらく待ちます。

###5.デモプログラムの実行
 オプティマイザの設定が終わったら、いよいよデモプログラムの実行です。
今回は、用意されてるバッチファイルを叩きます。このバッチファイルはビルドから必要なコンポーネントのインストールまでやってくれます。

```
cd C:\Intel\computer_vision_sdk\deployment_tools\demo
.\demo_squeezenet_download_convert_run.bat
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321239/1335bc67-2e22-57b6-34e2-f278f52c5b4f.png)

こんな感じになったら無事完了してます。

###6.デモプログラムの実行その2
5.でデモプログラムが動いたらそれでOKなのですが、今回はおまけにもう一つサンプルプログラムを動かしてみました。これもバッチファイル叩くだけなのですが、推論の結果画像を出してくれるので比較的わかりやすいかもしれません。

```
cd C:\Intel\computer_vision_sdk\deployment_tools\demo
.\demo_squeezenet_demo_security_barrier_camera.bat
```
5.と同じようにしばらく待つと、結果画像が出力されると思います。
ThinkPadの方でやった結果がこちら。↓
![result_tp_cpu.png](https://qiita-image-store.s3.amazonaws.com/0/321239/d32a7efe-6a0c-1a30-1f28-ddc271a1ddab.png)

Let'Noteの方はこちらです。↓
![result_lets_cpu.png](https://qiita-image-store.s3.amazonaws.com/0/321239/c516ab2c-5717-98a9-c5d2-0a713632547e.png)

どちらも推論にCPUを使い、20FPS以上出ていることがわかります。

###7.GPU(IntelHDGraphics)とNCSを使う
　推論にGPUやNCSを使いたい場合は、実行時に-dオプションをつけてデバイス名を指定してあげます。(ReadMeにかかれてました。)

GPUを使う場合は

``` 
.\demo_squeezenet_demo_security_barrier_camera.bat -d GPU 
```

で、Movidiusの場合は

``` 
.\demo_squeezenet_demo_security_barrier_camera.bat -d MYRIAD 
```
みたいな感じです。
　ちなみに、ThinkPadでGPUを使ったときの結果はこちらです。↓
![result_tp_gpu.png](https://qiita-image-store.s3.amazonaws.com/0/321239/ebfc4a90-d3ca-0ce6-8492-8b78ed6db4ac.png)
Let'sNoteのCPUと同程度の速度が出ています。

　そして肝心のMovidiusですが、Let'sNoteに挿したときの実行結果がこちらになります。↓
![result_tp_movidius.png](https://qiita-image-store.s3.amazonaws.com/0/321239/abeb8bea-0129-2de4-64ea-290485b5800f.png)
9FPS・・・ちょっと期待してたより遅いなぁ・・・
　MovidiusはThinkPadの方に挿しても動作速度が変わらなかったので、少なくともチューニングなどを施してない場合はこれが限界みたいです。デモプログラムによって動作速度変わるのかな？

###8.デモプログラムがビルドできない場合(特定の環境下での話)
　ここの話は大多数の人には関係ない話だと思います。
　私が使った備品のLet'sNoteは、授業で使うためにいくつかのヘッダファイルが変更されています。そのため、普通のプログラムがビルドできない場合があります。
　原因は、授業で使うプログラムがVC98などの時代に作られたもので、これをVS2008以降の環境に持ってくるとそのままビルドができないため、対処療法的に、WindowsSDK内のヘッダファイル(winnt.hなど)を弄られているからでした。
 一番手っ取り早いのはヘッダファイルをあるべき姿(初期状態)に戻すことですが、そうすると今度は授業で使うプログラムがビルドできません。そのため、そのプログラムのプロジェクトのプロパティを変更します。(ここから先はwinnt.hが初期状態に戻されてることを前提に進めます。)


####Step1.VisualStudioが検索するパスに追加

VisualStudio2017 Communityの場合、ソリューションエクスプローラーのプロジェクト名を右クリック→プロパティ→「構成プロパティ」→「C/C++」→「全般」まで辿り、「追加のインクルードディレクトリ」を編集します。
以下の2行のマクロを追加します。

```
$(VC_IncludePath)
$(WindowsSDK_IncludePath)
```

　解決にあたっては、以下のページを参考にしました。助かりました。
URL: https://taiyakisun.hatenablog.com/entry/20130406/1365248215

####Step2.リソースファイルを編集(プロジェクトがVisualStudio Professional以上で作られていた場合)

　ソリューションエクスプローラーからrcファイルを探します。rcファイルを開き、afxres.hと書かれている部分をwinres.hに置換します。私の方では2箇所ありました。

　解決にあたっては、以下のページを参考にしました。助かりました。
URL: https://qiita.com/yohhoy/items/7c2a37cfcbb7fd6f26a1

以上の手順を行い、プロジェクトをリビルドするとビルドが成功します。多分。

###9.課題
####1.Let'sNoteにおいて、_mm_blendv_psが見つからないというエラーが出てビルドに失敗する
　エラーメッセージで検索しましたが、解決策らしい情報にたどり着けませんでした。VisualStudioのコンポーネントが足りてないのかと思い、Intelの情報と揃えましたがダメでした。CPUが古いせいなのかなぁ？
　暫定的な対策として、該当行をコメントアウトしたらビルドできました。場所は、softmax.hの92行目でした。
　ThinkPadの方では出なかったので気になります・・・解決策をご存知の方いたらご教授ください。

####2.NCSのチューニング
　こちらの記事( https://qiita.com/PINTO/items/190daa4fddfd2a21f959 ) のようにNCS(1st Gen)を2本挿してデモプログラムを実行したのですが、1本のときと動作速度が変わらなかったです。　複数枚挿しに対応したコードを書かないといけないのかな。　また、世代が異なるStick同士を挿したときにどうなるかや、Stickの性能を引き出すための実装も検証してないので、これからやりたいと思います。

####3.Yoloのモデルファイルを使用して、汎用的な物体検知を試みる
　OpenVINOは、Yoloなどで使われているモデルファイルを中間言語にコンパイルすることで使うことができるようなので、試したいです。

###10.おわりに
　最初NCSについて調べたときはNCSDKがUbuntuしかサポートしていなかったこともあり、どうやって使おうか迷っていましたが、OpenVINOがWindowsをサポートしてくれたことでその心配がなくなりました。本格的な取り組みはこれからになりますが、やれるところまでやりたいと思います。
　当記事について何かありましたらコメント欄などで連絡ください。お願いします。