Ubuntu 18.04 ゼロから始めるDeep Learning環境構築

Deep Learningの学習，推論において重要になってくるのが計算時間です．
人気のネットワークを気軽に学習したい，または自分でネットワークを作成したい場合，CPUのみの学習では，日が暮れるどころか，何日経過しても学習が完了しません．

そんな計算時間の悩みを解決してくれるのがGPU（Graphics Processing Unit）です！

CPUで丸1日かかるような学習も，GPUを使うと30分で済んでしまう場合があります．
CPUはコア数が少ない代わりに複雑な処理が得意です．一方，GPUはコア数が多い代わりに複雑な処理は苦手ですが，定型的な命令は得意です．つまり，並列的な計算処理を頻繁におこなうDeep Learningでは，GPUがかなり有効なのが分かりますね．

本記事では，Ubuntuをインストールした後，GPUを使って，はじめてDeep Learningの環境を作りたいと思っている方に向けた内容を記載しています．

#開発環境

OS：Ubuntu 18.04 LTS
GPU：NVIDIA GeForce GTX 1070


#インストール手順

##インストール時の注意点

インストールにおいて一番重要なのが各ライブラリの**「バージョンの互換性」**です．
これを間違えてしまった場合，Ubuntuの再起動時にログインループが発生したり，GPUを用いた学習，推論ができなくなってしまったりと，後でかなり面倒なことになります．

以下のサイトに，NVIDIAドライバーとCUDAのバージョンの互換性が記載してあります．
左列の「CUDA」のバージョンを使用するためには，「NVIDIAドライバー」のバージョンが少なくとも右列のバージョン以上でなければならないという意味です．
https://stackoverflow.com/questions/30820513/what-is-the-correct-version-of-cuda-for-my-nvidia-driver

NVIDIAドライバーは，下記のサイトから事前に知ることもできます．
https://www.nvidia.co.jp/Download/index.aspx?lang=jp

私の環境では**「NVIDIAドライバー」**が**410.48以上**で，後にTensorFlowをインストールすることもあり，**「CUDA」**のバージョンを**10.0**にして進めていきました．

##(1) NVIDIAドライバーのインストール

パソコンでGPUを動作させるために必要なソフトウェアが**「NVIDIAドライバー」**です．

まず，パソコンにGPUを接続し，以下のようにNVIDIAドライバーをインストールします．

~~~
$ sudo apt update
$ sudo apt upgrade
$ sudo ubuntu-drivers autoinstall
$ sudo reboot
~~~

インストールできたか確認します．以下のように表示されればOKです．
ここで，「Driver Version」の隣に表示される数字がNVIDIAドライバーのバージョンです．

~~~
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI xxx.xx       Driver Version: ???.??       CUDA Version: xx.x     |
|-------------------------------+----------------------+----------------------+
| 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 1070    Off  | 00000000:01:00.0  On |                  N/A |
|  x%   xxx    xx    xxW / xxxW |    xxxMiB /  xxxxMiB |      x%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      xxxx      G   /usr/lib/xorg/Xorg                            xxMiB |
|    0      xxxx      G   /usr/bin/gnome-shell                          xxMiB |
+-----------------------------------------------------------------------------+
~~~

##(2) CUDAのインストール

GPUは，CPUと異なりコア数が多く並列処理が得意です．
その並列処理をおこなうために必要なプログラムが**「CUDA」**です．

まず，以下のようにコマンドを入力し，パッケージを認証します．

~~~
$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
~~~

下記のサイトにアクセスし，以下の書式に沿って，自分が欲しいCUDAのバージョンに合うdebファイルをメモしておきます．
http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/


***
* 書式

<font color="Black">cuda-repo-ubuntu1804_<font color="Red">[CUDAのバージョン]</font>.<font color="Red">xxx</font>-<font color="Red">x</font>_amd64.deb</font>
***

また，以下の書式に沿って，コマンドを実行します．

***
* 書式

$ <font color="Black">wget http\://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/<font color="Red">[debファイル]</font></font>
$ <font color="Black">sudo dpkg -i <font color="Red">[debファイル]</font></font>
$ <font color="Black">sudo apt update</font>
$ <font color="Black">sudo apt upgrade</font>
$ <font color="Black">sudo apt install cuda-<font color="Red">[CUDAのバージョン]</font> cuda-drivers</font>
$ <font color="Black">rm <font color="Red">[debファイル]</font></font>
***

例：cuda-repo-ubuntu1804_10.0.130-1_amd64.deb（cuda10.0の場合）

