GUINNESS + Intel OpenCLでディーブラーニング（１）

FPGAでDeepLerningを実装するツールとしてGUINNESSが公開されている．
このツールを使うとGUIで簡単に深層学習がFPGAに実装できてしまう．
フリーで使えるTrial版のGUINNESSを利用してクラス分類をやってみる．
GUINNESSはXilinxのFPGAをサポートしているが，IntelのFPGAデバイスでを実装してみた．
今回はGUINNESSの環境を整えるところまで

### 使用するFPGAデバイスについて

Terasic社製のC5Pを使う．

 - PCIeでPCに接続でき， ホスト側から簡単にクラス分類を実行できる． 
 - FPGAとHostの通信をあまり意識しなくて良い
 - 比較的に低価格なFPGAボード(Cyclone V FPGA搭載)

という特徴がある． 実際にボードが手に入らなくてもCPUでエミュレーションすることは出来る．


# GPUでモデルを訓練する
まずは，FPGAから離れて，GPUで深層学習モデルの訓練を行う．
GPUで訓練(GUINNESS) --> 学習済みモデルをOpenCLで扱えるcppに変換(GUINNESS) --> FPGA合成
という流れになる

## 環境構築
### GPU + nvidia-docker環境
GPUが1つ載ったUbuntuマシンがあればOK． GPUが刺さっていることを確認する

```
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.78       Driver Version: 410.78       CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 108...  Off  | 00000000:01:00.0 Off |                  N/A |
| 36%   33C    P5    24W / 250W |      0MiB / 11177MiB |      3%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```

次にnvidia-dockerをインストールしておく．

既にインストールしてあれば，以下のコマンドは読み飛ばしてください

```
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge -y nvidia-docker
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd
```
nvidia-smiがdockerごしに通るか確認．

```
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi
```

docker-composeも入れておく

```
curl -L https://github.com/docker/compose/releases/download/1.3.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```

これで，dockerの引数に色々指定なくてもymlでファイルに保存して呼び出すことが出来る．

### GUINNESS環境構築
docker pull + git cloneで環境をダウンロード

```
git clone https://github.com/HirokiNakahara/GUINNESS 
cd GUINNESS
```

docker-composeで便利にGUINNESSを起動できるように，以下のファイルを `GUINNESS` ディレクトリに作成しておく

```
$ vi docker-compose.yml
version: '2.3'
services:
  guinness:
    image: youkis/guinness:v1.24.0
    runtime: nvidia
    volumes:
      - $PWD:/root/guinness
      - ~/.Xauthority:/root/.Xauthority
    network_mode: "host"
    working_dir: "/root/guinness"
    environment:
      - DISPLAY
    command: /bin/bash
```

これで環境構築は終わり

## GUINNESSの起動
GUINNESSのGUIウィンドウを起動する． 初回の起動でdocker-hubのクラウドから環境がダウンロードされるため，1-2分ダウンロードに時間がかかる．

```
docker-compose run --rm guinness python guinness.py
```
<img width="1100" alt="sc1.png" src="https://qiita-image-store.s3.amazonaws.com/0/114454/2d9167ea-4675-8c62-3a8e-68eacf922d56.png">

起動が確認できたら一旦終了する

## データセットを揃えて学習する
[チュートリアル](https://www.dropbox.com/s/oe6gptgyi4y92el/guinness_tutorial1_v2.pdf?dl=0)にある3クラスのデータセットを[ダウンロード](https://www.dropbox.com/s/59fx0r5fuqmuo3j/class3_images.zip?dl=0)し `GUINNESS` ディレクトリ内に解凍したファイル `class3_images` を設置する．

画像をpickle形式に変換する

```
python gen_training_data.py --pathfile list.txt --dataset class3 --size 48 --keepaspect yes
```

データセットの準備が出来たのでGUINNESSを起動して学習を行う．

次回学習済みモデルをFPGA向けに変換する...