Ubuntu18.04でkeras版YOLOv3を使用するまでの道程

どうもこんにちは！
最近機械学習やら深層学習やらに興味が出てきて、ぽちぽちと勉強を始めております。今回は物体認識で利用されているYOLOv3を利用するまでの手順を個人的に書き残しています。
GPUを使って行うのでCUDAのインストールからYOLOv3の利用まで一通りざらーと書いていきますー。


# 目次
* 実施環境
* Nvidiaのインストール
* CUDAとcuDNNのインストール
* TensorFlow-gpuとKerasのインストール
* Keras版YOLOv3のインストールとデモ
* 終わりに
* 参考リンク

# 実施環境
* ubuntu 18.04
* pyenv 1.29
* python ~~3.7.2~~ 3.6.8
* GeForce GTX 980 Ti

# Nvidiaのインストール
### セキュアブートの無効化
起動画面時にF2だかなんだかを押してBIOS画面に入り、そこからセキュアブートを無効化します。
BIOSの種類(?)によってセキュアブートを無効にするとこが違うぽいので探すのに一苦労。（スマブラしながら5分くらい探しました）

### nouveauの停止
ubuntuに既存でインストールされているグラフィックドライバーであるnoveauを停止させる必要があります。
terminalからnoveauの動作確認を行います。

```
lsmod | grep -i nouveau
```

以下のように出力されておればnoveauが動作しています。
僕の環境ではこのように出力されました。

```
nouveau              1851392  20
mxm_wmi                16384  1 nouveau
ttm                   110592  1 nouveau
drm_kms_helper        172032  1 nouveau
drm                   458752  16 drm_kms_helper,ttm,nouveau
i2c_algo_bit           16384  1 nouveau
wmi                    24576  3 intel_wmi_thunderbolt,mxm_wmi,nouveau
video                  45056  1 nouveau
```

既存のグラフィックドライバーであるnouveauを停止させるために、blacklistを作成します。

```
vim /etc/modprobe.d/blacklist-nvidia-nouveau.conf
```

ここに以下のように書き込みます。

```
blacklist nouveau
options nouveau modset=0
```
書き込んだらコンソールにて以下のコマンドを打ちます。

```
sudo update-initramfs -u
```

### Nvidiaのインストール
Nvidiaのインストールは以下のコマンドだけでOK
その後再起動をしましょう。

```
sudo ubuntu-drivers autoinstall
sudo reboot
```

再起動で立ち上がったら、既存のnouveauが動作していないことを確認しましょう。

```
lsmod | grep -i nouveau
```

何も出力されなければOK
次にインストールしたドライバーが動作しているかを確認します。

```
nvidia-smi
```

上記のコマンドを打ってErrorではない何者かが出力されなければOK。
僕の場合は

```
Wed Mar 20 15:19:28 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.116                Driver Version: 390.116                   |
|-------------------------------+----------------------+----------------------+
| 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 980 Ti  Off  | 00000000:01:00.0  On |                  N/A |
| 26%   35C    P8    14W / 250W |    239MiB /  6080MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1158      G   /usr/lib/xorg/Xorg                            15MiB |
|    0      1196      G   /usr/bin/gnome-shell                          51MiB |
|    0      1373      G   /usr/lib/xorg/Xorg                            85MiB |
|    0      1506      G   /usr/bin/gnome-shell                          83MiB |
+-----------------------------------------------------------------------------+
```

こんな感じで出力されました。