~~~
$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install cuda-10.0 cuda-drivers
$ rm cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
~~~

以上で，CUDAのインストールは完了です．

次に，CUDAのライブラリがいつでも参照できるようにパスを設定します．
以下のコマンドを入力することで，「.bashrc」のファイルにパスの設定を書き込みます．

~~~
$ echo 'export PATH="/usr/local/cuda/bin:$PATH"' >> ~/.bashrc
$ echo 'export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"' >> ~/.bashrc
~~~

これで，Ubuntuが起動する際，自動的にパスが設定されるようになりました．
今すぐパスを有効にしたい場合は以下のコマンドを実行します．

~~~
$ source ~/.bashrc
~~~

再起動します．

~~~
$ sudo reboot
~~~

インストールできたか確認します．以下のように表示されればOKです．

~~~
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Sat_Aug_25_21:08:01_CDT_2018
Cuda compilation tools, release 10.0, V10.0.130
~~~

##(3) cuDNNのインストール

ほぼお決まりで，CUDAと一緒にインストールするライブラリが**「cuDNN」**になります．
これは，CUDAを用いて，GPU上でDeep Learningの計算を高速におこなうためのライブラリです．

まず，下記のサイトにアクセスし，ログイン（会員登録してない場合はそこから）します．
https://developer.nvidia.com/rdp/cudnn-download

そして，図中の丸印にチェックを入れます．
![2019-09-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374669/30821481-cf9b-3dfc-4a51-2ab7eb669350.png)

自分が希望するCUDAのバージョンに合うように，以下の書式に沿ってcuDNNのdebファイルを**3種類**インストールします．

![2019-09-12 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374669/c3b27534-764d-93e1-48a1-189345060dbd.png)

インストール先のディレクトリに移動します．
例：「ダウンロード」ディレクトリ直下の場合

~~~
$ cd ~/Downloads
# cd ~/ダウンロード　（日本語の場合）
~~~

書式に沿って以下のコマンドを実行します．
ここで，必ず上から順番に実行してください．（順番に実行しないとエラーが発生します．）

***
* 書式

$ <font color="Black">sudo dpkg -i libcudnn<font color="Red">X</font>\_<font color="Red">x</font>.<font color="Red">x</font>.<font color="Red">x</font>.<font color="Red">xx</font>-<font color="Red">x</font>+cuda<font color="Red">xx</font>.<font color="Red">x</font>\_amd64.deb</font>
$ <font color="Black">sudo dpkg -i libcudnn<font color="Red">X</font>-dev_<font color="Red">x</font>.<font color="Red">x</font>.<font color="Red">x</font>.<font color="Red">xx</font>-<font color="Red">x</font>+cuda<font color="Red">xx</font>.<font color="Red">x</font>\_amd64.deb</font>
$ <font color="Black">sudo dpkg -i libcudnn<font color="Red">X</font>-doc_<font color="Red">x</font>.<font color="Red">x</font>.<font color="Red">x</font>.<font color="Red">xx</font>-<font color="Red">x</font>+cuda<font color="Red">xx</font>.<font color="Red">x</font>\_amd64.deb</font>
***

例：cuDNN v7.4.2（cuda10.0の場合）

~~~
$ sudo dpkg -i libcudnn7_7.4.2.24-1+cuda10.0_amd64.deb
$ sudo dpkg -i libcudnn7-dev_7.4.2.24-1+cuda10.0_amd64.deb
$ sudo dpkg -i libcudnn7-doc_7.4.2.24-1+cuda10.0_amd64.deb
~~~

##(4) Pythonのインストール

近年，機械学習において注目を浴びているプログラミング言語が**「Python」**です．
Pythonが人気な理由は，コードがシンプルで見やすく，Deep Learningに便利なライブラリがいくつか入っているからです．

まず，以下のコマンドを実行し，Pythonをインストールします．
「python3」コマンドがpython3系です．

~~~
$ sudo apt install python3
~~~

以下のように，Pythonのプログラムが動作したらインストールは完了です．

~~~
$ python3
>>> print("Hello, World!!")
Hello, World!!
>>> exit()
~~~

次に，pythonで使用するライブラリを追加でインストールします．

~~~
$ sudo apt install python3-pip libpq-dev python-dev python-virtualenv
$ pip3 install numpy scipy pandas matplotlib seaborn scikit-learn requests jupyter tqdm opencv-python
~~~

「pip3」とは，Python3系で使用するパッケージを簡単にインストールするためのツールです．
「pip3」を使用する場合に「mainがない」というエラーが発生するときは，以下のサイトが参考になります．
https://qiita.com/qiita_kuru/items/77ef98e8ae37049cc1de

