NVIDIA DIGITS 2.0 RCをlinuxで使う

# NVIDIA DIGITSとは？
![lenet_car_great.png](https://qiita-image-store.s3.amazonaws.com/0/54829/076cc619-29ec-989c-a6f9-1ca551e4e46f.png)

NVIDIA GPUでの高速化とWEBでのGUI操作・WEBAPI操作の恩恵が受けられる、Caffeがバックエンドの画像処理Deep Learning Frameworkです。(Covolutional Neural Network,基本Feed-forward Neural Network向け)
標準ではLeNet, GoogleNet, AlexNetアーキテクチャがサポートされており、他のCaffeモデルをインポートすることも可能です。
https://developer.nvidia.com/digits
最新のNVIDIA DIGITS 2.0 RCではmultiple GPU support機能や最適化にAdaGradやNesterov's Accelerated Gradientが使用できるようになりました。
ちなみにNVIDIA DIGITSはCPUモードも可能です。

# NVIDIA Developer Zoneへの登録
NVIDIA DIGITSはNVIDIA Developer Zoneからダウンロードできます。
NVIDIA Developer Zone(無料）の登録が必要です。

# 環境構築(ubuntu)
XUbuntuをISOレベルで落としてくることを推奨します。(NVIDIA X Serverが安定しました）
標準Ubuntu Desktopだとunity/lightdmのアップデートでNVIDIA X serverが動かなくなるなど色々不安定です。
GeForce GT 740Mでは標準Ubuntu DesktopでNVIDIA X server動いたのですが新型のGeForce 940Mでは標準Ubuntu DesktopでNVIDIA X serverが動きませんでした。
NVIDIA X serverは/etc/X11/xorg.confを他のディレクトリに移動するなど仕様が厄介です。
GeForce 940MでNVIDIA DIGITSを使うまで設定が2週間かかりました。

1. `sudo add-apt-repository ppa:xorg-edgers/ppa`
   `sudo add-apt-repository ppa:graphics-drivers/ppa`
    `sudo apt-get update`
    `sudo apt-get install nvidia-355`
NVIDIA公式HPのdebパッケージなどからNVIDIA driverをインストールするとX Serverが動かなくなることが多数あるようです。NVIDIA ドライバーはppaからインストールすることをおすすめします。　　

2. NVIDIAの公式HPからNVIDIA CUDA 7.5 RCのインストール
Release Candidateですが問題なく動きました。CUDA 7.0よりCUDA 7.5 RCの方がGPUの計算が高速らしいので導入を推奨します。　　
https://developer.nvidia.com/rdp/cuda-75-release-candidate　　

3.`echo "export CUDA_HOME=/usr/local/cuda >> ~/.bashrc"`　　
  `echo "export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/cuda/lib64"`　　
CUDAのパスを通します。
4.NVIDIA Developer Zone HPからNVIDIA DIGITS 2.0をインストール
https://developer.nvidia.com/digits
5.digits 2.0のアーカイブを展開して `digits-2.0/install.sh`を実行
6.`cd digits-2.0/digits && for req in $(cat requirements.txt); do sudo pip install $req; done`　　
7.libcudnnをNVIDIA Developer Zoneからインストール
https://developer.nvidia.com/cudnn
8.cudnnアーカイブを解凍、ディレクトリ内に移動し
`sudo cp -a libcudnn* $CUDA_HOME/lib64`
`sudo cp cudnn.h $CUDA_HOME/include/`    
を実行 
9. digits-2.0/lib/cuda内に移動し
`sudo cp libcudart.so.7.0 /usr/local/cuda/lib64`
`sudo ldconfig`
`source ~/.bashrc`
 を実行
libcudart.so.7.0はCUDA 7.0用の共有ライブラリでcaffeの依存関係の一部になっています。
CUDA 7.5ではlibcudart.so.7.5であるためlibcudart.so.7.0を追加してください。
10.`echo "export $PYTHONPATH=${HOME}/digits-2.0/caffe/python:${PYTHONPATH} >> ~/.bashrc"`
これをしなくてもDIGITS自体は動作しますがDIGITSのpythonプログラムを使いたいときやpythonでcaffeを使うときに必要です。
11.`digit-2.0/runme.sh`
を実行しブラウザでlocalhost:5000にアクセスしてください。
12.適当なモデルで学習させトレーニング
https://github.com/NVIDIA/DIGITS/blob/master/docs/GettingStarted.md#installation
MNIST,CIFAR-10/100などが簡単に収集できると思います。
するとdigits-2.0/digits/digits/jobsディレクトリ以下にcaffeの設定ファイルが生成されます。
13.`digits-2.0/digits/examples/classification/example.py 生成したcaffeモデルファイル　デプロイファイル　画像ファイル　--labels ラベルファイル`
を実行すると推論結果が出ます。もちろんWEBのGUI操作からも推論が可能です。
自分は自律型ロボットのソフトウエア(https://www.facebook.com/happyrobotmini )にDIGITSを組み込むときにこのpythonプログラムを使用しました。
なおcaffeモデルなどは前述の通りdigits-2.0/digits/digits/jobsディレクトリ以下にあります。

# パフォーマンスのベンチマーク
ロボカップ世界大会@home leagueの人間認識タスクで性別認識器を製作する必要がありました。
ネット上から700枚ずつ男性、女性の画像を集めLeNet + Nesterov's Accelerated Gradientでtrainingを行ったところ、validation setでは75%の認識精度、特に女性の認識率が高かったです。またRoboCup@home leagueの人間認識タスクの性別認識部分では得点することができました。
![googlenet-learn.png](https://qiita-image-store.s3.amazonaws.com/0/54829/ee7afbe9-ce12-b9d6-cbf5-77e15edcc013.png)
![googlenet-dl.png](https://qiita-image-store.s3.amazonaws.com/0/54829/f32072a2-a0e3-c4e8-5cdc-9a107fafd1be.png)

また、ノートPC用NVIDIA　GPUを使用している場合、Network in Network ArchitectureなGoogleNetやAlexNetではバッチ数を１にするOnline LearningでないとGPUのメモリアロケーションエラー（メモリ不足）になり,GoogleNetでは過学習しました。LeNetが最も高速に学習できるかと思います。
![10-min.png](https://qiita-image-store.s3.amazonaws.com/0/54829/29991fbf-9bb5-075f-96ce-d2fa61ffacd0.png)

最適化手法についての比較ですが、Stochastic Gradient Descentでは性別認識器の学習が50分程度かかっていたのに比べてNesterov's Accelerated GradientやAdaGradでは学習が10分を切っており、推論結果にも支障は出ていません。また3値分類の１ラベル300~500枚程度の画像の自作姿勢識別器でも同じような結果が出ました。

#データセット集め
crawlerでスクレイピングという手法もありますがcrawlerの画像収集を弾くサイト、画像も結構多いです。
firefoxのdownthemall!というプラグインを用いて手動で画像収集をすることをおすすめします。作業は煩雑で、男性女性の画像合計1400枚程度の画像を収集するのに１６時間ほどかかりました。twitterやinstagramのタグは画像収集にかなり便利です。

#入力画像のサイズ変換やlabels.txt記入、train.txt製作など
入力画像を32x32,28x28ピクセルに変換する必要があるのですが、imagemajickという画像処理ツールが便利です。
また学習させるにはlabels.txtとtrain.txtを作る必要があるのですがこの設定ファイルを手動で記入するにはあまりに煩雑すぎるためシェルスクリプトなどで自動化をおすすめします。
前述の性別認識器とその学習のための設定ファイル製作のスクリプト、画像のサイズ変換のツール（シェルスクリプト）を
https://github.com/demulab/woman-man-recog
のscriptsディレクトリに配置しましたのでご活用ください。