# CUDAとcuDNNのインストール
### CUDAのインストール
TensorFlowとの兼ね合い(?)で最新のCUDAではなく、CUDA9.0をダウンロードします。
公式ページにひとっ飛び！
[CUDA Toolkit 9.0 Downloads](https://developer.nvidia.com/cuda-90-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1704&target_type=deblocal)

ダウンロードをしたらそのディレクトリにて以下のコマンドを入力しインストールします。

```
sudo dpkg -i cuda-repo-ubuntu1704-9-0-local_9.0.176-1_amd64.deb
sudo apt-key add /var/cuda-repo-9-0-local/
sudo apt-get update
sudo apt-get install cuda-toolkit-9-0
```
その後ホームディレクトリ直下の.bashrcファイルにCUDAのPATHを書き込みます。

```
export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
```

そして再起動して、CUDAがインストールされているかを確認します。

```
nvcc -V
```

すると下記のように出力されるはずです。

```
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176
```
もしnvccコマンドが使えない場合は、.bashrcに書き込んだPATHが間違っているかもしれません（実際に僕も書き間違えていました）。もう一度ご確認ください！


### cuDNNのインストール
NVIDIA公式ページより以下の3つをダウンロードします。

* cuDNN v7.1.4 Runtime Library for Ubuntu16.04 (Deb)
* cuDNN v7.1.4 Developer Library for Ubuntu16.04 (Deb)
* cuDNN v7.1.4 Code Samples and User Guide for Ubuntu16.04 (Deb)

[Download cuDNN v7.1.4 (May 16, 2018), for CUDA 9.0](https://developer.nvidia.com/rdp/cudnn-archive#a-collapse714-9)
このページの[Download cuDNN v7.1.4 (May 16, 2018), for CUDA 9.0]の中に3つとも入っています。

**<注意点>**
**必ずCUDA9.0対応のものをダウンロードしてきてください。僕はここで間違えて9.2のものをダウンロードしてしまい、あとでかなり詰みましたorz**


ダウンロードが完了したらそのディレクトリまで移動し、以下のコマンドを実行してインストールを行なってください。

```
sudo dpkg -i libcudnn7_7.1.4.18-1+cuda9.0_amd64.deb
sudo dpkg -i libcudnn7-dev_7.1.4.18-1+cuda9.0_amd64.deb
sudo dpkg -i libcudnn7-doc_7.1.4.18-1+cuda9.0_amd64.deb
```
依存関係の問題で、上記の順番でインストールを行わないとエラーが出てしまうのでご注意ください。

# TensorFlow-gpuとKerasのインストール
### TensorFlow-gpuのインストール
```
pip install tensorflow-gpu==1.8.0
```
僕は上記でエラーが出てしまいました。。。
というのも[この記事](https://qiita.com/lockdef/items/abb04846f2251f357650)によると、TensorFlowはpython3.7.xには対応していないらしいです。なのでなくなくpythonのバージョンを3.6.8に変更。変更してからもう一度インストールしてみると無事成功しました。

TensorFlowでGPUが動作しているかをpythonのインタラクティブモードから確認します。

```python
import tensorflow as tf
tf.test.gpu_device_name()
```


下記のような出力がでればOK

```
'/device:GPU:0'
```


### Kerasのインストール

```
pip install keras
```

importできるかをインタラクティブモードから確認しましょう。

```python
import keras
```
以下のような出力がでるかと思います。

```
Using TensorFlow backend.
```


# Keras版YOLOv3のインストールとデモ
いよいよKeras-yolov3のインストールを行いたいと思います。

とりあえずパッケージをクローンします。

```
git clone  https://github.com/qqwweee/keras-yolo3.git
```

クローン出来たら、kera-yolo3ディレクトリに移動

```
cd keras-yolo3
```

デモのために学習済みモデルをダウンロードします。
これはkera-yolo3ディレクトリ直下に置いておきます。

```
wget https://pjreddie.com/media/files/yolov3.weights
```

このままではKerasでは使えないのでKerasで使えるようにコンバートします。

```
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
```

これでようやく準備完了！デモを試してみましょう！

```
python yolo_video.py --image
```
とすると

```
Using TensorFlow backend.
model_data/yolo.h5 model, anchors, and classes loaded.
Input image filename:
```
このようになるのであとは画像のパスを入力してください。僕は今回ネットから適当に拾ってきた画像を使ってみました。

```
Using TensorFlow backend.
model_data/yolo.h5 model, anchors, and classes loaded.
Input image filename:person.jpg 
(416, 416, 3)
Found 1 boxes for img
person 1.00 (356, 111) (702, 637)
2.6241899099986767
```
こんな感じになるはずです！
出力されている画像をみるとしっかりと認識されていることがわかりますね！
![out.jpg](https://qiita-image-store.s3.amazonaws.com/0/318451/491ec894-72c5-94ba-ac40-55c0e278052e.jpeg)


# 最後に
[このページ](https://github.com/qqwweee/keras-yolo3/blob/master/model_data/coco_classes.txt)で学習済みモデルを使うと何が認識できるのかがわかるので色々試してみたいですね！



# 参考リンク
以下今回とてもとても参考させていただいたリンクたちです。みなさまありがとうございます。
こんな初心者の僕でも簡単に使えるようになるとは...時代に感謝です。

* [深層学習　Ubuntu 18.04 に Tensorflow GPU をインストール
](https://www.ecobioinfo.com/?p=744)
* [ubuntu18.04でTensorFlow-gpuを動かす](https://qiita.com/sho8e69/items/66c1662c49ac89a024be#ubuntu%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
* [Tensorflowがインストール出来ない症状を解決する方法（Python 3.7.0）](https://qiita.com/lockdef/items/abb04846f2251f357650)
* [KerasのYOLO-v3を動かしたった](https://qiita.com/yoyoyo_/items/10d550b03b4b9c175d9c#github)
* [【Python】keras-yolo3を使用して物体検出](https://kazusa-pg.com/use-keras-yolo3/)
* [【まずは画像から】Keras版のYOLOv3を試してみた](https://gangannikki.hatenadiary.jp/entry/2018/11/04/212535)