また，Pythonで行列演算をする場合は基本的に「NumPy」を使用しますが，行列数が多い場合はCUDA上でGPUを用いた行列演算が必要になってきます．これを実現するのが「CuPy」です．

以下の書式に沿って，「CuPy」をインストールします．

***
* 書式

$ <font color="Black">pip3 install cupy-cuda<font color="Red">[CUDAのバージョン]</font></font>
***

例：cuda10.0の場合

~~~
$ pip3 install cupy-cuda100
~~~

インストールできたか確認します．以下のように表示されればOKです．

~~~
$ pip3 freeze
cupy-cuda100==6.3.0
~~~

##(5) Jupyter Labのインストール

PythonでDeep Learningのプログラムを書く方法としては，「ターミナル」や「VisualCode」などさまざまな方法があります．
その中でも，自分のプログラムが適切かどうか逐次実行したいという場合があると思います．
この問題を解決してくれるのが**「Jupyter Lab」**です．

以下の順にコマンドを実行すればインストール完了です．

~~~
$ pip3 install jupyterlab widgetsnbextension
~~~

「Jupyter Lab」を起動したい場合は，以下のコマンドを実行します．

~~~
$ jupyter lab
~~~

##(6) 各種フレームワークのインストール

Deep LearningをGPUで動かすライブラリとして「CUDA」，「cuDNN」，プログラミング言語として「Python」，GPU上で行列演算をおこなうライブラリとして「CuPy」をインストールしてきました．

ここで，Deep Learningのプログラムを書く上で便利なソフトウェアがあります．それが**「フレームワーク」**です．
多くのプログラマーは，Deep Learningを実現する上でフレームワークを利用しています．

***
＜代表的なフレームワーク＞

* **TensorFlow (テンソルフロー)**
* **PyTorch (パイトーチ)**
* Chainer (チェイナー)　→　開発元の会社が撤退したため，今から始める人にはおすすめしません．

　etc.

以下，筆者の主観です．

・世界的な規模
TensorFlow > PyTorch
・機能の充実性
TensorFlow > PyTorch
・プログラムの可読性
PyTorch >> TensorFlow

***

その他のDeep Learningフレームワークに関しては，こちらの記事が参考になります．
https://www.kumilog.net/entry/deeplearning-framework
https://nal-hr.co.jp/column-2018-03-09-782

Web上のプログラムを動かす場合は，そのプログラムに対応したフレームワークを事前にインストールしておくとよいです．
また，自分でDeep Learningのプログラムを書く際は，上記の3つの観点から決めるのもよいと思います．

###(6-1) TensorFlowのインストール
<details><summary>詳細</summary><div><br>

下記のサイトに記載してあるCUDAのバージョンに対応したTensorFlowをインストールしてください．
https://www.tensorflow.org/install/source#common_installation_problems

***
* 書式

$ <font color="Black">pip3 install tensorflow-gpu==<font color="Red">[CUDAのバージョンに対応したTensorFlowのバージョン]</font></font>
***

例：tensorflow-gpu-1.13.1（CUDA10.0の場合）

~~~
$ pip3 install tensorflow-gpu==1.13.1
~~~

以下のコマンドを実行して，virtualenvの環境を作成します．

~~~
$ virtualenv --system-site-packages -p python3 tensorflow
~~~

プログラムを書く際にtensorflowを有効にしたい場合は，以下のコマンドを実行します．

~~~
$ source ~/tensorflow/bin/activate
~~~
</div></details>


###(6-2) PyTorchのインストール
<details><summary>詳細</summary><div><br>

下記のサイトから，自分の環境に対応したPyTorchをインストールしてください．
https://pytorch.org/get-started/locally/

例：Stable(1.2)，Linux，Pip，Python 3.6，CUDA10.0（最新版）の場合

~~~
$ pip3 install torch torchvision
~~~
</div></details>


##(7) Deep Learningの動作確認

今回は，画像を生成するDeep Learningモデルとして有名なGANの中でも「DCGAN」を動かしてみようと思います．


###(7-1) TensorFlowの動作確認
<details><summary>詳細</summary><div><br>

プログラムをインストールするには，GitHubのURLを添えて「git clone」コマンドを実行します．

~~~
$ git clone https://github.com/carpedm20/DCGAN-tensorflow.git
~~~

実際に学習してみましょう．

~~~
$ cd DCGAN-tensorflow
$ python3 download.py celebA
$ python3 main.py --dataset celebA --input_height=108 --train --crop
~~~

別のターミナルを立ち上げ，以下のコマンドを実行すると，1秒置きにGPUの使用状況が表示されます．

~~~
$ nvidia-smi -l 1
+-----------------------------------------------------------------------------+
xxx xxx xx xx:xx:xx xxxx       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI xxx.xx       Driver Version: xxx.xx       CUDA Version: xx.x     |
|-------------------------------+----------------------+----------------------+
| 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 1070    Off  | 00000000:01:00.0  On |                  N/A |
| 28%   66C    P2    52W / 151W |   2230MiB /  8116MiB |      2%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      xxxx      G   /usr/lib/xorg/Xorg                            xxMiB |
|    0      xxxx      G   /usr/bin/gnome-shell                          xxMiB |
|    0      xxxx      C   python3                                     1885MiB |
+-----------------------------------------------------------------------------+
~~~

真ん中の列の「2230MiB / 8116MiB」は，GPUのメモリ使用率です．

この数字が最大値に近い方が良いのですが，今回は1/4程度しかメモリを使えてないですね．
調査したところ，TensorFlowではGPUのメモリ使用率を決めることができるらしいです．

別のターミナルで学習しないのであれば，DCGANの「main.py」の76行目を以下に変更することで，メモリ使用率を最大値に近づけることができます．

~~~python:main.py
run_config.gpu_options.allow_growth=False
~~~

以下は，学習中の様子です．

~~~
[      25 Epoch:[ 0/25] [  24/3165] time: 48.3944, d_loss: 1.93663967, g_loss: 3.84208727
[      26 Epoch:[ 0/25] [  25/3165] time: 49.5605, d_loss: 7.44960308, g_loss: 0.00330437
[      27 Epoch:[ 0/25] [  26/3165] time: 50.7624, d_loss: 2.77127719, g_loss: 5.62518740
[      28 Epoch:[ 0/25] [  27/3165] time: 51.9261, d_loss: 7.94477749, g_loss: 0.00119625
[      29 Epoch:[ 0/25] [  28/3165] time: 53.0522, d_loss: 3.24802518, g_loss: 3.02732801
[      30 Epoch:[ 0/25] [  29/3165] time: 54.2179, d_loss: 8.69480038, g_loss: 0.00049170
[      31 Epoch:[ 0/25] [  30/3165] time: 55.4353, d_loss: 3.25925756, g_loss: 5.83671808
[      32 Epoch:[ 0/25] [  31/3165] time: 56.5918, d_loss: 5.83892536, g_loss: 0.00716284
[      33 Epoch:[ 0/25] [  32/3165] time: 57.7775, d_loss: 4.35211182, g_loss: 6.03375244
[      34 Epoch:[ 0/25] [  33/3165] time: 58.9709, d_loss: 5.45558357, g_loss: 0.00946872
[      35 Epoch:[ 0/25] [  34/3165] time: 60.1873, d_loss: 2.85949016, g_loss: 2.34101343
~~~

「d_loss」が識別器の損失，「g_loss」が生成器の損失になります．
GANについては，以下のサイトが参考になります．
https://qiita.com/taku-buntu/items/0093a68bfae0b0ff879d

学習は「Ctrl+C」で中断できます．

以下がDCGANの学習過程における生成画像です．

・学習初期
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374669/dab31ee7-f6bc-f983-4af3-67e896a46f12.png)

・学習終盤
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374669/d03a977e-c050-3775-ce8f-3696fafc946b.png)

学習初期に比べて，学習終盤の方が本物に近い顔の画像を生成できていることが分かります．

</div></details>


###(7-2) PyTorchの動作確認
<details><summary>準備中</summary><div><br>

</div></details>


# おわりに

以上で，Deep Learningの環境構築は終了です．

いかがでしたでしょうか？
各ライブラリのバージョンの整合性をとるのは大変ですが，実際にGPUで学習できているのを見ると感動しますよね．


以下は，Deep Learningを進めるにあたり筆者のおすすめの書籍です．

**・Deep Learningをゼロから学びたい（内部構造から全て学びたい）人向け**
[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/dp/4873117585)
**・Deep Learningを実装したい（既存手法を学びながら実装したい）人向け**
[つくりながら学ぶ! PyTorchによる発展ディープラーニング](https://www.amazon.co.jp/dp/4839970254)

それでは，楽しいDeep Learningライフを！

#参考URL
https://qiita.com/yukoba/items/4733e8602fa4acabcc35
https://qiita.com/pollenjp/items/004637de9eae7c038ea7
https://qiita.com/taka4sato/items/378782763dec3dacb1ee